mirror of
https://github.com/jie65535/maze.git
synced 2024-07-27 19:04:55 +08:00
Update README and fixes
This commit is contained in:
parent
b23a123012
commit
16c763732a
@ -6,3 +6,8 @@ C++ 控制台 迷宫 使用了自动生成迷宫算法,实现迷宫基本玩
|
||||
所以该代码只能在windows下编译
|
||||
|
||||
程序参数可以在代码头部设置,例如迷宫大小和输出区域大小等
|
||||
|
||||
需要合适的字体才能正常显示
|
||||
|
||||
|
||||

|
451
code.cpp
451
code.cpp
@ -9,10 +9,10 @@
|
||||
using namespace std;
|
||||
|
||||
// 显示区域的大小
|
||||
const size_t sWidth = 30, sHeight = 24;
|
||||
const size_t sWidth = 60, sHeight = 24;
|
||||
|
||||
// 迷宫的实际大小(必须是奇数!)
|
||||
const size_t width = 9, height = 9;
|
||||
const size_t width = 33, height = 15;
|
||||
const char wall = 1;
|
||||
const char path = 0;
|
||||
const char target = 2;
|
||||
@ -34,10 +34,7 @@ vector<pair<pair<int, int>, int> > walls;
|
||||
——2、如果对面的格子已经是通路了,那就从列表里移除这面墙
|
||||
*/
|
||||
|
||||
const int up = 0;
|
||||
const int down = 1;
|
||||
const int left = 2;
|
||||
const int right = 3;
|
||||
enum Dir { Up, Down, Left, Right };
|
||||
|
||||
// 四周一步
|
||||
int xx[] = { 0, 0, -1, 1 };
|
||||
@ -56,288 +53,280 @@ const int margin = 3;
|
||||
// 移动光标到xy位置
|
||||
void gotoxy(int x, int y)
|
||||
{
|
||||
COORD coord = { (short)x, (short)y };
|
||||
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
COORD coord = { (short)x, (short)y };
|
||||
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
|
||||
}
|
||||
|
||||
// 设置全地图为墙
|
||||
void setAllWall()
|
||||
{
|
||||
for (int y = 0; y < height; ++y)
|
||||
for (int x = 0; x < width; ++x)
|
||||
map[y][x] = wall;
|
||||
for (int y = 0; y < height; ++y)
|
||||
for (int x = 0; x < width; ++x)
|
||||
map[y][x] = wall;
|
||||
}
|
||||
|
||||
// 是否越界
|
||||
bool isOutBounds(int x, int y)
|
||||
{
|
||||
return (x<0 || x >= width
|
||||
|| y<0 || y >= height);
|
||||
return (x<0 || x >= width
|
||||
|| y<0 || y >= height);
|
||||
}
|
||||
|
||||
// 向四周探索
|
||||
void explore(int x, int y)
|
||||
{
|
||||
// 遍历四个方向
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// 顺着一条路走
|
||||
for (int x1 = x, y1 = y;
|
||||
!isOutBounds(x1, y1)
|
||||
&& map[y1][x1] == path;
|
||||
x1 += xx[i], y1 += yy[i])
|
||||
{
|
||||
// 每走一个格子检查四周是否为通路
|
||||
for (int fy = y1 - 1; fy <= y1 + 1; ++fy)
|
||||
for (int fx = x1 - 1; fx <= x1 + 1; ++fx)
|
||||
if (!isOutBounds(fx, fy)
|
||||
&& fog[fy][fx])
|
||||
fog[fy][fx] = false;
|
||||
}
|
||||
}
|
||||
// 遍历四个方向
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
// 顺着一条路走
|
||||
for (int x1 = x, y1 = y;
|
||||
!isOutBounds(x1, y1)
|
||||
&& map[y1][x1] == path;
|
||||
x1 += xx[i], y1 += yy[i])
|
||||
{
|
||||
// 每走一个格子检查四周是否为通路
|
||||
for (int fy = y1 - 1; fy <= y1 + 1; ++fy)
|
||||
for (int fx = x1 - 1; fx <= x1 + 1; ++fx)
|
||||
if (!isOutBounds(fx, fy)
|
||||
&& fog[fy][fx])
|
||||
fog[fy][fx] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将坐标处的墙添加到待通墙中
|
||||
void pushAroundWall(int x, int y)
|
||||
{
|
||||
// 遍历四个方向
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int tx = x + xx[i];
|
||||
int ty = y + yy[i];
|
||||
if (isOutBounds(tx, ty))
|
||||
continue;
|
||||
int wx = x + x2[i];
|
||||
int wy = y + y2[i];
|
||||
if (isOutBounds(wx, wy))
|
||||
continue;
|
||||
// 只要是墙就加入列表
|
||||
if (map[ty][tx] == wall)
|
||||
walls.push_back(pair<pair<int, int>, int>(pair<int, int>( tx,ty ),i ));
|
||||
}
|
||||
// 遍历四个方向
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int tx = x + xx[i];
|
||||
int ty = y + yy[i];
|
||||
if (isOutBounds(tx, ty))
|
||||
continue;
|
||||
int wx = x + x2[i];
|
||||
int wy = y + y2[i];
|
||||
if (isOutBounds(wx, wy))
|
||||
continue;
|
||||
// 只要是墙就加入列表
|
||||
if (map[ty][tx] == wall)
|
||||
walls.push_back(pair<pair<int, int>, int>(pair<int, int>( tx,ty ),i ));
|
||||
}
|
||||
}
|
||||
|
||||
// 展示地图
|
||||
void showMap()
|
||||
{
|
||||
int dx = sWidth / 2 - playerx;
|
||||
int dy = sHeight / 2 - playery;
|
||||
// 移动光标到最开始的位置
|
||||
gotoxy(1, 1);
|
||||
int dx = sWidth / 2 - playerx;
|
||||
int dy = sHeight / 2 - playery;
|
||||
// 移动光标到最开始的位置
|
||||
gotoxy(0, 0);
|
||||
|
||||
// 遍历整个地图
|
||||
for (int sy = 0; sy < sHeight; ++sy)
|
||||
{
|
||||
for (int sx = 0; sx < sWidth; ++sx)
|
||||
{
|
||||
//putchar(map[y][x]?'@':' ');
|
||||
int x = sx - dx;
|
||||
int y = sy - dy;
|
||||
// 遍历整个地图
|
||||
for (int sy = 0; sy < sHeight; ++sy)
|
||||
{
|
||||
for (int sx = 0; sx < sWidth; ++sx)
|
||||
{
|
||||
//putchar(map[y][x]?'@':' ');
|
||||
int x = sx - dx;
|
||||
int y = sy - dy;
|
||||
|
||||
const char *Symbol[5] = { "□", "▓", "▽", "☆", "◎" };
|
||||
const char *Symbol[5] = { "□", "▓", "▽", "☆", "◎" };
|
||||
|
||||
if (isOutBounds(x, y))
|
||||
{
|
||||
printf("□");
|
||||
continue;
|
||||
}
|
||||
if (x == playerx && y == playery)
|
||||
{
|
||||
printf("◎");
|
||||
continue;
|
||||
}
|
||||
if (fog[y][x])
|
||||
{
|
||||
printf("▓");
|
||||
continue;
|
||||
}
|
||||
if (!walk[y][x])
|
||||
{
|
||||
printf("▽");
|
||||
continue;
|
||||
}
|
||||
if (map[y][x] == path)
|
||||
{
|
||||
printf("□");
|
||||
continue;
|
||||
}
|
||||
if (map[y][x] == target)
|
||||
{
|
||||
printf("☆");
|
||||
continue;
|
||||
}
|
||||
if (isOutBounds(x, y))
|
||||
{
|
||||
printf("□");
|
||||
continue;
|
||||
}
|
||||
if (x == playerx && y == playery)
|
||||
{
|
||||
printf("◎");
|
||||
continue;
|
||||
}
|
||||
if (fog[y][x])
|
||||
{
|
||||
printf("▓");
|
||||
continue;
|
||||
}
|
||||
if (!walk[y][x])
|
||||
{
|
||||
printf("▽");
|
||||
continue;
|
||||
}
|
||||
if (map[y][x] == path)
|
||||
{
|
||||
printf("□");
|
||||
continue;
|
||||
}
|
||||
if (map[y][x] == target)
|
||||
{
|
||||
printf("☆");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("▓");
|
||||
continue;
|
||||
// 到此截断,后面为单字符地图时用
|
||||
printf("▓");
|
||||
continue;
|
||||
// 到此截断,后面为单字符地图时用
|
||||
|
||||
int d = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!isOutBounds(x + xx[i], y + yy[i]) && map[y + yy[i]][x + xx[i]] == wall)
|
||||
d |= 1 << i;
|
||||
// int d = 0;
|
||||
// for (int i = 0; i < 4; ++i)
|
||||
// {
|
||||
// if (!isOutBounds(x + xx[i], y + yy[i]) && map[y + yy[i]][x + xx[i]] == wall)
|
||||
// d |= 1 << i;
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
const int up = 1;
|
||||
const int down = 2;
|
||||
const int left = 4;
|
||||
const int right = 8;
|
||||
char ch = 0;
|
||||
switch (d)
|
||||
{
|
||||
case 0:
|
||||
ch = '&';
|
||||
break;
|
||||
//case up:
|
||||
//case down:
|
||||
case up | down:
|
||||
ch = '|';
|
||||
break;
|
||||
//case left:
|
||||
//case right:
|
||||
case left | right:
|
||||
ch = '-';
|
||||
break;
|
||||
default:
|
||||
ch = '+';
|
||||
}
|
||||
putchar(ch);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
//gotoxy(sWidth/2+1, sHeight/2+1);
|
||||
//putchar('A');
|
||||
}
|
||||
|
||||
/*
|
||||
// 手动延时函数
|
||||
void sleep(int n)
|
||||
{
|
||||
for (int i = 0; i < n*n*n*n; ++i);
|
||||
}
|
||||
*/
|
||||
|
||||
// 刷新地图
|
||||
void refresh()
|
||||
{
|
||||
gotoxy(1, 1);
|
||||
showMap();
|
||||
// const int up = 1;
|
||||
// const int down = 2;
|
||||
// const int left = 4;
|
||||
// const int right = 8;
|
||||
// char ch = 0;
|
||||
// switch (d)
|
||||
// {
|
||||
// case 0:
|
||||
// ch = '&';
|
||||
// break;
|
||||
// //case up:
|
||||
// //case down:
|
||||
// case up | down:
|
||||
// ch = '|';
|
||||
// break;
|
||||
// //case left:
|
||||
// //case right:
|
||||
// case left | right:
|
||||
// ch = '-';
|
||||
// break;
|
||||
// default:
|
||||
// ch = '+';
|
||||
// }
|
||||
// putchar(ch);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
//gotoxy(sWidth/2+1, sHeight/2+1);
|
||||
//putchar('A');
|
||||
}
|
||||
|
||||
// 生成地图算法,参数为起始点坐标
|
||||
void generate(int cx, int cy)
|
||||
{
|
||||
// 首先将地图全部设置为墙
|
||||
setAllWall();
|
||||
// 首先将地图全部设置为墙
|
||||
setAllWall();
|
||||
|
||||
// 填满迷雾,清空已经走过的路径
|
||||
for (int i = 0; i < width*height; ++i)
|
||||
*((bool*)fog + i) = *((bool*)walk + i) = true;
|
||||
// 填满迷雾,清空已经走过的路径
|
||||
for (int i = 0; i < width*height; ++i)
|
||||
*((bool*)fog + i) = *((bool*)walk + i) = true;
|
||||
|
||||
//设置玩家的坐标
|
||||
playerx = cx;
|
||||
playery = cy;
|
||||
//设置玩家的坐标
|
||||
playerx = cx;
|
||||
playery = cy;
|
||||
|
||||
// 从起点开始,将四周的墙壁添加到待凿列表中
|
||||
pushAroundWall(cx, cy);
|
||||
// 把这个点变成路
|
||||
map[cy][cx] = path;
|
||||
// 从起点开始,将四周的墙壁添加到待凿列表中
|
||||
pushAroundWall(cx, cy);
|
||||
// 把这个点变成路
|
||||
map[cy][cx] = path;
|
||||
|
||||
// 只要还有待凿的墙,就一直循环
|
||||
while (!walls.empty())
|
||||
{
|
||||
// 随机找个待凿的墙
|
||||
int index = rand() % walls.size();
|
||||
int wx = walls[index].first.first;
|
||||
int wy = walls[index].first.second;
|
||||
int d = walls[index].second;
|
||||
// 如果是墙,打穿,将下一个点四周的墙壁加入待凿列表
|
||||
if (map[wy + yy[d]][wx + xx[d]] == wall)
|
||||
{
|
||||
map[wy][wx] = path;
|
||||
map[wy + yy[d]][wx + xx[d]] = path;
|
||||
pushAroundWall(wx + xx[d], wy + yy[d]);
|
||||
//sleep(70);
|
||||
//refresh();
|
||||
}
|
||||
// 打穿后,将该墙移除待凿列表
|
||||
walls.erase(walls.begin() + index);
|
||||
}
|
||||
// 只要还有待凿的墙,就一直循环
|
||||
while (!walls.empty())
|
||||
{
|
||||
// 随机找个待凿的墙
|
||||
int index = rand() % walls.size();
|
||||
int wx = walls[index].first.first;
|
||||
int wy = walls[index].first.second;
|
||||
int d = walls[index].second;
|
||||
// 如果是墙,打穿,将下一个点四周的墙壁加入待凿列表
|
||||
if (map[wy + yy[d]][wx + xx[d]] == wall)
|
||||
{
|
||||
map[wy][wx] = path;
|
||||
map[wy + yy[d]][wx + xx[d]] = path;
|
||||
pushAroundWall(wx + xx[d], wy + yy[d]);
|
||||
}
|
||||
// 打穿后,将该墙移除待凿列表
|
||||
walls.erase(walls.begin() + index);
|
||||
}
|
||||
|
||||
map[height-2][width-2] = target;
|
||||
map[height-2][width-2] = target;
|
||||
|
||||
// 展开迷雾
|
||||
explore(playerx, playery);
|
||||
// 展开迷雾
|
||||
explore(playerx, playery);
|
||||
}
|
||||
|
||||
|
||||
// 玩家移动,参数是移动的方向
|
||||
void playerMove(int dir)
|
||||
bool playerMove(Dir dir)
|
||||
{
|
||||
if (0 > dir || dir >= 4)
|
||||
return;
|
||||
int tx = playerx + xx[dir];
|
||||
int ty = playery + yy[dir];
|
||||
if (isOutBounds(tx, ty))
|
||||
return;
|
||||
if (map[ty][tx] == wall)
|
||||
return;
|
||||
if (map[ty][tx] == target)
|
||||
{
|
||||
system("cls");
|
||||
cout << "游戏胜利!" << endl;
|
||||
system("pause");
|
||||
exit(0);
|
||||
}
|
||||
// 只有是路的时候才可以移动
|
||||
if (map[ty][tx] == path) {
|
||||
playerx = tx, playery = ty;
|
||||
walk[ty][tx] = false;
|
||||
}
|
||||
// 移动完后再次探索迷雾
|
||||
explore(playerx, playery);
|
||||
if (0 > dir || dir >= 4)
|
||||
return false;
|
||||
int tx = playerx + xx[dir];
|
||||
int ty = playery + yy[dir];
|
||||
if (isOutBounds(tx, ty))
|
||||
return false;
|
||||
if (map[ty][tx] == wall)
|
||||
return false;
|
||||
if (map[ty][tx] == target)
|
||||
{
|
||||
system("cls");
|
||||
cout << "游戏胜利!" << endl;
|
||||
system("pause");
|
||||
return true;
|
||||
}
|
||||
// 只有是路的时候才可以移动
|
||||
if (map[ty][tx] == path) {
|
||||
playerx = tx, playery = ty;
|
||||
walk[ty][tx] = false;
|
||||
}
|
||||
// 移动完后再次探索迷雾
|
||||
explore(playerx, playery);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 每一帧执行更新
|
||||
void updata()
|
||||
bool updata()
|
||||
{
|
||||
char ch = getch();
|
||||
switch (ch)
|
||||
{
|
||||
case 'w':
|
||||
playerMove(up);
|
||||
break;
|
||||
case 's':
|
||||
playerMove(down);
|
||||
break;
|
||||
case 'a':
|
||||
playerMove(2);
|
||||
break;
|
||||
case 'd':
|
||||
playerMove(3);
|
||||
break;
|
||||
}
|
||||
char ch = getch();
|
||||
bool win = false;
|
||||
switch (ch)
|
||||
{
|
||||
case 'w':
|
||||
win = playerMove(Dir::Up);
|
||||
break;
|
||||
case 's':
|
||||
win = playerMove(Dir::Down);
|
||||
break;
|
||||
case 'a':
|
||||
win = playerMove(Dir::Left);
|
||||
break;
|
||||
case 'd':
|
||||
win = playerMove(Dir::Right);
|
||||
break;
|
||||
case 'q':
|
||||
exit(0);
|
||||
break;
|
||||
case 'r':
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return !win;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 设置种子
|
||||
srand((unsigned int)time(0));
|
||||
do {
|
||||
// 生成地图
|
||||
generate(1, 1);
|
||||
// 设置种子
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
// 游戏循环
|
||||
while (1)
|
||||
{
|
||||
// 输出地图
|
||||
showMap();
|
||||
// 等待输入,更新
|
||||
updata();
|
||||
}
|
||||
printf("WSAD移动,Q退出,R重开");
|
||||
system("pause");
|
||||
|
||||
} while (getch() != 0);
|
||||
while (true) {
|
||||
// 生成地图
|
||||
generate(1, 1);
|
||||
|
||||
return 0;
|
||||
// 游戏循环
|
||||
do {
|
||||
// 输出地图
|
||||
showMap();
|
||||
} while (updata());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user