#include // à enlever après #include #include #define X_BLOCK_SIZE 20 #define Y_BLOCK_SIZE 10 typedef enum jeton { VIDE = 0, BLEU = 1, ROUGE = 2 } jeton; typedef struct colonne { int hauteur; int capacite; jeton* jetons; } colonne; 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) { print_tab(col->jetons, col->capacite); } 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(jeton j, colonne *col) { if (col->hauteur >= col->capacite && !agrandir_colonne(Y_BLOCK_SIZE, col)) return false; col->jetons[col->hauteur] = j; col->hauteur++; return true; } jeton acceder_jeton_col(int indice, colonne *col) { return (indice < col->hauteur) ? col->jetons[indice] : VIDE; } void detruire_colonne(colonne *col) { free(col->jetons); free(col); } typedef struct grille { int n_positifs; colonne **positifs; int n_negatifs; colonne **negatifs; } grille; /* * 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-1)/2 * n_negatifs = 1 + (largeur-1)/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] * * - ... TODO */ grille *g = malloc(sizeof(grille)); if (g == NULL) return NULL; g->n_positifs = largeur/2; g->positifs = malloc(g->n_positifs * sizeof(colonne*)); if (g->positifs == NULL) free(g); bool echec_allocation = false; for (int i=0; in_positifs; i++) { g->positifs[i] = creer_colonne(Y_BLOCK_SIZE); if (g->positifs[i] == NULL) allocation_fail = true; } // si une colonne n'a pas pu être crée, on détruit la grille if (echec_allocation) { detruire_grille(g); g = 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; i<*d_len; i++) { (*tab)[*len + i] = creer_colonne(Y_BLOCK_SIZE); if ((*tab)[*len + i] == NULL) echec_allocation = true; } // si échec on revient à l'état initial if (echec_allocation) { 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 indice) { // pour les positifs, de l'indice dans la représentation à double sensles positifs: 0 |-> 0 ; 1 |-> 1 } void detruire_grille(grille *g) { for (int i=0; in_positifs) if (g->positifs[i] != NULL) detruire_colonne(g->positifs[i]); for (int i=-1; i>=g->n_negatifs) if (g->negatifs[i] != NULL) detruire_colonne(g->negatifs[i]); free(g); } // =========================================== TEST ================================================= int main() { colonne *col = creer_colonne(Y_BLOCK_SIZE); print_colonne(col); for (int i=0; i<15; i++) { if (ajouter_jeton((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; }