280 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h> // à enlever après
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdbool.h>
 | 
						|
 | 
						|
#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<n; i++)
 | 
						|
		printf("%p --> %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; i<count; i++)
 | 
						|
	{
 | 
						|
		ptr[i] = VIDE;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
colonne *creer_colonne(int capacite)
 | 
						|
{
 | 
						|
	colonne *col = malloc(sizeof(colonne));
 | 
						|
	if (col == NULL)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	col->jetons = 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; i<g->n_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; i<d_len; i++)
 | 
						|
			if ((*tab)[*len + i] != NULL)
 | 
						|
				detruire_colonne((*tab)[*len + i]);
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	*len += d_len;
 | 
						|
 | 
						|
	return true;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool etendre_gauche(int d_len, grille *g)
 | 
						|
{
 | 
						|
	// application sur les négatifs
 | 
						|
	return etendre_tab(d_len, &g->n_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; i<g->n_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;
 | 
						|
}
 |