From aa2cc63942fccc944000e3115df186f1fc4aec34 Mon Sep 17 00:00:00 2001 From: Diane Date: Fri, 21 Apr 2017 22:16:35 +0200 Subject: [PATCH] Add files via upload --- game.c | 125 ++++++++++++++++++++++++ game.h | 97 +++++++++++++++++++ grid.c | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++ grid.h | 208 ++++++++++++++++++++++++++++++++++++++++ rgb.c | 97 +++++++++++++++++++ rgb.h | 132 +++++++++++++++++++++++++ solveur1.c | 145 ++++++++++++++++++++++++++++ solveur1.h | 28 ++++++ 8 files changed, 1107 insertions(+) create mode 100644 game.c create mode 100644 game.h create mode 100644 grid.c create mode 100644 grid.h create mode 100644 rgb.c create mode 100644 rgb.h create mode 100644 solveur1.c create mode 100644 solveur1.h diff --git a/game.c b/game.c new file mode 100644 index 0000000..ebccf49 --- /dev/null +++ b/game.c @@ -0,0 +1,125 @@ +#include "game.h" + +game *gameInit(int size, int cNb) { + if(size < 2 || cNb < 2) exit(1); + game *g = (game *)calloc(1, sizeof(game)); + if(!g) exit(1); + g->size = size; + g->cNb = cNb; + g->cTab = rgbArrayGenRand(cNb); + while(rgbArrayHasDuplicate(g->cTab,cNb)) g->cTab = rgbArrayGenRand(cNb); + g->grid = gridInit(size); + gridInitColors(g->grid, g->cTab, cNb); + g->cPlayer = gridGetColor(g->grid, 0, 0); + g->turnCount = 0; + return g ; +} + +void gameCopy(game* g1, game* g2) { + g2->cTab = g1->cTab; + g2->turnCount = g1->turnCount; + gridCopy(g1->grid,g2->grid); + g2->cPlayer = g1->cPlayer; +} + +void gamePrint(game *g) { + printf("Color Flood :\nSize : %2d nb_Colors : %2d\n", g->size, g->cNb); + printf("Colors available :\n"); + rgbArrayPrint(g->cTab, g->cNb); + printf("Board state:\n"); + gridPrint(g->grid, g->cTab, g->cNb); + /* tests */ + printf("Labels:\n"); + gridPrintLabels(g->grid); + /* end tests */ + printf("Player's color: %d\n", rgbColorToInt(g->cPlayer,g->cTab,g->cNb)); + rgbPrint(g->cPlayer); +} + +void gameFree(game *g) { + free(g->cTab); + gridFree(g->grid); + free(g); +} + +void gamePlayTurn(game *g) { + char line[256]; + int color; + printf("Enter new color: \n"); + if (fgets(line, sizeof(line), stdin)) { + if (1 == sscanf(line, "%d", &color)) { + if(color < 0 || color > g->cNb-1 || rgbEqual(g->cPlayer, g->cTab[color])) { + printf("Not a valid color\n"); + } + else { + gridSetColor(g->grid, g->cTab[color], 0, 0); + gridFloodFillColor(g->grid, 0, 0); + gridSetLabel(g->grid, gridGetMaxLabel(g->grid) + g->turnCount, 0, 0); + gridFloodFillLabel(g->grid, 0, 0); + g->cPlayer = g->cTab[color]; + g->turnCount++; + } + } + } +} + +bool gameOver(game *g) { + return gridIsUniform(g->grid); +} + +game *gameImport(char *save) { + + char buffer[256]; + int size, colors; + + FILE *fp = fopen(save,"r"); + if(fp == NULL) { + printf("save not found\n"); + exit(1); + } + + /* FILE FORMAT : + * grid_size cNb + * R G B (cNb lines) + * 11 12 13 .... + * 21 22 23 .... + * ............. + */ + + fgets(buffer, sizeof(buffer), fp); + if(sscanf(buffer, "%d %d", &size, &colors) != 2) { + printf("Not a valid save file\n"); + exit(1); + } + + if(size < 2 || colors < 2) exit(1); + game *g = (game *)calloc(1, sizeof(game)); + if(!g) exit(1); + g->size = size; + g->cNb = colors; + g->turnCount = 0; + g->cTab = rgbImport(fp, colors); + g->grid = gridImport(fp, size, g->cTab, colors); + g->cPlayer = gridGetColor(g->grid, 0, 0); + + fclose(fp); + + return g; +} + +void gameExport(game *g) { + + char name[100]; + /* generate name from date */ + sprintf(name, "save_%ju.data",time(NULL)); + FILE *fp = fopen(name,"ab+"); + if(fp == NULL) exit(1); + + fprintf(fp, "%d %d\n", g->size, g->cNb); + + rgbExport(fp, g->cTab, g->cNb); + gridExport(fp, g->grid, g->cTab, g->cNb); + + fclose(fp); + +} diff --git a/game.h b/game.h new file mode 100644 index 0000000..5852c63 --- /dev/null +++ b/game.h @@ -0,0 +1,97 @@ +#ifndef GAME_H +#define GAME_H + +/** +* \file game.c +* \author LastButNotLeast +* \date Mars 2017 +* \brief Gestion du jeu pendant une partie. +*/ +#include +#include +#include "rgb.h" +#include "grid.h" + +/** +* \struct t_game +* \brief Structure de la partie +*/ +typedef struct t_game { + grid *grid; /**< Grille du jeu */ + int size; /**< Taille de la grille, ie nombre de cases sur un coté. (duplicate data, size in grid too)*/ + int cNb; /**< Nombre de couleurs différentes*/ + int turnCount; /**< Nombre de clic au cours de la partie*/ + RGB *cTab; /**< Tableau contenant toutes les couleurs*/ + RGB cPlayer; /**< Couleur du joueur, ie couleur de la case en haut à gauche (première case)*/ +} game; + +/** +* \fn gameInit(int size, int cNb) +* \brief Initialise une partie avec une grille qui contient un nombre donné de couleurs au hasard +* +* \param size : taille de la grille à générer ie nombre de cases d'un coté +* \param cNb : Nombre de couleurs différentes +* \return Le jeu généré. +*/ +game *gameInit(int size, int cNb); + +/** +* \fn gameCopy(game* g1, game* g2) +* \brief Copie la partie g1 dans la partie g2. +* +* \param g1 : le jeu à copier +* \param g2 : le jeu dans lequel on va copier +*/ +int gameCopy(game* g1, game* g2); + +/** +* \fn gamePrint(game *g) +* \brief Affiche la grille de jeu et d'autres informations +* +* \param g : le jeu +*/ +void gamePrint(game *g); + +/** +* \fn gameFree(game *g) +* \brief Supprime la partie +* +* \param g : le jeu +*/ +void gameFree(game *g); + +/** +* \fn gamePlayTurn(game *g) +* \brief Modifie la grille après que le joueur ait décidé d'une couleur +* +* \param g : le jeu +*/ +void gamePlayTurn(game *g); + +/** +* \fn gameOver(game *g) +* \brief Teste si la partie est terminée (victoire du joueur) ou si elle continue +* +* \param g : le jeu +* \return true si le jeu est terminé, false sinon +*/ +bool gameOver(game *g); + +/** +* \fn gameImport(char *save) +* \brief Importe une partie depuis un fichier existant +* +* \param save : le fichier +* \return le jeu généré +*/ +game *gameImport(char *save); + +/** +* \fn gameExport(game *g) +* \brief *Exporte une partie dans un fichier +* +* \param g : le jeu à exporter +*/ +void gameExport(game *g); + +#endif diff --git a/grid.c b/grid.c new file mode 100644 index 0000000..dfb2ecd --- /dev/null +++ b/grid.c @@ -0,0 +1,275 @@ +#include "grid.h" +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +grid *gridInit(int size) { + grid *g = (grid *)calloc(1,sizeof(grid)); + if(!g) exit(1); + g->rgbGrid = (RGB *)calloc(1,sizeof(RGB) * size * size); + if(!g->rgbGrid) exit(1); + g->ccGrid = (int *)calloc(1,sizeof(int) * size * size); + if(!g->ccGrid) exit(1); + g->size = size; + return g; +} + + +void gridInitColors(grid *g, RGB *cTab, int cNb) { + assert(cNb > 0); + int i; + for (i=0; i<(g->size * g->size); i++) { + g->rgbGrid[i] = cTab[rand() % cNb]; + } + g->maxLabel = gridLabelCC(g); +} + +grid *gridImport(FILE *fp, int board_size, RGB *cTab, int cNb) { + + char buffer[256]; + char *pnext; + grid *g = gridInit(board_size); + int cIndex; + int i, j; + + for(i=0; i cNb - 1) { + printf("Not a valid save\n"); + exit(1); + } + + /*move pointer to end of word */ + do pnext++; while (*pnext != ' ' && *pnext != '\0'); + + gridSetColor(g, cTab[cIndex], i, j); + j++; + + } while(*pnext != '\0'); + } + + g->maxLabel = gridLabelCC(g); + + return g; +} + +void gridExport(FILE *fp, grid *g, RGB *cTab, int cNb) { + int x,y; + for(x=0; x < g->size; x++) { + for(y=0; y < g->size; y++) { + fprintf(fp, "%s%d%s", + (y>0) ? " ":"", + rgbColorToInt(gridGetColor(g, x, y), cTab, cNb), + (y==g->size-1)?"\n":""); + } + + } +} + +bool gridEqual(grid* g1, grid* g2) { + if (g1->size != g2->size) exit(1); + bool res = true; + int i = 0; + while(res && i < (g1->size * g1->size)) { + res = rgbEqual(g1->rgbGrid[i],g2->rgbGrid[i]); + i++; + } + return res; +} + +void gridCopy(grid* g1, grid* g2) { + if (g1->size != g2->size) exit(1); + int i = 0; + while(i < (g1->size * g1->size)) { + g2->rgbGrid[i] = g1->rgbGrid[i]; + i++; + } +} + +RGB gridGetColor(grid *g, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + return(g->rgbGrid[x * g->size + y]); +} + +void gridSetColor(grid *g, RGB newColor, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + g->rgbGrid[x * g->size + y] = newColor; +} + +int gridGetLabel(grid *g, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + return(g->ccGrid[x * g->size + y]); +} + +void gridSetLabel(grid *g, int newLabel, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + g->ccGrid[x * g->size + y] = newLabel; +} + +int gridGetMaxLabel(grid *g) { + return(g->maxLabel); +} + +bool gridIsUniform(grid *g) { + bool res = true; + int i = 1; + while(res && i < (g->size * g->size)) { + res = rgbEqual(g->rgbGrid[i-1],g->rgbGrid[i]); + i++; + } + return res; +} + +/* FONCTIONNE PAS + * int gridGetCompatibleLabel(grid *g, int x, int y) { + * int lbl = 0,possLbl; + * RGB curCell = gridGetColor(g, x, y); + * if(x>0 && rgbEqual(gridGetColor(g, x-1, y),curCell)) { + * possLbl = gridGetLabel(g, x-1, y); + * lbl = (lbl && possLbl) ? MIN(lbl,possLbl) : MAX(lbl,possLbl); + * } + * if (xsize-1 && rgbEqual(gridGetColor(g, x+1, y),curCell)) { + * possLbl = gridGetLabel(g, x+1, y); + * lbl = (lbl && possLbl) ? MIN(lbl,possLbl) : MAX(lbl,possLbl); + * } + * if (y>0 &&rgbEqual(gridGetColor(g, x, y-1),curCell)) { + * possLbl = gridGetLabel(g, x, y-1); + * lbl = (lbl && possLbl) ? MIN(lbl,possLbl) : MAX(lbl,possLbl); + * } + * if (y>g->size-1 && rgbEqual(gridGetColor(g, x, y+1),curCell)) { + * possLbl = gridGetLabel(g, x, y+1); + * lbl = (lbl && possLbl) ? MIN(lbl,possLbl) : MAX(lbl,possLbl); + * } + * return lbl; + *} + * + *void gridLabelCC(grid *g) { + * int nxtLabel = 1, cmpLabel; + * int i,j; + * * double parcours pour eviter : + * * rgb lbl + * * 1 1 1 2 1 1 1 2 + * * 1 1 1 2 -> 1 1 1 2 + * * 3 3 2 2 3 3 4 2 + * * NB : on pourrait regarder seulement les voisins haut et gauche dans le sens + * * descendant et les voisins bas et droit en remontant, mais faudrait 2 fctn + * * + * for(i=0; isize; i++) { + * for(j=0; jsize; j++) { + * cmpLabel = gridGetCompatibleLabel(g, i, j); + * if(!cmpLabel) cmpLabel = nxtLabel++; + * gridSetLabel(g, cmpLabel, i, j); + * } + * } + * gridPrintLabels(g); + * bool correction = true; + * while(correction) { + * correction = false; + * for(i=g->size-1; i>=0; i--) { + * for(j=g->size-1; j>=0; j--) { + * cmpLabel = gridGetCompatibleLabel(g, i, j); + * if(cmpLabel && (cmpLabel < gridGetLabel(g, i, j))) { + * gridSetLabel(g, cmpLabel, i, j); + * correction = true; + * } + * } + * } + * } + * + *} + */ + +void gridFloodFillLabel(grid *g, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + int lbl = gridGetLabel(g, x, y); + assert(lbl); + RGB currColor = gridGetColor(g, x, y); + if(x>0 && rgbEqual(gridGetColor(g, x-1, y), currColor) && gridGetLabel(g, x-1, y) != lbl) { + gridSetLabel(g, lbl, x-1, y); + gridFloodFillLabel(g, x-1, y); + } + if(xsize-1 && rgbEqual(gridGetColor(g, x+1, y), currColor) && gridGetLabel(g, x+1, y) != lbl) { + gridSetLabel(g, lbl, x+1, y); + gridFloodFillLabel(g, x+1, y); + } + if(y>0 && rgbEqual(gridGetColor(g, x, y-1), currColor) && gridGetLabel(g, x, y-1) != lbl) { + gridSetLabel(g, lbl, x, y-1); + gridFloodFillLabel(g, x, y-1); + } + if(ysize-1 && rgbEqual(gridGetColor(g, x, y+1), currColor) && gridGetLabel(g, x, y+1) != lbl) { + gridSetLabel(g, lbl, x, y+1); + gridFloodFillLabel(g, x, y+1); + } +} + +void gridFloodFillColor(grid *g, int x, int y) { + assert(x > -1 && y > -1 && x < g->size && y < g->size); + RGB c = gridGetColor(g, x, y); + int currLbl = gridGetLabel(g, x, y); + if(x>0 && (gridGetLabel(g, x-1, y) == currLbl) && !rgbEqual(gridGetColor(g, x-1, y), c) ) { + gridSetColor(g, c, x-1, y); + gridFloodFillColor(g, x-1, y); + } + if(xsize-1 && (gridGetLabel(g, x+1, y) == currLbl) && !rgbEqual(gridGetColor(g, x+1, y), c) ) { + gridSetColor(g, c, x+1, y); + gridFloodFillColor(g, x+1, y); + } + if(y>0 && (gridGetLabel(g, x, y-1) == currLbl) && !rgbEqual(gridGetColor(g, x, y-1), c) ) { + gridSetColor(g, c, x, y-1); + gridFloodFillColor(g, x, y-1); + } + if(ysize-1 && (gridGetLabel(g, x, y+1) == currLbl) && !rgbEqual(gridGetColor(g, x, y+1), c) ) { + gridSetColor(g, c, x, y+1); + gridFloodFillColor(g, x, y+1); + } +} + + +int gridLabelCC(grid *g) { + int nxtLabel = 1; + int i,j; + for(i=0; isize; i++) { + for(j=0; jsize; j++) { + if(!gridGetLabel(g, i, j)) { + gridSetLabel(g, nxtLabel, i, j); + nxtLabel++; + gridFloodFillLabel(g, i, j); + } + } + } + return nxtLabel; +} + +void gridPrint(grid *g, RGB *cTab, int cNb) { + assert(cNb > 0); + int i, j; + for(i=0; isize; i++) { + for(j=0; jsize; j++) { + printf("%3d ",rgbColorToInt(g->rgbGrid[i*g->size + j], cTab, cNb)); + } + printf("\n"); + } +} + +void gridPrintLabels(grid *g) { + int i, j; + for(i=0; isize; i++) { + for(j=0; jsize; j++) { + printf("%3d ",gridGetLabel(g, i, j)); + } + printf("\n"); + } +} + +void gridFree(grid *g) { + free(g->rgbGrid); + free(g->ccGrid); + free(g); +} diff --git a/grid.h b/grid.h new file mode 100644 index 0000000..0005aa7 --- /dev/null +++ b/grid.h @@ -0,0 +1,208 @@ +#ifndef GRID_H +#define GRID_H + +/** +* \file grid.c +* \author LastButNotLeast +* \date Mars 2017 +* \brief Gestion de la grille de jeu +*/ +#include +#include +#include +#include +#include "rgb.h" + +/** +* \struct t_grid +* \brief Structure d'une grille +*/ +typedef struct t_grid { + RGB* rgbGrid; /*!< tableau contenant les couleurs (en code RGB) des cases de la grille, mises les unes à la suite des autres */ + int* ccGrid; /*!< tableau contenant la composante connexe (désignée par un entier supérieur ou égal à 1 : "label") à laquelle appartient la case associée */ + int size; /*!< taille de la grille, ie nombre de case sur un coté */ + int maxLabel; /*!< nombre de composantes connexes */ +} grid; + +/** +* \fn gridInit(int size) +* \brief Initialise une grille d'une taille donnée +* +* \param size : taille de la grille à générer ie nombre de cases d'un coté +* \return La grille générée. +*/ +grid *gridInit(int size); + +/** +* \fn gridInitColors(grid *g, RGB *cTab, int cNb) +* \brief Génère des couleurs au hasard dans une grille, associe à chaque case son label et obtient le label maximal. +* +* \param g : la grille dans laquelle il faut mettre des couleurs +* \param cTab : tableau contenant les couleurs en code RGB, dans lequel on va piocher +* \param cNb : nombre de couleurs du tableau +*/ +void gridInitColors(grid *g, RGB *cTab, int cNb); + +/** +* \fn gridImport(FILE *fp, int board_size, RGB *cTab, int cNb) +* \brief Importe une grille à partir d'un fichier existant +* +* \param fp : le fichier +* \param board_size : taille de la grille +* \param cTab : tableau contenant les différentes couleurs +* \param cNb : nombre de couleurs différentes +* \return la grille générée +*/ +grid *gridImport(FILE *fp, int board_size, RGB *cTab, int cNb); + +/** +* \fn gridExport(FILE *fp, grid *g, RGB *cTab, int cNb) +* \brief Exporte une grille dans un fichier +* +* \param fp : le fichier +* \param g : la grille +* \param cTab : tableau contenant les différentes couleurs +* \param cNb : nombre de couleurs différentes +*/ +void gridExport(FILE *fp, grid *g, RGB *cTab, int cNb); + +/** +* \fn gridEqual(grid* g1, grid* g2) +* \brief Vérifie si deux grilles sont identiques +* +* \param g1 : la première grille +* \param g2 : la deuxième grille +* \return true si les grilles sont les mêmes, false sinon. +*/ +bool gridEqual(grid* g1, grid* g2); + +/** +* \fn gridCopy(grid* g1, grid* g2) +* \brief Copie une grille +* +* \param g1 : la grille à copier +* \param g2 : la grille dans laquelle il faut mettre la copie +*/ +void gridCopy(grid* g1, grid* g2); + +/** +* \fn gridGetColor(grid *g, int x, int y) +* \brief Donne la couleur d'une case d'une grille. +* +* \param g : la grille +* \param x : numéro de la colonne qui contient la case visée +* \param y : numéro de la ligne qui contient la case visée +* \return La couleur de la case. +*/ +RGB gridGetColor(grid *g, int x, int y); + +/** +* \fn gridSetColor(grid *g, RGB newColor, int x, int y) +* \brief Affecte une couleur à une case d'une grille. +* +* \param g : la grille +* \param newColor : la couleur à affecter en code RGB +* \param x : numéro de la ligne qui contient la case visée +* \param y : numéro de la colonne qui contient la case visée +*/ +void gridSetColor(grid *g, RGB newColor, int x, int y); + +/** +* \fn gridGetLabel(grid *g, int x, int y) +* \brief Obtient le label d'une case de la grille +* +* \param g : la grille +* \param x : numéro de la ligne qui contient la case visée +* \param y : numéro de la colonne qui contient la case visée +* \return Le numéro de la composante connexe de la case. +*/ +int gridGetLabel(grid *g, int x, int y); + +/** +* \fn gridSetLabel(grid *g, int newLabel, int x, int y) +* \brief Associe un label à une case de la grille +* +* \param g : la grille +* \param newLabel : le label à associer +* \param x : numéro de la ligne qui contient la case visée +* \param y : numéro de la colonne qui contient la case visée +* \return Le numéro de la composante connexe de la case. +*/ +void gridSetLabel(grid *g, int newLabel, int x, int y); + +/** +* \fn gridGetMaxLabel(grid *g) +* \brief Obtient le plus grand label dans la grille +* \details Ce nombre n'est pas le nombre de labels dans la grille, et par conséquent pas le nombre de composantes connexes. +* +* \param g : la grille +* \return Le label maximal. +*/ +int gridGetMaxLabel(grid *g); + +/** +* \fn gridIsUniform(grid *g) +* \brief Cherche si la grille est composée d'une seule couleur +* +* \param g : la grille +* \return true si la grille est unicolore, false sinon. +*/ +bool gridIsUniform(grid *g); + +/** +* \fn gridFloodFillLabel(grid *g, int x, int y) +* \brief Modifie le label de toutes les cases appartenant à la même composante connexe qu'une case visée, pour y associer le label de la case en question. +* +* \param g : la grille +* \param x : numéro de la ligne qui contient la case visée +* \param y : numéro de la colonne qui contient la case visée +*/ +void gridFloodFillLabel(grid *g, int x, int y); + +/** +* \fn gridFloodFillColor(grid *g, int x, int y) +* \brief Modifie la couleur de toutes les cases appartenant à la même composante connexe (ie même label) qu'une case visée, pour y associer la couleur de la case en question. +* +* \param g : la grille +* \param x : numéro de la ligne qui contient la case visée +* \param y : numéro de la colonne qui contient la case visée +*/ +void gridFloodFillColor(grid *g, int x, int y); + +/** +* \fn gridLabelCC(grid *g) +* \brief Associe à chaque case un label (commun aux autres cases de la même composante connexe) et obtient le plus grand label +* \details Le label maximal n'est pas le nombre de labels dans la grille, et par conséquent pas le nombre de composantes connexes +* +* \param g : la grille +* \return Le plus grand label +*/ +int gridLabelCC(grid *g); + +/** +* \fn gridPrint(grid *g, RGB *cTab, int cNb) +* \brief Affiche la grille : chaque case est représentée par le rang de sa couleur (comme élément du tableau de couleurs). +* +* \param g : la grille +* \param cTab : tableau contenant toutes les couleurs en code RGB +* \param cNb : nombre de couleurs différentes contenues dans le tableau +*/ +void gridPrint(grid *g, RGB *cTab, int cNb); + +/** +* \fn gridPrintLabels(grid *g) +* \brief Affiche la grille : chaque case est représentée par son label. +* +* \param g : la grille +*/ +void gridPrintLabels(grid *g); + +/** +* \fn gridFree(grid *g) +* \brief Supprime la grille. +* +* \param g : la grille +*/ +void gridFree(grid *g); + +#endif diff --git a/rgb.c b/rgb.c new file mode 100644 index 0000000..29a2c4e --- /dev/null +++ b/rgb.c @@ -0,0 +1,97 @@ +#include "rgb.h" + + +RGB rgbNew(int R, int G, int B) { + RGB c = { + .R = R % 256, + .G = G % 256, + .B = B % 256, + }; + return c; +} + +RGB* rgbImport(FILE *fp, int cNb) { + + char buffer[256]; + RGB *cTab = (RGB *)malloc(sizeof(RGB) * cNb); + int R, G, B; + + int i; + for(i=0; i < cNb; i++) { + fgets(buffer, sizeof(buffer), fp); + if(sscanf(buffer, "%d %d %d", &R, &G, &B) != 3) { + printf("Not a valid save file\n"); + exit(1); + } + cTab[i] = rgbNew(R,G,B); + } + return cTab; +} + +void rgbExport(FILE *fp, RGB *cTab, int cNb) { + int i; + for(i=0; i < cNb; i++) { + fprintf(fp, "%d %d %d\n", cTab[i].R, cTab[i].G, cTab[i].B); + } +} + +void rgbPrint(RGB c) { + printf("%02x%02x%02x\n",c.R,c.G,c.B); +} + +void rgbArrayPrint(RGB *tab, int size) { + int i; + for(i=0; i 0); + RGB* tab = (RGB *)malloc(sizeof(RGB)*nb); + if(!tab) exit(1); + int i; + for (i=0; i +#include +#include +#include +#include + +/** +* \struct t_RGB +* \brief Structure d'une couleur en utilisant le code rgb +*/ +typedef struct t_RGB { + unsigned char R; /*!< pourcentage de rouge */ + unsigned char G; /*!< pourcentage de vert */ + unsigned char B; /*!< pourcentage de bleu */ +} RGB; + + +/** +* \fn rgbNew(int R, int G, int B) +* \brief Créer une couleur en utilisant les pourcentages donnés de chaque composante +* +* \param R : pourcentage de rouge (en 256) +* \param G : pourcentage de vert (en 256) +* \param B : pourcentage de bleu (en 256) +* \return : la couleur (enc ode RGB) +*/ +RGB rgbNew(int R, int G, int B); + +/** +* \fn rgbImport(FILE *fp, int cNb) +* \brief Importe des couleurs à partir d'un fichier +* +* \param fp : le fichier +* \param cNb : nombre de couleurs différentes +* \return un tableau contenant les couleurs importées +*/ +RGB* rgbImport(FILE *fp, int cNb); + +/** +* \fn rgbExport(FILE *fp, RGB *cTab, int cNb) +* \brief Exporte un tableau de couleurs dans un fichier +* +* \param fp : le fichier +* \param cTab : le tableau de couleurs +* \param cNb : le nombre de couleurs différentes +*/ +void rgbExport(FILE *fp, RGB *cTab, int cNb); + +/** +* \fn rgbPrint(RGB c) +* \brief Affiche les trois composantes de la couleur +* +* \param c : une couleur +*/ +void rgbPrint(RGB c); + +/** +* \fn rgbArrayPrint(RGB *tab, int size) +* \brief Affiche un tableau contenant plusieurs couleurs +* +* \param tab : le tableau qui contient les couleurs +* \param size : nombre de couleurs dans le tableau +*/ +void rgbArrayPrint(RGB *tab, int size); + +/** +* \fn rgbGenRand() +* \brief Genère une couleur au hasard. +* +* \return La couleur générée avec le code RGB. +*/ +RGB rgbGenRand(); + +/** +* \fn rgbArrayGenRand(int nb) +* \brief Génère un tableau de couleurs au hasard. +* +* \details : la taille du tableau doit être non nulle. +* \param nb : taille du tableau à générer. +* \return Le tableau de couleurs avec le code RGB. +*/ +RGB* rgbArrayGenRand(int nb); + +/** +* \fn rgbEqual(RGB c1, RGB c2) +* \brief Teste deux couleurs pour savoir si ce sont les mêmes. +* +* \param c1 : la première couleur +* \param c2 : la deuxième couleur +* \return true si les couleurs sont les mêmes, false sinon. +*/ +bool rgbEqual(RGB c1, RGB c2); + +/** +* \fn rgbColorToInt(RGB c, RGB* tab, int size) +* \brief Cherche une couleur donnée dans un tableau de couleurs. +* +* \param c : la couleur cherchée +* \param tab : le tableau de couleurs +* \param size : la taille du tableau +* \return Le rang de la couleur dans le tableau si elle a été trouvée ; -1 sinon. +*/ +int rgbColorToInt(RGB c, RGB* tab, int size); + +/** +* \fn rgbArrayFree(RGB *tab) +* \brief Supprime un tableau de couleurs. +* +* \param tab : le tableau à supprimer +*/ +void rgbArrayFree(RGB *tab); + +/** +* \fn rgbArrayHasDuplicate(RGB *tab, int size) +* \brief Teste un tableau de couleurs pour savoir si deux couleurs sont les mêmes +* +* \param tab : le tableau de couleurs +* \param size : la taille du tableau +* \return true s'il y a deux couleurs identiques, false sinon. +*/ +bool rgbArrayHasDuplicate(RGB *tab, int size); + +#endif diff --git a/solveur1.c b/solveur1.c new file mode 100644 index 0000000..961e8f1 --- /dev/null +++ b/solveur1.c @@ -0,0 +1,145 @@ +#include "solveur1.h" + + +Stack *stackNew(void){ + Stack *res = (Stack*)calloc(1,sizeof(Stack)); + res->g = NULL; + res->color = -1; + res->NbAttempts = 0; + res->next = NULL; + res->size = 0; + return res; +} + +Stack* cons(Stack* s, game* g, int c, int NbA) +{ + Stack *res = stackNew(); + res->g = g; + res->color = c; + res->NbAttempts = NbA; + res->next = s; + res->size = (s->size)+1; + return res; +} + +void stackFree(Stack *stack){ + free(stack); +} + +int stackEmpty(Stack *stack){ + return (stack->size == 0); +} + +int stackSize(Stack *stack) { + return stack->size; +} + +int stackPush(Stack *stack, game* g, int c, int NbA){ + Stack *pushed; + if ((pushed = cons(stack, g, c, NbA)) == NULL) + return -1; + *stack = *pushed; + return 0; +} + +int stackPop(Stack *stack){ + if (stack == stackNew()) + return -1; + stack->size--; + *stack = *stack->next; + return 0; +} + +Stack* stackReverse(Stack* s) { + Stack* res = stackNew(); + while (!stackEmpty(s)) { + res = cons(res, s->g, s->color, s->NbAttempts); + s=s->next; + } + return res; +} + + +/*********************************************/ +/*********************************************/ +/*********************************************/ + + +bool solveurChoice(game* g, RGB c) { + return (!rgbEqual(g->cPlayer, c)); +} + +bool solveurIsSolution(Stack* solution) { + return gameOver(solution->g); +} + +ensSol* solveurNewSolution(ensSol** oldSolutions, Stack** newSolution) { + ensSol* Solutions = (ensSol*)calloc(1,sizeof(ensSol)); + /*if (oldSolutions->size > stackSize(newSolution)) {*/ + (Solutions)->sol = *newSolution; + (Solutions)->next = *oldSolutions; + (Solutions)->size = (*oldSolutions)->size +1; + + return Solutions; +} + +void solveurPlayTurn(game* g, game* g2, int color) { + gameCopy(g, g2); + gridSetColor(g2->grid, g2->cTab[color], 0, 0); + gridFloodFillColor(g2->grid, 0, 0); + gridSetLabel(g2->grid, gridGetMaxLabel(g2->grid) + g2->turnCount, 0, 0); + gridFloodFillLabel(g2->grid, 0, 0); + g2->cPlayer = g2->cTab[color]; + g2->turnCount++; +} + +void solv(game* g, Stack** solution, ensSol** oldSolutions, int* lim) { + int color=0; + if (!((*oldSolutions)->size == 0)) *lim = ((*oldSolutions)->sol)->NbAttempts; + game* g2 = gameInit(g->size,g->cNb); + while ((g->turnCount < *lim)&&(colorcNb)) { + + if (solveurChoice(g, g->cTab[color])) { + solveurPlayTurn(g, g2, color); + stackPush(*solution, g2, color, g2->turnCount); + if (solveurIsSolution(*solution)) { + *oldSolutions=solveurNewSolution(oldSolutions, solution); + printf("Coucou %d, %d, %d\n", *lim, (*solution)->NbAttempts, g2->turnCount); + } + else solv(g2, solution, oldSolutions, lim); + + stackPop(*solution); + } + + color++; + } + +} + + +void solveurPrint(Stack *solution) { + int k=1; + while (!stackEmpty(solution)) { + printf("%deme coup : couleur %d\n",k,solution->color); + k++; + stackPop(solution); + } +} + +int main() { + game* g = gameInit(10,6); + int lim = 30; + /*game** stock = (game**)calloc(1,sizeof(game*)); + stock[0] = g; + int nbTries=0;*/ + ensSol* oldSolutions = (ensSol*)calloc(1,sizeof(ensSol)); + oldSolutions->sol = stackNew(); + oldSolutions->next = NULL; + oldSolutions->size = 0; + Stack* solution = stackNew(); + solv(g, &solution, &oldSolutions, &lim); + + solveurPrint(stackReverse(oldSolutions->sol)); + + return 0; +} diff --git a/solveur1.h b/solveur1.h new file mode 100644 index 0000000..7402a74 --- /dev/null +++ b/solveur1.h @@ -0,0 +1,28 @@ +/** +* \file solveur1.h +* \author LastButNotLeast +* \date Mars 2017 +* \brief +*/ + +#include +#include +#include +#include +#include "game.h" +#include "rgb.h" +#include "grid.h" + +typedef struct t_stack{ + game* g; + int NbAttempts; + int color; + struct t_stack *next; + int size; +} Stack; + +typedef struct t_ensSol { + Stack *sol; + struct t_ensSol *next; + int size; +} ensSol;