迷宫问题:给定入口和出口,随机生成一个可以走出去的迷宫。
【解决办法】
1.迷宫地图用二维数组,用随机数生成数组元素,空格为通,#做墙壁。
2.每次探测当前位置的上下左右,如果是通路,继续探测;如果不是通路,回到上一个走过位置,递归调用的思想。
当然也可以用压栈和堆栈来回溯。
3.利用二维数组下标的界限来判断是否找到出口。
这里使用了c++,直接在类中写了代码,由于代码不多,最好还是在类中声明,函数实现单独完成。
给大家贴出代码:
#include<iostream>
#include<getch.h>
#include<stdlib.h>
#include <time.h>
using namespace std;
time_t tstart;
//设置迷宫结构
struct Maze
{
private:
//地图
char map[15][15];
//空位置数量
int space;
//入口位置
char in_x,in_y;
//出口位置
char out_x,out_y;
//坐标
char x,y;
//老鼠位置
char m_x,m_y;
int success;
//......
//构造地图
void create_map(void)
{
srand(time(NULL));
//在地图中全部填#
for(int i=0;i<15;i++)
{
for(int j=0;j<15;j++)
{
map[i][j]='#';
}
}
//设置出口、入口
for(int i=0;i<space;)
{
x=rand()%13+1;
y=rand()%13+1;
if(map[x][y]=='#')
{
map[x][y]=' ';
i++;
}
}
map[in_x][in_y]='@';
if(map[out_x][out_y]!=' ')
{
map[out_x][out_y]=' ';
}
}
//检查地图是否可以走出
int check_map(int i,int j)
{
//参考经典算法大全
map[i][j]='@';
if(i == out_x && j ==out_y )
{
success = 1;
}
if(success != 1 && map[i][j+1] == ' ') check_map(i, j+1);
if(success != 1 && map[i+1][j] == ' ') check_map(i+1, j);
if(success != 1 && map[i][j-1] == ' ') check_map(i, j-1);
if(success != 1 && map[i-1][j] == ' ') check_map(i-1, j);
if(success != 1)
{
map[i][j] = ' ';
}
return success;
}
public:
//构建迷宫
Maze(char inx,char iny,char outx,char outy,int _space)
{
//使用构造函数的参数对成员初始化
in_x=m_x=inx;
in_y=m_y=iny;
out_x=outx;
out_y=outy;
space=_space;
while(1)
{
//构造地图
create_map();
//检查地图是否可以走出
success=0;
if(check_map(in_x,in_y)==1)
{
break;
}
}
for (int i = 0; i < 15; ++i)
{
for(int j=0;j<15;j++)
{
if(map[i][j]=='@')
{
map[i][j]=' ';
}
}
}
map[in_x][in_y]='@';
tstart=time(NULL);
}
//显示迷宫
void show(void)
{
system("clear");
//printf("\33[2J");
for(int i=0;i<15;i++)
{
for(int j=0;j<15;j++)
{
cout<<map[i][j]<<' ';
}
cout<<endl;
}
}
//老鼠向上
void up(void)
{
if(map[m_x-1][m_y]==' ')
{
map[m_x-1][m_y]='@';
map[m_x][m_y]=' ';
m_x-=1;
}
else
{
return;
}
}
//老鼠向下
void down(void)
{
if(map[m_x+1][m_y]==' ')
{
map[m_x+1][m_y]='@';
map[m_x][m_y]=' ';
m_x+=1;
}
else
{
return;
}
}
//向右
void right(void)
{
if(map[m_x][m_y+1]==' '&&m_y<=14)
{
map[m_x][m_y+1]='@';
map[m_x][m_y]=' ';
m_y+=1;
}
else
{
return;
}
}
//向左
void left(void)
{
if(map[m_x][m_y-1]==' '&&m_y>=1)
{
map[m_x][m_y-1]='@';
map[m_x][m_y]=' ';
m_y-=1;
}
else
{
return;
}
}
//检查是否到达出口
bool check(void)
{
if(m_x==out_x&&m_y==out_y)
{
return true;
}
return false;
}
};
int main()
{
//创建迷宫对象
Maze maze(1,1,14,13,140);
while(1)
{
//检查是否走通
if(maze.check())
{
maze.show();
time_t tend=time(NULL);
cout<<"逃出迷宫!用时"<<tend-tstart<<"秒!"<<endl;
break;
}
//显示地图
maze.show();
switch(getch())
{
case 183:maze.up();break;
case 184:maze.down();break;
case 185:maze.right();break;
case 186:maze.left();break;
}
}
}
给大家再来一个用栈实现的版本:
Maze.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include "Stack.h"
using namespace std;
struct Pos
{
Pos(int row = 0, int col = 0)
:_row(row)
, _col(col)
{}
int _row;
int _col;
};
void InitMazeMap(char* map, int row, int col);
void PrintMazeMap(char* map, int row, int col);
bool GetPath(char* map, int row, int col, Pos enter,Stack<Pos>& path);
bool IsExport(const Pos& pos, int row, int col);
bool IsAccess(const Pos& pos, char* map, int row, int col);
void GetSize(int* prow, int* pcol);
Maze.cpp
<pre class="cpp" name="code">#include "Maze.h"
#include <cassert>
void InitMazeMap(char* map, int row, int col)
{
FILE* f1 = fopen("MazeMap.txt", "r");
assert(f1);
//跳过第一行
int ch = fgetc(f1);
while (ch != '\n')
{
ch = fgetc(f1);
}
//开始读取迷宫地图
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col;)
{
ch = fgetc(f1);
if (ch == '0' || ch == '1')
{
map[i*col + j] = ch;
++j;
}
}
}
fclose(f1);
}
void PrintMazeMap(char* map, int row, int col)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
cout << map[i*col + j] << " ";
}
cout << endl;
}
cout << endl;
}
//找通路
bool GetPath(char* map, int row, int col, Pos enter, Stack<Pos>& path)
{
map[enter._row*col + enter._col] = '2';
path.Push(enter);
while (!path.Empty())
{
Pos cur = path.Top();
if (cur._col!= enter._col && cur._row!=enter._row && IsExport(cur,row,col))
{
return true;
}
//上
Pos next = cur;
next._row -= 1;
if (IsAccess(next,map,row,col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//右
next = cur;
next._col += 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//下
next = cur;
next._row += 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
//左
next = cur;
next._col -= 1;
if (IsAccess(next, map, row, col))
{
map[next._row*col + next._col] = '2';
path.Push(next);
continue;
}
map[cur._row*col + cur._col] = '3';
path.Pop();
}
return false;
}
//判断pos位置是否通
bool IsAccess(const Pos& pos, char* map, int row, int col)
{
if (pos._row >= 0 && pos._row < row
&&pos._col >= 0 && pos._col < col
&&map[pos._row*col + pos._col] == '0')
{
return true;
}
else
{
return false;
}
}
//判断pos位置是否为出口
bool IsExport(const Pos& pos, int row ,int col)
{
if (pos._col == 0 || pos._row == 0 || pos._col == (col - 1) || pos._row == (row - 1))
{
return true;
}
else
{
return false;
}
}
//从文件中获取迷宫的大小
void GetSize(int* prow, int* pcol)
{
FILE* f = fopen("MazeMap.txt", "r");
assert(f);
int ch = fgetc(f);
while (ch != '\n' && (ch <= '0' || ch >= '9'))//跳过非数字字符
{
ch = fgetc(f);
}
while (ch >= '0'&&ch <= '9') //row
{
*prow = *prow * 10 + (ch - '0');
ch = fgetc(f);
}
while (ch != '\n'&& (ch<='0' || ch>='9'))
{
ch = fgetc(f);
}
while (ch >= '0' && ch <= '9')//col
{
*pcol = *pcol * 10 + (ch - '0');
ch = fgetc(f);
}
fclose(f);
}
Stack.h当然也可以用库里的,这里自己实现了一下
#pragma once
#include <cassert>
#include <iostream>
using namespace std;
template <class T>
class Stack
{
public:
Stack()
:_data(NULL)
, _size(0)
, _capacity(0)
{}
~Stack()
{
if (_data != NULL)
{
delete _data;
_data = NULL;
_size = 0;
_capacity = 0;
}
}
void Push(const T& data)
{
CheckCapacity();
_data[_size++] = data;
}
void Pop()
{
assert(_size > 0);
_size--;
}
T& Top() const
{
assert(_size > 0);
return _data[_size - 1];
}
bool Empty() const
{
return _size == 0;
}
size_t Size() const
{
return _size;
}
protected:
void CheckCapacity()
{
if (_size == _capacity)
{
size_t newCapacity = _capacity * 2 + 3;
T* tmp = new T[newCapacity];
for (size_t i = 0; i < _size; ++i)
{
tmp[i] = _data[i];
}
delete _data;
_data = tmp;
_capacity = newCapacity;
}
}
protected:
T* _data;
size_t _size;
size_t _capacity;
};
test.cpp
#include "Stack.h"
#include "Maze.h"
void TestStack()
{
Stack<int> s1;
s1.Push(1);
s1.Push(2);
s1.Push(3);
s1.Push(4);
while (!s1.Empty())
{
cout << s1.Top() << endl;
s1.Pop();
}
}
void TestMaze()
{
int row = 0;
int col = 0;
GetSize( &row, &col);
char* Map = (char*)malloc((row*col)*sizeof(char));
Pos mEnter(2, 0);
Stack<Pos> path;
InitMazeMap( Map, row, col);
PrintMazeMap(Map, row, col);
if(GetPath(Map, row, col, mEnter, path))
{
PrintMazeMap(Map, row, col);
}
else
{
cout << "没有通路"<<endl;
}
free(Map);
}
int main()
{
TestMaze();
system("pause");
return 0;
}
版权声明:本文为Dachao0707原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。