自定义迷宫类以及相关结构体,直接上代码,有空我会把布线问题也更新一下
下面展示一些 maze.h
。
// An highlighted block
#include<iostream>
#include<time.h>
#include<stack>
#include<windows.h>
using namespace std;
class maze
{
public:
maze():Maze(nullptr), size(0),isinit(false){};
void ramdonint(int=10);
void showmaze() const;
int getSize() const{ return size; };
int* operator[](int row){ return Maze[row]; };
//虽然三五法则,但是这里好像真的不需要拷贝构造和等号重载?
~maze();
private:
int size;
int** Maze;
bool isinit;
};
struct position
{
int row;
int col;
position(int Col=0, int Row=0) :row(Row), col(Col){};
void operator=(position& p){ row = p.row; col = p.row; };
};
下面展示一些 maze.cpp
。
// An highlighted block
#include"maze.h"
void maze::ramdonint(int Size)
{
size = Size;
srand((int)time(NULL));
if (!isinit)
{
Maze = new int*[Size + 2]{};
for (int i = 0; i <= Size + 1; i++)
{
Maze[i] = new int[Size + 2]{};
if (i == 0 || i == size + 1){ continue; }//第一行行为空
for (int j = 1; j <= Size; j++)//第一列为空,最后一列为空
{
if (rand() % 10 > 7)
{
Maze[i][j] = 1;
}
}
}
isinit = true;
}
else
{
for (int i = 1; i < Size + 1; i++)
{
for (int j = 1; j < Size + 1; j++)//第一列为空,最后一列为空
{
if (rand() % 10 > 7)
{
Maze[i][j] = 1;
}
else
{
Maze[i][j] = 0;
}
}
}
}
Maze[1][1] = 0;
Maze[size][size]=0;
}
void maze::showmaze()const
{
for (int i = 0; i <= size+1; i++)
{
for (int j = 0; j <=size+1; j++)
{
cout << Maze[i][j] << " ";
}
cout << endl;
}
}
maze::~maze()
{
if (nullptr != Maze)
{
for (int i = 0; i < size; i++)
{
delete[] Maze[i];
}
}
delete[] Maze;
Maze = nullptr;
}
下面展示一些 main.cpp
。
// An highlighted block
#include"maze.h"
bool findpath(maze& m);
void main()
{
int count = 1;
maze m;
m.ramdonint();
do{
m.ramdonint();
Sleep(1000);
} while (!findpath(m));
system("cls");
m.showmaze();
m.~maze();
system("pause");
}
bool findpath(maze& m)//深搜
{
static const position* const offSet = new position[4]{{1, 0}, { 0, 1 }, { -1, 0 }, { 0, -1 }};//右下左上
stack<position> *path;
path = new stack<position>();
int size = m.getSize();
for (int i = 0; i <= size+1; i++)
{
m[0][i] = m[size + 1][i] = 1;
m[i][0] = m[i][size + 1] = 1;
}
position here(1, 1);
m[1][1] = 2;
int option = 0;
int maxoption = 3;
while (here.row != size || here.col != size)
{
int r, c;
while (option <= maxoption)
{
r = here.row + offSet[option].row;
c = here.col + offSet[option].col;
if (m[r][c] == 0 )
{
break;
}
option++;
}
if (option <= maxoption)
{
path->push(here);
here.row = r;
here.col = c;
m[r][c] = 2;
option = 0;//从头开始选
}
else
{
if (path->empty())
return false;
position next = path->top();
path->pop();
if (next.row == here.row)//如果上一步在同一排
{
option = 2 + next.col - here.col;//上一步在这一步左边为1,右边为3,对应还有3和1次搜寻机会
}
else
{
option = 3 + next.row - here.row;//同理,如果在同一列,上面为2,下面为4,对应2和0次搜索机会
}
m[here.row][here.col] = 2;
m[next.row][next.col] = 2;
here = next;
}
}
m[size][size] = 2;
delete path;
delete[] offSet;
return true;
}
运行结果
2为曾经走过的路径
下面展示一些 广搜实现寻路
。
// An highlighted block
bool findpath2(maze& m)//广搜
{
static const position* const offSet = new position[4]{{1, 0}, { 0, 1 }, { -1, 0 }, { 0, -1 }};//右下左上
queue<position> *path;
path = new queue<position>();
int size = m.getSize();
for (int i = 0; i <= size + 1; i++)
{
m[0][i] = m[size + 1][i] = 1;
m[i][0] = m[i][size + 1] = 1;
}
position here(1, 1);
m[1][1] = 2;
position nbr;
int numofNbrs = 4;//同一方格能到达的方格数
while (true)
{
for (int i = 0; i < numofNbrs; i++)
{
nbr.row = here.row + offSet[i].row;
nbr.col = here.col + offSet[i].col;
if (m[nbr.row][nbr.col]==0)
{
m[nbr.row][nbr.col] = m[here.col][here.col] + 1;
if (nbr.col == size&&nbr.row == size)
{
here = position(size, size);
break;
}
path->push(nbr);
}
if (path->empty())
{
return false;
}
here = path->front();//取下一个位置,可能一次push进去了很多个位置,但是都是右下左上顺序取
path->pop();
}
}//把所有跟出发点联通的区域都标记好之后
//构造路径,
int length = m[size][size] - 2;
position *way = new position[length];
//从终点逆推
for (int j = length - 1; j >= 0; j--)
{
way[j] = here;
for (int i = 0; i < numofNbrs; i++)
{
nbr.row = here.row + offSet[i].row;
nbr.col = here.col + offSet[i].col;
if (m[nbr.row][nbr.col] == j + 2) break;//如果比目前的数小一个
}
here = nbr;//更新位置
}
delete path;
delete [] way;
delete [] offSet;
return true;
}