diff --git a/a.exe b/a.exe new file mode 100644 index 0000000..4dfb839 Binary files /dev/null and b/a.exe differ diff --git a/code.cpp b/code.cpp new file mode 100644 index 0000000..9e2584f --- /dev/null +++ b/code.cpp @@ -0,0 +1,343 @@ +#include +#include +#include +#include +#include +#include +#include + +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, 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, int>(pair( 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; +} \ No newline at end of file