diff --git a/game_tools.c b/game_tools.c index 615dc80..d3e9b32 100644 --- a/game_tools.c +++ b/game_tools.c @@ -354,25 +354,18 @@ int game_analyze(game g) { * @return true if the game is solved * @return false if the game is unsolvable */ -bool aux_game_solve(game g, uint deep, int* move_played, bool nb_sol, uint* cpt) { +bool aux_game_solve(game g, uint deep, int* move_played) { 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) { int tmp = 0; game_play_move(g, i, j, S_LIGHTBULB); if (!game_has_error_general(g)) { - if (game_is_over(g)) { - if (!nb_sol) - return true; - else - (*cpt)++; - } + if (game_is_over(g)) + return true; tmp = game_analyze(g); if (tmp == -1) { - if (!nb_sol) - return true; - else - (*cpt)++; + return true; } if (tmp == -2) { game_undo(g); @@ -381,7 +374,7 @@ bool aux_game_solve(game g, uint deep, int* move_played, bool nb_sol, uint* cpt) } else (*move_played) += tmp; if (deep > 1) { - if (aux_game_solve(g, deep - 1, move_played, nb_sol, cpt)) { + if (aux_game_solve(g, deep - 1, move_played)) { return true; } } @@ -422,7 +415,7 @@ bool game_solve(game g) { // else try brutforce with deepness going from 1 to the total number of blank cases on the game for (uint deep = 1; deep < total_number_of_blank_cases(g); deep++) { total_move_played += move_played; - if (aux_game_solve(g, deep, &move_played, false, NULL)) { + if (aux_game_solve(g, deep, &move_played)) { return true; } } @@ -432,21 +425,74 @@ bool game_solve(game g) { return false; } -uint game_nb_solutions(cgame g) { - game copy_g = game_copy(g); - // first analyze of the game to reduce the number of brutforce needed - int total_move_played = game_analyze(copy_g); - // give move_played and not total_move_played to keep the first analyze - int move_played = 0; - uint nb_solutions = 0; - if (total_move_played == -1) - return 1; - // if the game is unsolvalbe at the first analyze it's unsolvable even with brutforce - if (total_move_played == -2) +uint game_nb_solutions_aux(game g, game* t_games, uint* index, uint* ind_max) { + /*sauvegarde de la game de base*/ + game game_save = game_copy(g); + /*application du game solve*/ + if (game_solve(g) == false) { return 0; - // else try brutforce with deepness going from 1 to the total number of blank cases on the game - for (uint deep = 1; deep < total_number_of_blank_cases(copy_g); deep++) { - aux_game_solve(copy_g, deep, &move_played, true, &nb_solutions); } - return nb_solutions; + + /*copy de la solution dans le tableau*/ + t_games[*index] = game_copy(g); + *index = (*index) + 1; + + if (*index == *ind_max) { + /*allocation de une place en plus dans le tableau t_game pour pouvoir ensuite utiliser en recursif la case d'apres*/ + fprintf(stderr, "Too much solutions\n"); + exit(EXIT_FAILURE); + } + + /*initialisation des différentes variables utilisé par la suite dans la fonction*/ + uint res = 1; // resultat renvoyé par la fonction + uint** tab = (uint**)malloc(sizeof(uint*) * (g->height * g->width)); // tableau stockant l'emplacement des lightbulbs + for (uint r = 0; r < (g->height * g->width); r++) { + tab[r] = (uint*)malloc(sizeof(uint) * 2); + } + uint size = 0; // nombre de lightbulb dans tab + + /*listage est stock des emplacements des lightbulb dans tab*/ + 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++; + } + } + } + + /*marquage dans la game de base des emplacements des lightbulbs 1 a 1 et appel recursif de sorte a tester toutes les possibilitées*/ + for (uint s = 0; s < size; s++) { + game game_test = game_copy(game_save); + game_set_square(game_test, tab[s][0], tab[s][1], S_MARK); + res = res + game_nb_solutions_aux(game_test, t_games, index, ind_max); + game_delete(game_test); + } + game_delete(game_save); + free(tab); + return res; +} + +uint game_nb_solutions(cgame g) { + if (g == NULL) { + return 0; + } + uint index = 0; + uint ind_max = 2048; + game t_games[ind_max]; + game g_tmp = game_copy(g); + uint nb = game_nb_solutions_aux(g_tmp, t_games, &index, &ind_max); + game_delete(g_tmp); + uint res = nb; + for (uint n = 0; n < nb; n++) { + for (uint i = n + 1; i < nb; i++) { + game g1 = t_games[n]; + game g2 = t_games[i]; + if (game_equal(g1, g2)) { + res--; + } + } + } + return (res); } \ No newline at end of file