add dfs
This commit is contained in:
parent
e4f1d90c6f
commit
88928aa18c
3 changed files with 133 additions and 12 deletions
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define NBL 20
|
#define NBL 20
|
||||||
#define NBC 20
|
#define NBC 20
|
||||||
#define MAX_CRATES 20
|
#define MAX_DEPTH 16
|
||||||
|
|
||||||
enum movement { MOVE_U = 0, MOVE_D, MOVE_L, MOVE_R, MOVE_W };
|
enum movement { MOVE_U = 0, MOVE_D, MOVE_L, MOVE_R, MOVE_W };
|
||||||
|
|
||||||
|
@ -49,8 +50,9 @@ typedef struct {
|
||||||
sok_board_t state;
|
sok_board_t state;
|
||||||
int path_len;
|
int path_len;
|
||||||
std::string path;
|
std::string path;
|
||||||
} bfsNode;
|
} Node;
|
||||||
|
|
||||||
int bfs(bfsNode &result);
|
int bfs(Node &result);
|
||||||
|
int dfs(Node &result, int depth);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,12 +99,12 @@ void sok_board_t::load(char *_file) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bfs(bfsNode &result) {
|
int bfs(Node &result) {
|
||||||
// Création de la queue de BFS
|
// Création de la queue de BFS
|
||||||
std::queue<bfsNode> q;
|
std::queue<Node> q;
|
||||||
|
|
||||||
// Ajout de l'état initial à la queue
|
// Ajout de l'état initial à la queue
|
||||||
bfsNode first;
|
Node first;
|
||||||
first.state = result.state;
|
first.state = result.state;
|
||||||
first.path_len = 0;
|
first.path_len = 0;
|
||||||
first.path = "";
|
first.path = "";
|
||||||
|
@ -113,7 +113,7 @@ int bfs(bfsNode &result) {
|
||||||
// Boucle principale de la recherche BFS
|
// Boucle principale de la recherche BFS
|
||||||
while (!q.empty()) {
|
while (!q.empty()) {
|
||||||
// Retrait de l'état en tête de la queue
|
// Retrait de l'état en tête de la queue
|
||||||
bfsNode cur = q.front();
|
Node cur = q.front();
|
||||||
q.pop();
|
q.pop();
|
||||||
|
|
||||||
// Si l'état actuel est celui souhaité (toutes les caisses sur des cibles)
|
// Si l'état actuel est celui souhaité (toutes les caisses sur des cibles)
|
||||||
|
@ -154,7 +154,7 @@ int bfs(bfsNode &result) {
|
||||||
next.man1_y = new_man1_y;
|
next.man1_y = new_man1_y;
|
||||||
|
|
||||||
// On ajoute cet état suivant à la queue
|
// On ajoute cet état suivant à la queue
|
||||||
bfsNode next_bfs;
|
Node next_bfs;
|
||||||
next_bfs.state = next;
|
next_bfs.state = next;
|
||||||
next_bfs.path_len = cur.path_len + 1;
|
next_bfs.path_len = cur.path_len + 1;
|
||||||
next_bfs.path = cur.path + move_str[i] + " ";
|
next_bfs.path = cur.path + move_str[i] + " ";
|
||||||
|
@ -205,7 +205,7 @@ int bfs(bfsNode &result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// On ajoute l'état suivant à la queue
|
// On ajoute l'état suivant à la queue
|
||||||
bfsNode next_bfs;
|
Node next_bfs;
|
||||||
next_bfs.state = next;
|
next_bfs.state = next;
|
||||||
next_bfs.path_len = cur.path_len + 1;
|
next_bfs.path_len = cur.path_len + 1;
|
||||||
next_bfs.path = cur.path + move_str[i] + " ";
|
next_bfs.path = cur.path + move_str[i] + " ";
|
||||||
|
@ -218,3 +218,115 @@ int bfs(bfsNode &result) {
|
||||||
// en a pas
|
// en a pas
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dfs(Node &result, int depth) {
|
||||||
|
// Si on a atteint la profondeur maximale, on arrête la recherche
|
||||||
|
if (depth == MAX_DEPTH) {
|
||||||
|
/* std::cout << "max\n"; */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si l'état actuel est celui souhaité (toutes les caisses sur des cibles)
|
||||||
|
if (result.state.num_crates_free <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcours des déplacements possibles à partir de l'état actuel
|
||||||
|
for (int i = 0; i < dsize - 1; ++i) {
|
||||||
|
// Position de la case du joueur
|
||||||
|
int man1_x = result.state.man1_x;
|
||||||
|
int man1_y = result.state.man1_y;
|
||||||
|
|
||||||
|
// Position du joueur après déplacement
|
||||||
|
int new_man1_x = result.state.man1_x + dx[i];
|
||||||
|
int new_man1_y = result.state.man1_y + dy[i];
|
||||||
|
|
||||||
|
// Si la case devant le joueur est un mur, on ignore ce mouvement
|
||||||
|
if (result.state.board[new_man1_x][new_man1_y] == WALL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si la case devant le joueur est libre ou une cible, on déplace le joueur
|
||||||
|
if (result.state.board[new_man1_x][new_man1_y] == FREE ||
|
||||||
|
result.state.board[new_man1_x][new_man1_y] == TARGET) {
|
||||||
|
// On déplace le joueur dans le prochain état
|
||||||
|
sok_board_t next = result.state;
|
||||||
|
|
||||||
|
// Déplacement joueur, ancienne position
|
||||||
|
next.board[man1_x][man1_y] =
|
||||||
|
next.board[man1_x][man1_y] == MAN1_ON_TARGET ? TARGET : FREE;
|
||||||
|
// Déplacement joueur, nouvelle position
|
||||||
|
next.board[new_man1_x][new_man1_y] =
|
||||||
|
next.board[new_man1_x][new_man1_y] == TARGET ? MAN1_ON_TARGET
|
||||||
|
: MAN1_ON_FREE;
|
||||||
|
next.man1_x = new_man1_x;
|
||||||
|
next.man1_y = new_man1_y;
|
||||||
|
|
||||||
|
// On ajoute cet état suivant à la pile
|
||||||
|
Node next_dfs;
|
||||||
|
next_dfs.state = next;
|
||||||
|
next_dfs.path_len = result.path_len + 1;
|
||||||
|
next_dfs.path = result.path + move_str[i] + " ";
|
||||||
|
|
||||||
|
int res = dfs(next_dfs, depth + 1);
|
||||||
|
if (res == 0) {
|
||||||
|
result = next_dfs;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si la case devant le joueur est une caisse, on déplace la caisse et le
|
||||||
|
// joueur
|
||||||
|
if (result.state.board[new_man1_x][new_man1_y] == CRATE_ON_FREE ||
|
||||||
|
result.state.board[new_man1_x][new_man1_y] == CRATE_ON_TARGET) {
|
||||||
|
// Position de la caisse
|
||||||
|
int cx = new_man1_x;
|
||||||
|
int cy = new_man1_y;
|
||||||
|
// Position de la caisse après déplacement
|
||||||
|
int new_cx = cx + dx[i];
|
||||||
|
int new_cy = cy + dy[i];
|
||||||
|
|
||||||
|
// Si la case derrière la caisse n'est pas accessible, on ignore ce
|
||||||
|
// mouvement
|
||||||
|
if (result.state.board[new_cx][new_cy] != TARGET &&
|
||||||
|
result.state.board[new_cx][new_cy] != FREE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On déplace la caisse et le joueur dans le prochain état
|
||||||
|
sok_board_t next = result.state;
|
||||||
|
|
||||||
|
// Déplacement caisse, ancienne position
|
||||||
|
next.board[cx][cy] =
|
||||||
|
next.board[cx][cy] == CRATE_ON_TARGET ? TARGET : FREE;
|
||||||
|
// Déplacement caisse, nouvelle position
|
||||||
|
next.board[new_cx][new_cy] = next.board[new_cx][new_cy] == TARGET
|
||||||
|
? CRATE_ON_TARGET
|
||||||
|
: CRATE_ON_FREE;
|
||||||
|
// Déplacement joueur, ancienne position
|
||||||
|
next.board[man1_x][man1_y] =
|
||||||
|
next.board[man1_x][man1_y] == MAN1_ON_TARGET ? TARGET : FREE;
|
||||||
|
// Déplacement joueur, nouvelle position
|
||||||
|
next.board[new_man1_x][new_man1_y] =
|
||||||
|
next.board[new_man1_x][new_man1_y] == TARGET ? MAN1_ON_TARGET
|
||||||
|
: MAN1_ON_FREE;
|
||||||
|
next.man1_x = new_man1_x;
|
||||||
|
next.man1_y = new_man1_y;
|
||||||
|
|
||||||
|
// On ajoute cet état suivant à la pile
|
||||||
|
Node next_dfs;
|
||||||
|
next_dfs.state = next;
|
||||||
|
next_dfs.path_len = result.path_len + 1;
|
||||||
|
next_dfs.path = result.path + move_str[i] + " ";
|
||||||
|
|
||||||
|
int res = dfs(next_dfs, depth + 1);
|
||||||
|
if (res == 0) {
|
||||||
|
result = next_dfs;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aucune solution n'a été trouvée à partir de cet état
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -11,19 +11,26 @@ int main(int _ac, char **_av) {
|
||||||
S.load(_av[1]);
|
S.load(_av[1]);
|
||||||
S.print_board();
|
S.print_board();
|
||||||
|
|
||||||
bfsNode result;
|
Node result;
|
||||||
|
|
||||||
result.state = S;
|
result.state = S;
|
||||||
result.path = "";
|
result.path = "";
|
||||||
result.path_len = 0;
|
result.path_len = 0;
|
||||||
if (bfs(result) == -1) {
|
/* if (bfs(result) == -1) {
|
||||||
|
std::cout << "Aucune solution trouvée\n";
|
||||||
|
} else {
|
||||||
|
std::cout << "Coups : " << result.path_len << "\n";
|
||||||
|
std::cout << "Solution : " << result.path << "\n";
|
||||||
|
} */
|
||||||
|
|
||||||
|
if (dfs(result, 0) == -1) {
|
||||||
std::cout << "Aucune solution trouvée\n";
|
std::cout << "Aucune solution trouvée\n";
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Coups : " << result.path_len << "\n";
|
std::cout << "Coups : " << result.path_len << "\n";
|
||||||
std::cout << "Solution : " << result.path << "\n";
|
std::cout << "Solution : " << result.path << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
result.state.print_board();
|
// result.state.print_board();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue