加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
code.cpp 6.12 KB
一键复制 编辑 原始数据 按行查看 历史
jie65535 提交于 2018-09-24 13:12 . 提交源码
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <utility>
#include <conio.h>
#include <windows.h>
using namespace std;
// 显示区域的大小
const size_t sWidth = 30, sHeight = 24;
// 迷宫的实际大小(必须是奇数!)
const size_t width = 9, height = 9;
const char wall = 1;
const char path = 0;
const char target = 2;
// 地图
char map[height][width];
bool fog[height][width];
bool walk[height][width];
// 带凿墙列表
vector<pair<pair<int, int>, int> > walls;
/*
随机prim算法的核心是:
1、让迷宫全是墙
2、选一个格作为迷宫的通路,然后把它的邻墙放入列表
3、当列表里还有墙时
——1、从列表里随机选一个墙,如果它对面的格子不是迷宫的通路
————1、把墙打通,让对面的格子成为迷宫的通路
————2、把那个格子的邻墙加入列表
——2、如果对面的格子已经是通路了,那就从列表里移除这面墙
*/
const int up = 0;
const int down = 1;
const int left = 2;
const int right = 3;
// 四周一步
int xx[] = { 0, 0, -1, 1 };
int yy[] = { -1, 1, 0, 0 };
// 四周两步
int x2[] = { 0, 0, -2, 2 };
int y2[] = { -2, 2, 0, 0 };
// 玩家坐标
int playerx;
int playery;
int SPX;
int SPY;
const int margin = 3;
// 移动光标到xy位置
void gotoxy(int x, int y)
{
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;
}
// 是否越界
bool isOutBounds(int x, int y)
{
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;
}
}
}
// 将坐标处的墙添加到待通墙中
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 ));
}
}
// 展示地图
void showMap()
{
int dx = sWidth / 2 - playerx;
int dy = sHeight / 2 - playery;
// 移动光标到最开始的位置
gotoxy(1, 1);
// 遍历整个地图
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] = { "□", "▓", "▽", "☆", "◎" };
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;
// 到此截断,后面为单字符地图时用
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();
}
// 生成地图算法,参数为起始点坐标
void generate(int cx, int cy)
{
// 首先将地图全部设置为墙
setAllWall();
// 填满迷雾,清空已经走过的路径
for (int i = 0; i < width*height; ++i)
*((bool*)fog + i) = *((bool*)walk + i) = true;
//设置玩家的坐标
playerx = cx;
playery = cy;
// 从起点开始,将四周的墙壁添加到待凿列表中
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);
}
map[height-2][width-2] = target;
// 展开迷雾
explore(playerx, playery);
}
// 玩家移动,参数是移动的方向
void playerMove(int 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);
}
// 每一帧执行更新
void 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;
}
}
int main()
{
// 设置种子
srand((unsigned int)time(0));
do {
// 生成地图
generate(1, 1);
// 游戏循环
while (1)
{
// 输出地图
showMap();
// 等待输入,更新
updata();
}
} while (getch() != 0);
return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化