实现了astar
今天早上头脑清醒,再加上昨天做迷宫的经验,1个小时就把a*寻路编好了。可以递归又没有队列那玩意儿编着真爽。没看过真正的astar代码,但也琢磨得八九不离十吧:D 下面是我的理解:
有人说a*速度快但是有时候寻不到路径,也有人说a*和普通搜索一样正确率是100%。都对,如果你想节省一点空间就可以把子路径的数量减少一些,否则你也可以找所有路径。要根据g()把它们排序一下,损失的时间是在于排序,但能保证100%的有解,因为这样只是相当于普通的深搜搞乱了一下顺序。正因为这样,a*是比深搜费很多空间的(难道这就是跌代加深?)。
#include <cstdlib>
#include <cmath>
#include <iostream>
using namespace std;
enum {WAY, WALL = 5};
const int side = 10;
char maze[side][side];
void init_maze ()
{
for (int i = 0; i < side; ++i)
maze[5][i] = WALL, maze[8][i] = WALL;
maze[5][4] = WAY; maze[5][8] = WAY;
maze[8][1] = WAY;
maze[8][7] = WAY;
}
void swap (int *a, int *b)
{
int tmp[3] = {a[0],a[1],a[2]};
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
b[0] = tmp[0];
b[1] = tmp[1];
b[2] = tmp[2];
}
void gsort (int next[3][3])
{
for (int i = 0; i < 3; ++i) {
int dx = side -1 - next[i][0];
int dy = side -1 - next[i][1];
next[i][2] = (int)sqrt (1.0 * dx*dx + dy*dy);
}
// sort by next[][2]
if (next[1][2] < next[0][2])
swap (next[1], next[0]);
if (next[2][2] < next[0][2])
swap (next[2], next[0]);
if (next[2][2] < next[1][2])
swap (next[2], next[1]);
}
bool astar (int x, int y)
{
if (maze[x][y] != WAY)
return false;
maze[x][y] = '*'; // mark
if (x == side-1 && y == side-1)
return true;
// sort the directions with g ()
int nextpos[3][3] = {{x+1,y,0},{x,y+1,0},{x,y-1,0}};
gsort (nextpos);
for (int i = 0; i < 3; ++i)
if (astar (nextpos[i][0], nextpos[i][1]) == true)
return true;
maze[x][y] = 0;
return false;
}
void showmaze ()
{
for (int i = 0; i < side; ++i) {
for (int j = 0; j < side; ++j)
cout << maze[i][j] << ' ';
cout << '\n';
}
}
void runmaze ()
{
init_maze ();
astar (0, 0);
showmaze ();
}
int main(int argc, char *argv[])
{
runmaze ();
system("PAUSE");
return EXIT_SUCCESS;
}
#include <cmath>
#include <iostream>
using namespace std;
enum {WAY, WALL = 5};
const int side = 10;
char maze[side][side];
void init_maze ()
{
for (int i = 0; i < side; ++i)
maze[5][i] = WALL, maze[8][i] = WALL;
maze[5][4] = WAY; maze[5][8] = WAY;
maze[8][1] = WAY;
maze[8][7] = WAY;
}
void swap (int *a, int *b)
{
int tmp[3] = {a[0],a[1],a[2]};
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
b[0] = tmp[0];
b[1] = tmp[1];
b[2] = tmp[2];
}
void gsort (int next[3][3])
{
for (int i = 0; i < 3; ++i) {
int dx = side -1 - next[i][0];
int dy = side -1 - next[i][1];
next[i][2] = (int)sqrt (1.0 * dx*dx + dy*dy);
}
// sort by next[][2]
if (next[1][2] < next[0][2])
swap (next[1], next[0]);
if (next[2][2] < next[0][2])
swap (next[2], next[0]);
if (next[2][2] < next[1][2])
swap (next[2], next[1]);
}
bool astar (int x, int y)
{
if (maze[x][y] != WAY)
return false;
maze[x][y] = '*'; // mark
if (x == side-1 && y == side-1)
return true;
// sort the directions with g ()
int nextpos[3][3] = {{x+1,y,0},{x,y+1,0},{x,y-1,0}};
gsort (nextpos);
for (int i = 0; i < 3; ++i)
if (astar (nextpos[i][0], nextpos[i][1]) == true)
return true;
maze[x][y] = 0;
return false;
}
void showmaze ()
{
for (int i = 0; i < side; ++i) {
for (int j = 0; j < side; ++j)
cout << maze[i][j] << ' ';
cout << '\n';
}
}
void runmaze ()
{
init_maze ();
astar (0, 0);
showmaze ();
}
int main(int argc, char *argv[])
{
runmaze ();
system("PAUSE");
return EXIT_SUCCESS;
}