#include "game_tools.h" #include #include "game_aux.h" #include "game_ext.h" #include "game_private.h" #define NB_CHAR_HEADER_WITHTOUT_DIMENSIONS 4 game game_load(char* filename) { checkPointer((void*)filename, "NULL pointer filename on game_load\n"); // ouvrons le fichier FILE* f = fopen(filename, "r"); checkPointer((void*)f, "Couldn't open file\n"); // récuperer les valeurs dont on a beson pour créer le jeu initail uint nb_rows, nb_cols; int wrapping; test_output(fscanf(f, "%u %u %d\n", &nb_rows, &nb_cols, &wrapping), 3, "Error in scan of file"); // créer le jeu initail game g1 = game_new_empty_ext(nb_rows, nb_cols, wrapping); checkPointer((void*)g1, "Couldn't create game\n"); // récuperer les coups à jouer for (uint i = 0; i < nb_rows; i++) { for (uint j = 0; j < nb_cols; j++) { test_output(feof(f), 0, "Malformed file : Reached end of file\n"); // obtenir les squares pour les jouer dans g1 char play = fgetc(f); if (play == '\n') play = fgetc(f); if (play == 'b') game_set_square(g1, i, j, S_BLANK); else if (play == '*') game_set_square(g1, i, j, S_LIGHTBULB); else if (play == '-') game_set_square(g1, i, j, S_MARK); else if (play == 'w') game_set_square(g1, i, j, S_BLACKU); else if (play == '0') game_set_square(g1, i, j, S_BLACK0); else if (play == '1') game_set_square(g1, i, j, S_BLACK1); else if (play == '2') game_set_square(g1, i, j, S_BLACK2); else if (play == '3') game_set_square(g1, i, j, S_BLACK3); else if (play == '4') game_set_square(g1, i, j, S_BLACK4); else { fprintf(stderr, "Malformed file : Unrecognized character %c.\n", play); exit(EXIT_FAILURE); } } } fclose(f); game_update_flags(g1); return g1; } /** * @brief Get the char from state object * * @param g game to get the square from * @param i the i coordinate * @param j the j coordinate * @return char of the corresponding square */ char get_char_from_state(cgame g, uint i, uint j) { // char tab[index] => index in enum square char tab[] = {'b', '*', '-', '?', '?', '?', '?', '?', '0', '1', '2', '3', '4', 'w'}; return tab[(int)game_get_state(g, i, j)]; } void game_save(cgame g, char* filename) { checkPointer((void*)filename, "NULL pointer filename on game_save\n"); checkPointer((void*)g, "NULL pointer game g on game_save\n"); // try create or open file named filename FILE* f = fopen(filename, "w"); checkPointer((void*)f, "Couldn't open file in game_save\n"); // try to print the first line (game_nb_rows(g) / 10 + 1 = nb char of a number) test_output(fprintf(f, "%d %d %d\n", game_nb_rows(g), game_nb_cols(g), game_is_wrapping(g)), NB_CHAR_HEADER_WITHTOUT_DIMENSIONS + game_nb_rows(g) / 10 + 1 + game_nb_cols(g) / 10 + 1, "Couldn't print in file.\n"); // for each case of the game get the char of the given case and try to print it on the file for (uint i = 0; i < game_nb_rows(g); i++) { for (uint j = 0; j < game_nb_cols(g); j++) { test_output(fprintf(f, "%c", get_char_from_state(g, i, j)), 1, "Couldn't print in file.\n"); } // print a \n at the end of each row test_output(fprintf(f, "\n"), 1, "Couldn't print in file.\n"); } fclose(f); } bool aux_game_solve(game g, uint deep) { for (uint i = 0; i < game_nb_rows(g); i++) { for (uint j = 0; j < game_nb_cols(g); j++) { if (game_get_state(g, i, j) == S_BLANK) { game_set_square(g, i, j, S_LIGHTBULB); game_update_flags(g); if (game_is_over(g)) return true; if (deep > 1) { if (aux_game_solve(g, deep - 1)) { return true; } } game_set_square(g, i, j, S_BLANK); } } } return false; } bool game_solve(game g) { for (uint deep = 1; deep < game_nb_cols(g) * game_nb_rows(g); deep++) { if (aux_game_solve(g, deep)) { return true; } } return false; } uint game_nb_solutions_aux(game g, game* games) { game game_save = game_copy(g); uint res = 1; if (game_solve(g) == false) { return 0; } games = (game*)calloc(sizeof(game)); games[0] = game_copy(g); uint** tab = (uint**)malloc(sizeof(uint*) * (g->height * g->width)); for (uint r = 0; r < (g->height * g->width); r++) { tab[r] = (uint*)malloc(sizeof(uint) * 2); } uint size = 0; for (uint i = 0; i < g->height; i++) { for (uint j = 0; j < g->width; j++) { if (game_get_state(g, i, j) == S_LIGHTBULB) { tab[size][0] = i; tab[size][1] = j; size++; } } } for (uint s = 0; s < size; s++) { game game_test = game_copy(game_save); res = res + game_nb_solutions_aux(game_test, &games[1]); } return res; } uint game_nb_solutions(cgame g) { game* games = (game*)malloc(0); game g_tmp = game_copy(g); uint nb = game_nb_solutions_aux(g_tmp, games); uint res = nb; for (uint n = 0; n < nb; n++) { for (uint i = n; i < nb; i++) { game g1 = g_tmp[n]; game g2 = g_tmp[i]; if (game_equal(g1, g2)) { res--; } } } return (res); }