/* * Infini puissance N : un jeu à plusieurs joueurs. * Copyright (C) 2023 Valentin Moguérou * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include // à enlever après #include #include #include "grille.h" char repr_jeton(jeton j) { switch (j) { case (BLEU): return 'B'; case (ROUGE): return 'R'; default: return '_'; } } void print_tab(jeton *tab, int n) { for (int i=0; i %x (%d)\n", &tab[i], tab[i], tab[i]); printf("\n"); } void print_colonne(colonne *col) { for (int i=0; icapacite; i++) putc(repr_jeton(col->jetons[i]), stdout); putc('\n', stdout); } void init_zeros(jeton* ptr, int count) { for (int i=0; ijetons = malloc(capacite*sizeof(jeton)); if (col->jetons == NULL) { free(col); return NULL; } init_zeros(col->jetons, capacite); col->capacite = capacite; col->hauteur = 0; return col; } bool agrandir_colonne(int diff_taille, colonne *col) { jeton *jetons_nouv = realloc(col->jetons, (col->capacite + diff_taille)*sizeof(jeton)); if (jetons_nouv == NULL) return false; // allocation impossible, on garde col->jetons tel quel col->jetons = jetons_nouv; // on met des zéros dans la partie nouvellement attribuée init_zeros(col->jetons + col->capacite, diff_taille); // free est appelée par realloc et les éléments sont copiés par realloc col->capacite += diff_taille; return true; } bool ajouter_jeton_col(jeton j, colonne *col) { if (col->hauteur >= col->capacite && !agrandir_colonne(Y_BLOCK_SIZE, col)) return false; col->jetons[col->hauteur] = j; printf("(%p)->jetons[%d] = %c\n", col, col->hauteur, repr_jeton(j)); col->hauteur++; return true; } jeton get_jeton_col(int indice, colonne *col) { return (indice < col->hauteur) ? col->jetons[indice] : VIDE; } void detruire_colonne(colonne *col) { free(col->jetons); free(col); } /* * On essaie de représenter une structure abstraite comme ceci : * En abscisse, les "colonne*"; en ordonnée, les "jeton" * * +oo (jetons) * ^ * | * | * | * | * | * -oo <------------------------I----------------------> +oo (colonne*) * * Représentation en mémoire : * * g->positifs = [colonne*(0), colonne*(1), ...] * // autant que de colonnes positives ou nulles ç.à.d autant que g->n_positifs * * g->negatifs = [colonne*(-1), colonne*(-2) , ...] * // autant que de colonnes str. négatives ç.à.d autant que g->n_negatifs */ grille *creer_grille(int largeur) { /* On divise largeur en deux : * * |-----------------------------|-----------------------------| * negatifs 0 positifs * * d'où n_positifs = largeur/2 + largeur%2 * n_negatifs = largeur/2 * * de telle sorte que: * n_negatifs + n_positifs = largeur * * Ex : * - L'intervalle [-10, 9] de cardinal 20 se découpe en * 10 nombres positifs [0, 9] et 10 nombres négatifs [-10, -1] représenté */ grille *g = malloc(sizeof(grille)); if (g == NULL) return NULL; g->n_positifs = largeur/2 + largeur%2; g->n_negatifs = largeur/2; g->positifs = malloc(g->n_positifs * sizeof(colonne*)); g->negatifs = malloc(g->n_negatifs * sizeof(colonne*)); /* if (g->positifs == NULL || g->negatifs == NULL) { free(g->positifs); free(g->negatifs); free(g); return NULL; } bool echec_allocation = false; */ for (int i=0; i < g->n_positifs; i++) { g->positifs[i] = creer_colonne(Y_BLOCK_SIZE); //if (g->positifs[i] == NULL) // echec_allocation = true; } for (int i=0; i < g->n_negatifs; i++) { g->negatifs[i] = creer_colonne(Y_BLOCK_SIZE); //if (g->negatifs[i] == NULL) // echec_allocation = true; } // si une colonne n'a pas pu être crée, on détruit la grille /* if (echec_allocation) { detruire_grille(g); return NULL; } */ return g; } bool etendre_tab(int d_len, int *len, colonne ***tab) { /* Fonction qui prend en entrée une différence de taille, un pointeur * vers un tableau de colonnes et un pointeur vers sa longueur. * * Si la réallocation n'échoue pas (99.99% des cas), le pointeur vers * le tableau est éventuellement modifié (selon la tambouille de realloc) * et la taille est modifiée. * * Un argument est un colonne*** car c'est un pointeur vers un tableau de colonne* * */ colonne **tab_nouv = realloc(*tab, (*len + d_len)*sizeof(colonne*)); if (tab_nouv == NULL) return false; // la mémoire n'a pas pu être allouée *tab = tab_nouv; bool echec_allocation = false; for (int i=0; in_negatifs, &g->negatifs); } bool etendre_droite(int d_len, grille *g) { // application sur les positifs return etendre_tab(d_len, &g->n_positifs, &g->positifs); } colonne *get_colonne(int i, grille *g) { /* La structure de tableau double sens se traduit de la façon suivante : * * Si i >= 0, on regarde g->positifs[i] * Si i < 0, on regarde g->negatifs[-i-1] */ if (i >= 0 && i < g->n_positifs) return g->positifs[i]; else if (i < 0 && ~i < g->n_negatifs) return g->negatifs[~i]; else return NULL; // en dehors de l'allocation } jeton get_case(int x, int y, grille *g) { colonne *col = get_colonne(x, g); return (col != NULL) ? get_jeton_col(y, col) : VIDE; } bool ajouter_jeton(jeton j, int x, grille *g) { if (x >= 0 && x > g->n_positifs) for (int i=0; i < x-g->n_positifs+1; i++) if (!etendre_droite(X_BLOCK_SIZE, g)) return false; if (x < 0 && ~x > g->n_negatifs) for (int i=0; i < ~x-g->n_negatifs+1; i++) if (!etendre_gauche(X_BLOCK_SIZE, g)) return false; return ajouter_jeton_col(j, get_colonne(x, g)); } void detruire_grille(grille *g) { for (int i=0; i < g->n_positifs; i++) if (g->positifs[i] != NULL) detruire_colonne(g->positifs[i]); for (int i=0; i < g->n_negatifs; i++) if (g->negatifs[i] != NULL) detruire_colonne(g->negatifs[i]); free(g); } // =========================================== TEST ================================================= int test_colonne() { colonne *col = creer_colonne(Y_BLOCK_SIZE); print_colonne(col); for (int i=0; i<15; i++) { if (ajouter_jeton_col((i%2==0) ? ROUGE : BLEU, col)) printf("Jeton ajouté.\n"); else fprintf(stderr, "Erreur dans l'ajout d'un jeton.\n"); } print_colonne(col); detruire_colonne(col); return 0; } void print_grille(grille *g) { printf("n_positifs : %d ; n_negatifs : %d\n", g->n_positifs, g->n_negatifs); for (int i=-g->n_negatifs; in_positifs; i++) { printf("% 5d | ", i); print_colonne(get_colonne(i, g)); } } int test_grille() { grille *g = creer_grille(20); ajouter_jeton(BLEU, 0, g); ajouter_jeton(BLEU, 0, g); ajouter_jeton(BLEU, 0, g); ajouter_jeton(ROUGE, -1, g); ajouter_jeton(BLEU, -1, g); ajouter_jeton(BLEU, -1, g); ajouter_jeton(BLEU, -2, g); ajouter_jeton(ROUGE, 4, g); ajouter_jeton(ROUGE, 4, g); ajouter_jeton(ROUGE, 4, g); ajouter_jeton(BLEU, 240, g); print_grille(g); detruire_grille(g); return 0; } int main() { return test_grille(); }