前言
许多游戏里都需要给AI寻路算法,而其中最简单的就是BFS暴力搜索
思路
注:地图只有起点(S)、终点(E)、空地(.) 和 墙(#)
1.遍历:BFS遍历一遍地图,并记录下走到每一个格子的最短步数(最短步数为附近4格走过的格子的步数+1)
遍历
(若便利不到终点说明到不了终点)
2.回寻:从终点开始遍历,比较附近4个格子(走过的)的最短步数,选择其中最小的(一样的选先查询的那个),就可一知道最短路径了
回寻
(你或许看见两个视频不一样,是应为有一个丢失了重做的)
代码流程
1.输入地图大小和地图
2. bfs一遍,直到找到终点,找不到就是(队列空)起点走不到终点,在寻找过程中记录每一个格子的最短路径,如果最终找不到终点就说明到不了
3.如果到得了就回寻,并把回寻路径在输出地图(一个数组变量)中标出来(或记录下来)
4.如果到得了就输出输出地图,否则输出"到不了"。
C++演示代码:
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int M = 10001;
struct Node {
int x, y;
Node (int _x = 0, int _y = 0, int _step = 0) : x(_x), y(_y) {}
};
int n, m, step[M][M], dic[10][3] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };
char map[M][M], ans[M][M];
int bfs(Node start, Node end);
bool rightful(int x, int y), vis[M][M];
void check(Node start, Node end);
void init(Node &start, Node &end), print();
int main() {
Node start, end;
init(start, end); // 输入
if (bfs(start, end) == -1) cout << "到不了"; // 走不到终点
else {
check(start, end); // 查询终点到起点的路径
print(); // 输出路径
}
system("pause");
return 0;
}
void print() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
printf("%c ", ans[i][j]);
printf("\n");
}
}
void init(Node &start, Node &end) {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> map[i][j];
ans[i][j] = map[i][j]; // 复制地图
if (ans[i][j] == 'S') start = Node(i, j); // 找到起点
if (ans[i][j] == 'E') end = Node(i, j); // 找到终点
}
}
bool rightful(int x, int y) {
if (x < 1 or x > n or y < 1 or y > m) return false; // 是否出界
if (ans[x][y] == '#') return false; // 是否障碍
if (vis[x][y]) return false; // 是否走过
return true;
}
int bfs(Node start, Node end) {
queue <Node> q;
q.push(Node(start.x, start.y)); // 起点入队
vis[start.x][start.y] = true; // 标记起点走过
while (!q.empty()) {
Node t = q.front();
q.pop();
if (t.x == end.x and t.y == end.y) return 0; // 到达终点
for (int i = 0; i < 4; i++) {
int x = t.x + dic[i][0], y = t.y + dic[i][1];
if (rightful(x, y)) {
step[x][y] = step[t.x][t.y] + 1; // 记录步数
vis[x][y] = true; // 标记走过
q.push(Node(x, y)); // 入队
}
}
}
return -1;
}
void check(Node start, Node end) {
int x = end.x, y = end.y;
while (1) {
Node minn = Node(x, y); // INT_MAX是2147483647
int ms = INT_MAX;
for (int i = 0; i < 4; i++) {
int tx = x + dic[i][0], ty = y + dic[i][1];
if (tx == start.x and ty == start.y) return; // 到达起点
if (step[tx][ty] == 0) continue; // 出界或障碍
if (ms > step[tx][ty]) {
minn = Node(tx, ty); // 记录最小步数
ms = step[tx][ty];
}
}
x = minn.x, y = minn.y; // 走到最小步数的位置
ans[x][y] = '*'; // 标记路径
}
}
变量:
结构体Node:表示一个点,里面有坐标(x, y)
start, end:起点和终点
n, m:地图大小(长和宽)
step:记录节点到起点的最短步数
dic:四个方向
map:输入的地图
ans:输出的地图(路径写在这里面)
常量:
M:最大地图大小
函数:
init():输入
bfs():bfs查找
rightful(int x, int y):此节点是否可走(rightful:正确的)
check():回寻