1 parent
9bd00580d0
commit
fac94d892d
1 file changed
+74
-28
+74
-28
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user