我全程使用TCHAR系列函数,亲测可以不改动代码兼容Unicode/ANSI开发环境,功能正常。大概有100行代码是来自网络的,我也做了改动,侵权请联系删除。本文作者szx0427,只发布于CSDN博客园

这个代码不能算是完美,还是会有轻微的闪屏现象,懒得再加双缓存了,大家可以自行修改。这里用的是SetConsoleCursorPosition函数和cls刷新屏幕。

好了,上代码!VS2015编译通过无警告。其他版本应该也没问题

  1. // C++ Maze main code
  2. // Copyright (c) 2020 szx0427
  3. #include <cstdio>
  4. #include <Windows.h>
  5. #include <conio.h>
  6. #include <tchar.h>
  7. #include <ctime>
  8. using namespace std;
  9. #ifdef _UNICODE
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #define CH_RECT L'■' // a rectangle (wall)
  13. #define CH_PLAYER L'○' // a circle (player)
  14. #define CH_SPACE L' ' // a space (route)
  15. #else
  16. #define CH_RECT '#'
  17. #define CH_PLAYER 'O'
  18. #define CH_SPACE ' '
  19. #endif // _UNICODE
  20. #define LENGTH (30 + 2 * 2)
  21. #define WALL 0
  22. #define ROUTE 1
  23. #define PLAYER 2
  24. static UINT g_Rank = 0;
  25. static SHORT g_lives = 3;
  26. static BOOL** g_maze = nullptr;
  27. void _Create(
  28. __in const int x,
  29. __in const int y );
  30. void _Print(void);
  31. int _CreateAndPrint(void);
  32. inline void _die(void)
  33. {
  34. --g_lives;
  35. for (int n = 1; n <= 2; n++) {
  36. _tsystem(_T("color fc"));
  37. Sleep(70);
  38. _tsystem(_T("color 07"));
  39. Sleep(70);
  40. }
  41. }
  42. int _tmain(void)
  43. {
  44. CONSOLE_CURSOR_INFO cci;
  45. GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
  46. cci.bVisible = false;
  47. SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
  48. #ifdef _UNICODE
  49. _setmode(_fileno(stdout), _O_U16TEXT);
  50. #endif // _UNICODE
  51. srand((UINT)time(NULL));
  52. int k;
  53. start:
  54. k = _CreateAndPrint();
  55. TCHAR ch;
  56. bool bExit = false;
  57. bool bWin = false;
  58. int x = 2, y = 1;
  59. while (!bExit && g_lives >= 0 && !bWin) {
  60. ch = _gettch();
  61. switch (ch) {
  62. case _T('R'):
  63. case _T('r'):
  64. _tsystem(_T("cls"));
  65. x = 2; y = 1;
  66. for (int l = 0; l < LENGTH; l++) {
  67. free(g_maze[l]);
  68. }
  69. free(g_maze);
  70. k = _CreateAndPrint();
  71. break;
  72. case VK_ESCAPE:
  73. bExit = true;
  74. break;
  75. case TCHAR(0xE0):
  76. switch (ch = _gettch()) {
  77. case TCHAR(72):
  78. if (g_maze[x - 1][y] != WALL) {
  79. g_maze[x][y] = ROUTE;
  80. --x;
  81. g_maze[x][y] = PLAYER;
  82. } else {
  83. _die();
  84. } break;
  85. case TCHAR(80):
  86. if (g_maze[x + 1][y] != WALL) {
  87. g_maze[x][y] = ROUTE;
  88. ++x;
  89. g_maze[x][y] = PLAYER;
  90. } else {
  91. _die();
  92. } break;
  93. case TCHAR(75):
  94. if (g_maze[x][y - 1] != WALL && !(x == 2 && y == 1)) {
  95. g_maze[x][y] = ROUTE;
  96. --y;
  97. g_maze[x][y] = PLAYER;
  98. } else {
  99. _die();
  100. } break;
  101. case TCHAR(77):
  102. if (g_maze[x][y + 1] != WALL) {
  103. g_maze[x][y] = ROUTE;
  104. ++y;
  105. g_maze[x][y] = PLAYER;
  106. } else {
  107. _die();
  108. } break;
  109. default: break;
  110. }
  111. if (x == k && y == LENGTH - 2) {
  112. bWin = true;
  113. }
  114. _Print();
  115. break;
  116. default: break;
  117. }
  118. }
  119. x = 2; y = 1;
  120. for (int l = 0; l < LENGTH; l++) {
  121. free(g_maze[l]);
  122. }
  123. free(g_maze);
  124. if (g_lives == -1) {
  125. _tsystem(_T("cls"));
  126. _putts(_T("你撞墙次数超过限制,本局游戏失败!"));
  127. _putts(_T("如果要再开局,请按下[R]键!否则,按下其他键以退出!"));
  128. ch = _gettch();
  129. if (ch == 'R' || ch == 'r') {
  130. goto start;
  131. }
  132. } else if (bWin) {
  133. _tsystem(_T("cls"));
  134. _putts(_T("恭喜,你赢了!是否要再来一局?"));
  135. _putts(_T("如果要再开局,请按下[R]键!否则,按下其他键以退出!"));
  136. ch = _gettch();
  137. if (ch == 'R' || ch == 'r') {
  138. goto start;
  139. }
  140. }
  141. return 0;
  142. }
  143. void _Create(const int x, const int y)
  144. {
  145. g_maze[x][y] = ROUTE;
  146. int dict[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
  147. int r, tmp;
  148. for (int i = 0; i < 4; i++) {
  149. r = rand() % 4;
  150. tmp = dict[0][0];
  151. dict[0][0] = dict[r][0];
  152. dict[r][0] = tmp;
  153. tmp = dict[0][1];
  154. dict[0][1] = dict[r][1];
  155. dict[r][1] = tmp;
  156. }
  157. int dx, dy, range, count;
  158. for (int j = 0; j < 4; j++) {
  159. dx = x;
  160. dy = y;
  161. range = 1 + (g_Rank == 0 ? 0 : rand() % g_Rank);
  162. while (range > 0) {
  163. dx += dict[j][0];
  164. dy += dict[j][1];
  165. if (g_maze[dx][dy] == ROUTE) {
  166. break;
  167. }
  168. count = 0;
  169. for (int k = dx - 1; k < dx + 2; k++) {
  170. for (int l = dy - 1; l < dy + 2; l++) {
  171. if (abs(k - dx) + abs(l - dy) == 1 && g_maze[k][l] == ROUTE) {
  172. count++;
  173. }
  174. }
  175. }
  176. if (count > 1) {
  177. break;
  178. }
  179. --range;
  180. g_maze[dx][dy] = ROUTE;
  181. }
  182. if (range <= 0) {
  183. _Create(dx, dy);
  184. }
  185. }
  186. }
  187. int _CreateAndPrint(void)
  188. {
  189. _tprintf(_T("正在分配内存..."));
  190. g_maze = (int**)malloc(LENGTH * sizeof(int*));
  191. for (int i = 0; i < LENGTH; i++) {
  192. g_maze[i] = (int*)calloc(LENGTH, sizeof(int));
  193. }
  194. _tprintf(_T("完成!\n"));
  195. _tprintf(_T("正在加载迷宫..."));
  196. g_lives = 3;
  197. for (int j = 0; j < LENGTH; j++) {
  198. g_maze[j][0] = ROUTE;
  199. g_maze[0][j] = ROUTE;
  200. g_maze[j][LENGTH - 1] = ROUTE;
  201. g_maze[LENGTH - 1][j] = ROUTE;
  202. }
  203. _Create(2, 2);
  204. g_maze[2][1] = PLAYER;
  205. int k;
  206. for (k = LENGTH - 3; k >= 0; k--) {
  207. if (g_maze[k][LENGTH - 3] == ROUTE) {
  208. g_maze[k][LENGTH - 2] = ROUTE;
  209. break;
  210. }
  211. }
  212. _tprintf(_T("完成!\n"));
  213. _Print();
  214. return k;
  215. }
  216. void _Print(void)
  217. {
  218. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { 0, 0 });
  219. for (int x = 0; x < LENGTH; x++) {
  220. for (int y = 0; y < LENGTH; y++) {
  221. switch (g_maze[x][y]) {
  222. case ROUTE:
  223. _puttch(CH_SPACE); break;
  224. case WALL:
  225. _puttch(CH_RECT); break;
  226. case PLAYER:
  227. _puttch(CH_PLAYER); break;
  228. default: break;
  229. }
  230. }
  231. _tprintf(_T("\n"));
  232. }
  233. _putts(_T("上下左右方向键用来移动,按Esc可退出,按R重新开局。"));
  234. _tprintf(_T("剩余可撞墙次数:%d"), g_lives);
  235. }

这是C++风格的代码。因为用到了内联函数等C++特性,可能不能直接兼容C语言环境,但是稍作改动即可完美兼容。(ps:至少大家不用为字符集设置发愁了 XD)

效果:

其中LENGTH宏规定了边长。这里是30。



想改边长,直接更改那个30就可以了。

其中全局变量g_Rank规定了难度,数值越小难度越大,最小值为0。

也是一样,改难度直接改这个就OK。


有什么问题和建议,欢迎大家指正!!!!

[开源]C++实现控制台随机迷宫的更多相关文章

  1. 利用纯JS和HTML Canvas生成随机迷宫过程中产生的有趣的事情

    上效果图: #先看生成随机迷宫的代码吧↓ <html> <head> <title>生成随机迷宫v1.0</title> </head> & ...

  2. 斯坦福开源无Bug的随机计算图Certigrad

    斯坦福开源无Bug的随机计算图Certigrad https://news.cnblogs.com/n/573690/ ttps://github.com/dselsam/certigrad

  3. 随机Prim法创建随机迷宫(C#实现)

    因为这两天想参加一个比赛,所以就在上网找素材,刚好看到了迷宫生成,就决定拿这个开刀了. 参考的原文地址为(来源页面) 源地址中是使用AS实现的,没学过AS,所以直接不会运行,于是就自己根据原文的概念进 ...

  4. C++随机迷宫生成[转载]

    原文:http://tieba.baidu.com/p/2596809144 #include<iostream.h> #include"time.h" #includ ...

  5. Unity_Dungeonize 随机生成迷宫

    本文对随机生成迷宫的实现思路进行记录,其作用在于为游戏过程提供随机性以及节省开发周期,下面是Dungeonize的结构 随机迷宫的生成主要包括几个阶段 1.生成房间体结构,为墙体,自定义房间,自定义物 ...

  6. AI-随机迷宫&迷宫求解

    本文记录了,人工智能中简单的搜索策略中的路径搜索策略中的A*算法,来实现迷宫寻路的问题.(这只是一次本人的课外作业) 完整的程序源码已经发送到我的Git.这里只记录了我的思路和感想以及收获. 产生随机 ...

  7. 小项目特供 简易迷宫(基于Java)

    明天返校,于是昨天和今天简单熟系了一下JAVA的GUI,做了一个简易的迷宫小游戏(暂时没有时间实现随机迷宫及多关卡,仅供学习) 源码及运行文件(提供JRE8):链接:简易迷宫 密码:hy8v

  8. Linux下随机生成密码的命令总结

    有时候经常为如何设置一个安全.符合密码复杂度的密码而绞尽脑汁,说实话,这实在是一个体力活而且浪费时间,更重要的是设置密码的时候经常纠结.终于有一天实在忍不住了,于是学习.整理了一下如何使用Linux下 ...

  9. 企业安全建设之搭建开源SIEM平台

    https://www.freebuf.com/special/127172.html https://www.freebuf.com/special/127264.html https://www. ...

随机推荐

  1. nohup启动 jar 不输出日志

    简单暴力:nohup java -jar xxx.jar >/dev/null 2>&1 &

  2. centos 关闭SELINUX并重启系统

    关闭SELINUX [root@bogon ~]# vim /etc/sysconfig/selinux  ... SELINUX=disabled ... 执行过程: 重启系统 [root@bogo ...

  3. [网络编程]mqtt概念&数据包

    目录 前言 1. MQTT 简介 2. MQTT 通信模型 2.1 MQTT 协议 2.2 MQTT 协议中的订阅&主题&会话 2.3 MQTT 协议中的方法 3. MQTT 协议数据 ...

  4. rabbitmq概念简介

    AMQP协议 AMQP: Advanced Message Queue,高级队列协议. 特征: 这是一个在进程间传递异步消息的网络协议,因此数据的发送方.接收方以及容器(MQ)都可以在不同的设备上. ...

  5. 资源:zookeeper下载地址

    提供zookeeper下载地址:https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/

  6. mysql 深度解析auto-increment自增列"Duliplicate key"问题

    转载自:https://cloud.tencent.com/developer/article/1367681 问题描述 近期,线上有个重要Mysql客户的表在从5.6升级到5.7后master上插入 ...

  7. python之学生信息管理系统

    1 #!usr/bin/python 2 #encoding=utf-8 3 4 #1. 打印学生管理系统界面 5 def printStd(): 6 print ("*"*50) ...

  8. 网站图片无缝兼容 WebP/AVIF

    前言 WebP 格式发布已有十余年,但不少站点至今仍未使用,只为兼顾极少数低版本浏览器.至于去年发布的 AVIF 格式,使用的站点就更少了. 然而图片往往是流量大户,与其费尽心机优化脚本体积,可能还不 ...

  9. python使用笔记17--异常处理

    什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错误. 当Pyth ...

  10. 2018年成为Web开发者的路线图

    本文通过一组大图展示了Web开发技能图谱,给出了作为Web 开发者可以采取的路径,以及总结了想要成为Web工程师的朋友们.希望和大家一起交流分享 介绍 Web 开发的角色一般说来,包括前端.后端和de ...