找回密码
 立即注册!
搜索
查看: 1145|回复: 0

扫雷圣诞节特别版

[复制链接]

11

主题

57

回帖

585

积分

清正廉明~版主

风纪委员

积分
585

最佳新人活跃会员

发表于 2020-7-18 11:07:14 | 显示全部楼层 |阅读模式 IP:浙江嘉兴
  1. #include<stdio.h>
  2. #include<windows.h>
  3. #include<stdlib.h>
  4. #include<time.h>
  5. #include<conio.h>
  6. #include<queue>
  7. #include<ctype.h>
  8. #define A 17 //地图的高
  9. #define B 17 //地图的宽
  10. #define C 30 //雷的总数
  11. using namespace std;

  12. //全局变量
  13. DWORD a,b;
  14. char map[A][B],news,spare;
  15. int BoomTotalNum,floatx,floaty,flag[A][B],flagnum,mode,slect[A][B],game;

  16. //颜色属性
  17. const WORD FORE_BLUE = FOREGROUND_BLUE; //蓝色文本属性
  18. const WORD FORE_GREEN = FOREGROUND_GREEN; //绿色文本属性
  19. const WORD FORE_RED = FOREGROUND_RED; //红色文本属性

  20. //开垦地图结构体
  21. struct node {
  22. int x;
  23. int y;
  24. };
  25. queue <node> dui;

  26. //打印位置
  27. void position(int x,int y) {
  28. COORD pos={x,y};
  29. HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);
  30. SetConsoleCursorPosition(Out,pos);
  31. }

  32. //隐藏光标
  33. void Hide() {
  34. HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
  35. CONSOLE_CURSOR_INFO CursorInfo;
  36. GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
  37. CursorInfo.bVisible = false; //隐藏控制台光标
  38. SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
  39. }

  40. //初始化
  41. void Beginning() {
  42. while(!dui.empty()) {
  43. dui.pop();
  44. }
  45. game=1;
  46. //BoomTotalNum=C;
  47. floatx=A/2;
  48. floaty=B/2;
  49. flagnum=0;
  50. BoomTotalNum=C;
  51. mode=0;
  52. HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
  53. CONSOLE_SCREEN_BUFFER_INFO csbi;      //定义窗口缓冲区信息结构体
  54. GetConsoleScreenBufferInfo(handle_out, &csbi);   //获得窗口缓冲区信息
  55. int x,y;
  56. srand((unsigned)time(0));
  57. for(int i=0;i<A;i++) for(int j=0;j<B;j++) {
  58. map[i][j]=' ';
  59. flag[i][j]=0;
  60. slect[i][j]=0;
  61. }
  62. while(BoomTotalNum) {
  63. x=rand()%A;
  64. y=rand()%B;
  65. if(map[x][y]==' ') {
  66. map[x][y]='@';
  67. BoomTotalNum--;
  68. }
  69. }
  70. SetConsoleTextAttribute(handle_out, FORE_GREEN);
  71. for(int i=0;i<A;i++) {
  72. for(int j=0;j<B;j++) printf("█");
  73. printf("\n");
  74. }
  75. position(floaty*2,floatx);
  76. SetConsoleTextAttribute(handle_out, FORE_RED);
  77. printf(""); //光标位置
  78. position(44,9);
  79. printf("扫雷模式");
  80. position(44,5);
  81. printf("剩余雷数:%d ",C-flagnum);
  82. SetConsoleTextAttribute(handle_out, FORE_GREEN);
  83. position(5,22);
  84. printf("按“空格”切换模式");
  85. position(5,23);
  86. printf("按“Enter”确认");
  87. position(5,24);
  88. printf("按“方向键”选择方块");

  89. }

  90. //打印地图的一块儿
  91. void Lump(int xx,int yy) {
  92. switch(map[xx][yy]) {
  93. case '1' : printf("①");break; //周围雷的数量(下同)
  94. case '2' : printf("②");break;
  95. case '3' : printf("③");break;
  96. case '4' : printf("④");break;
  97. case '5' : printf("⑤");break;
  98. case '6' : printf("⑥");break;
  99. case '7' : printf("⑦");break;
  100. case '8' : printf("⑧");break;
  101. case ' ' :
  102. if(xx==floatx&&yy==floaty) {
  103. if(flag[xx][yy]==0) {
  104.   if(mode%2==0) printf("");
  105.   else printf("");
  106. }
  107. else printf("");
  108. }
  109. else {
  110. if(flag[xx][yy]==0) printf("█");
  111. else printf("");
  112. }
  113. break;
  114. case '@' :
  115. if(xx==floatx&&yy==floaty) {
  116. if(flag[xx][yy]==0) {
  117.   if(mode%2==0) printf("");
  118.   else printf("");
  119. }
  120. else printf("");
  121. }
  122. else {
  123. if(flag[xx][yy]==0) printf("█");
  124. else printf("");
  125. }
  126. break;
  127. case 'x' : if(floatx==xx&&floaty==yy) printf(""); else printf(" ");break; //已经挖开的空白
  128. }
  129. }

  130. //移动光标
  131. void Move() {
  132. HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
  133. CONSOLE_SCREEN_BUFFER_INFO csbi;      //定义窗口缓冲区信息结构体
  134. GetConsoleScreenBufferInfo(handle_out, &csbi);   //获得窗口缓冲区信息
  135. int xxx,yyy;
  136. xxx=floatx;
  137. yyy=floaty;
  138. switch(news) {
  139. case 72 : floatx--;break; //上
  140. case 80 : floatx++;break; //下
  141. case 75 : floaty--;break; //左
  142. case 77 : floaty++;break; //右
  143. }
  144. if(floatx==-1) floatx=A-1; floatx%=A; //两端穿模处理
  145. if(floaty==-1) floaty=B-1; floaty%=B;

  146. position(yyy*2,xxx);
  147. SetConsoleTextAttribute(handle_out, FORE_GREEN);
  148. Lump(xxx,yyy); //删除原位置

  149. if(map[floatx][floaty]=='x') {
  150. position(floaty*2,floatx);
  151. printf(" ");
  152. }

  153. position(floaty*2,floatx);
  154. SetConsoleTextAttribute(handle_out, FORE_BLUE);
  155. Lump(floatx,floaty); //更新新位置
  156. }

  157. //插旗和排雷模式切换
  158. void Mode() {
  159. HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
  160. CONSOLE_SCREEN_BUFFER_INFO csbi;      //定义窗口缓冲区信息结构体
  161. GetConsoleScreenBufferInfo(handle_out, &csbi);   //获得窗口缓冲区信息
  162. mode++;
  163. SetConsoleTextAttribute(handle_out, FORE_BLUE);
  164. position(floaty*2,floatx);
  165. if(mode%2==0) printf("");
  166. else printf("");

  167. position(44,9);
  168. if(mode%2==0) {
  169. SetConsoleTextAttribute(handle_out, FORE_BLUE);
  170. printf("扫雷模式");
  171. }
  172. else {
  173. SetConsoleTextAttribute(handle_out, FORE_RED);
  174. printf("插旗模式");
  175. }
  176. }

  177. //该点周围地雷数
  178. int Boomnum(int xx,int yy) {
  179. int num=0;
  180. if((xx-1>=0)&&(yy-1>=0)&&(map[xx-1][yy-1]=='@')) num++;
  181. if((xx-1>=0)&&(yy+0>=0)&&(map[xx-1][yy]=='@')) num++;
  182. if((xx-1>=0)&&(yy+1<B) &&(map[xx-1][yy+1]=='@')) num++;
  183. if((xx+0>=0)&&(yy-1>=0)&&(map[xx][yy-1]=='@')) num++;
  184. if((xx+0>=0)&&(yy+1<B) &&(map[xx][yy+1]=='@')) num++;
  185. if((xx+1<A)&&(yy-1>=0) &&(map[xx+1][yy-1]=='@')) num++;
  186. if((xx+1<A)&&(yy+0>=0) &&(map[xx+1][yy]=='@')) num++;
  187. if((xx+1<A)&&(yy+1<B) &&(map[xx+1][yy+1]=='@')) num++;
  188. return num;
  189. }

  190. //更新地图
  191. void Open() {
  192. node c;
  193. node d;
  194. while(!dui.empty()) {
  195. dui.pop();
  196. }
  197. c.x=floatx;
  198. c.y=floaty;
  199. dui.push(c);
  200. slect[c.x][c.y]=1;
  201. while(!dui.empty()) {
  202. c=dui.front();
  203. dui.pop();
  204. if(Boomnum(c.x,c.y)!=0) {
  205. map[c.x][c.y]=(Boomnum(c.x,c.y)+48);
  206. continue;
  207. }
  208. else {
  209. map[c.x][c.y]='x';                                                                                                         
  210. if((c.x-1>=0)&&(c.y-1>=0)&&(map[c.x-1][c.y-1]==' ')&&(slect[c.x-1][c.y-1]==0)) {
  211. d.x=c.x-1;
  212. d.y=c.y-1;
  213. dui.push(d);
  214. slect[d.x][d.y]=1;
  215. }
  216. if((c.x-1>=0)&&(c.y-0>=0)&&(map[c.x-1][c.y]==' ')&&(slect[c.x-1][c.y]==0)) {
  217. d.x=c.x-1;
  218. d.y=c.y-0;
  219. dui.push(d);
  220. slect[d.x][d.y]=1;
  221. }
  222. if((c.x-1>=0)&&(c.y+1<B)&&(map[c.x-1][c.y+1]==' ')&&(slect[c.x-1][c.y+1]==0)) {
  223. d.x=c.x-1;
  224. d.y=c.y+1;
  225. dui.push(d);
  226. slect[d.x][d.y]=1;
  227. }
  228. if((c.x-0>=0)&&(c.y-1>=0)&&(map[c.x][c.y-1]==' ')&&(slect[c.x][c.y-1]==0)) {
  229. d.x=c.x-0;
  230. d.y=c.y-1;
  231. dui.push(d);
  232. slect[d.x][d.y]=1;
  233. }
  234. if((c.x-0>=0)&&(c.y+1<B)&&(map[c.x][c.y+1]==' ')&&(slect[c.x][c.y+1]==0)) {
  235. d.x=c.x-0;
  236. d.y=c.y+1;
  237. dui.push(d);
  238. slect[d.x][d.y]=1;
  239. }
  240. if((c.x+1<A)&&(c.y-1>=0)&&(map[c.x+1][c.y-1]==' ')&&(slect[c.x+1][c.y-1]==0)) {
  241. d.x=c.x+1;
  242. d.y=c.y-1;
  243. dui.push(d);
  244. slect[d.x][d.y]=1;
  245. }
  246. if((c.x+1<A)&&(c.y-0>=0)&&(map[c.x+1][c.y]==' ')&&(slect[c.x+1][c.y]==0)) {
  247. d.x=c.x+1;
  248. d.y=c.y-0;
  249. dui.push(d);
  250. slect[d.x][d.y]=1;
  251. }
  252. if((c.x+1<A)&&(c.y+1<B)&&(map[c.x+1][c.y+1]==' ')&&(slect[c.x+1][c.y+1]==0)) {
  253. d.x=c.x+1;
  254. d.y=c.y+1;
  255. dui.push(d);
  256. slect[d.x][d.y]=1;
  257. }
  258. }
  259. }
  260. }

  261. int main() {
  262. freopen("排名.txt","r",stdin);
  263. Relife: //重玩处
  264. HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
  265. CONSOLE_SCREEN_BUFFER_INFO csbi;      //定义窗口缓冲区信息结构体
  266. GetConsoleScreenBufferInfo(handle_out, &csbi);   //获得窗口缓冲区信息

  267. Hide();
  268. Beginning();
  269. a=GetTickCount();
  270. while(1) {
  271. if(kbhit()!=0) {
  272. spare=getch();


  273. if((spare!=(-32))&&(spare!=13)&&(spare!=' ')) continue;


  274. if(spare==13) {;

  275. if(mode%2==0) {
  276.   if(map[floatx][floaty]=='@'&&flag[floatx][floaty]==0) {
  277.   break;
  278.   game=0;
  279.   }
  280.   
  281.   if(flag[floatx][floaty]==1) continue;
  282.   Open();
  283.   position(0,0);
  284.   SetConsoleTextAttribute(handle_out, FORE_GREEN);
  285.   for(int i=0;i<A;i++) {
  286.   for(int j=0;j<B;j++) Lump(i,j);
  287.   printf("\n");
  288.   }
  289.   position(floaty*2,floatx);
  290.   SetConsoleTextAttribute(handle_out, FORE_BLUE);
  291.   Lump(floatx,floaty);
  292. }


  293. else {
  294.   
  295.   
  296.   if(map[floatx][floaty]=='x'||(map[floatx][floaty]>'0'&&map[floatx][floaty]<'9'))
  297.   continue;
  298.   
  299.   
  300.   if(flag[floatx][floaty]==0) {
  301.   flagnum++;
  302.   flag[floatx][floaty]=1;
  303.   position(floaty*2,floatx);
  304.   SetConsoleTextAttribute(handle_out, FORE_BLUE);
  305.   Lump(floatx,floaty);
  306.   }
  307.   
  308.   
  309.   else {
  310.   flagnum--;
  311.   flag[floatx][floaty]=0;
  312.   position(floaty*2,floatx);
  313.   SetConsoleTextAttribute(handle_out, FORE_BLUE);
  314.   Lump(floatx,floaty);
  315.   }
  316. }
  317. }


  318. if(spare==' ') Mode();

  319. //按方向键
  320. if(spare==-32) {
  321. news=getch();
  322. Move();
  323. }
  324. for(int i=0;i<A;i++) for(int j=0;j<B;j++) if(map[i][j]=='x'||(map[i][j]>'0'&&map[i][j]<'9')) game++;
  325. if(game==A*B-C+1) break;
  326. else game=1;
  327. SetConsoleTextAttribute(handle_out, FORE_RED);
  328. position(44,5);
  329. printf("剩余雷数:%d ",C-flagnum);
  330. }
  331. else Sleep(10);
  332. b=GetTickCount();
  333. SetConsoleTextAttribute(handle_out, FORE_RED);
  334. position(44,7);
  335. printf("用时:");
  336. if((b-a)/60000<10) printf("0");
  337. printf("%d:",(b-a)/60000);
  338. if(((b-a)/1000)%60<10) printf("0");
  339. printf("%d:",((b-a)/1000)%60);
  340. if(((b-a)/10)%100<10) printf("0");
  341. printf("%d",((b-a)/10)%100);
  342. }
  343. SetConsoleTextAttribute(handle_out, FORE_RED);
  344. position(5,5);
  345. if(game==1) printf("游戏结束!");
  346. else printf("恭喜通关!");
  347. position(5,8);
  348. printf("任意键重玩");
  349. scanf("%c%c",&spare,&spare);
  350. system("cls");
  351. position(0,0);
  352. goto Relife;
  353. }
复制代码



本帖被以下淘专辑推荐:


tel:181 5707 6602
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册!

本版积分规则

QQ|手机版|小黑屋|网站地图|动象论坛

GMT+8, 2023-10-3 21:15 , Processed in 0.112090 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.5 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表