当前位置:   article > 正文

C语言_c语言黑白棋

c语言黑白棋

                                          黑白棋 C语言

                  5天实训,弄出来一个黑白棋,bug超多,但还是挺有成就感


  1. #include<iostream>
  2. #include<iomanip>
  3. #include<fstream>
  4. #include<string>
  5. #include<cstdio>
  6. #include<cstring>
  7. #include<cstdlib>
  8. #include<ctime>
  9. #include<queue>
  10. #include<conio.h>
  11. #include<windows.h>
  12. //#include <graphics.h>
  13. using namespace std;
  14. HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE),hin=GetStdHandle(STD_INPUT_HANDLE);//句柄
  15. INPUT_RECORD mouseRec;//控制台输入信息
  16. DWORD res;
  17. int qipan[8][8],tishi[8][8],huiqiqipan[8][8];
  18. int heiqi,baiqi,xxx,yyy;
  19. /*清屏函数*/
  20. inline void clear_screen()
  21. {
  22. COORD home= {0,0};
  23. DWORD dummy;
  24. CONSOLE_SCREEN_BUFFER_INFO csbi;
  25. GetConsoleScreenBufferInfo(hout,&csbi);
  26. FillConsoleOutputCharacter(hout,' ',csbi.dwSize.X*csbi.dwSize.Y,home,&dummy);
  27. SetConsoleCursorPosition(hout,home);
  28. }
  29. /*隐藏光标*/
  30. inline void hide()
  31. {
  32. CONSOLE_CURSOR_INFO cursor_info= {1,0};
  33. SetConsoleCursorInfo(hout, &cursor_info);
  34. }
  35. inline COORD get_mouse()//鼠标位置
  36. {
  37. while(1)
  38. {
  39. COORD pos;
  40. ReadConsoleInput(hin,&mouseRec,1,&res);
  41. if (mouseRec.EventType==MOUSE_EVENT)
  42. {
  43. if (mouseRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)
  44. {
  45. pos=mouseRec.Event.MouseEvent.dwMousePosition;
  46. return pos;
  47. }
  48. }
  49. }
  50. }
  51. void jiluqipan() //记录棋盘的上一步
  52. {
  53. int i,j;
  54. for(i=0; i<8; i++)
  55. {
  56. for(j=0; j<8; j++)
  57. {
  58. huiqiqipan[i][j]=qipan[i][j];
  59. }
  60. }
  61. }
  62. void huiqi() //悔棋函数
  63. {
  64. int i,j;
  65. for(i=0; i<8; i++)
  66. {
  67. for(j=0; j<8; j++)
  68. {
  69. qipan[i][j]=huiqiqipan[i][j];
  70. }
  71. }
  72. }
  73. int tongji(int qipan[][8],int player)//统计棋子的个数
  74. {
  75. int i,j;
  76. int hei=0,bai=0;
  77. for(i=0; i<8; i++)
  78. {
  79. for(j=0; j<8; j++)
  80. {
  81. if(qipan[i][j]==1)
  82. {
  83. hei++;
  84. }
  85. if(qipan[i][j]==-1)
  86. {
  87. bai++;
  88. }
  89. }
  90. }
  91. heiqi=hei;
  92. baiqi=bai;
  93. if(player==1)
  94. {
  95. return heiqi;
  96. }
  97. else
  98. {
  99. return baiqi;
  100. }
  101. }
  102. int zhuanhuax(int x)
  103. {
  104. if(x>1 && x<5)
  105. {
  106. return 0;
  107. }
  108. if(x>5 && x<9)
  109. {
  110. return 1;
  111. }
  112. if(x>9 && x<13)
  113. {
  114. return 2;
  115. }
  116. if(x>13 && x<17)
  117. {
  118. return 3;
  119. }
  120. if(x>17 && x<21)
  121. {
  122. return 4;
  123. }
  124. if(x>21 && x<25)
  125. {
  126. return 5;
  127. }
  128. if(x>25 && x<29)
  129. {
  130. return 6;
  131. }
  132. if(x>29 && x<33)
  133. {
  134. return 7;
  135. }
  136. }
  137. int zhuanhuay(int x)
  138. {
  139. if(x>=1 && x<3)
  140. {
  141. return 0;
  142. }
  143. if(x>=3 && x<5)
  144. {
  145. return 1;
  146. }
  147. if(x>=5 && x<7)
  148. {
  149. return 2;
  150. }
  151. if(x>=7 && x<9)
  152. {
  153. return 3;
  154. }
  155. if(x>=9 && x<11)
  156. {
  157. return 4;
  158. }
  159. if(x>=11 && x<13)
  160. {
  161. return 5;
  162. }
  163. if(x>=13 && x<15)
  164. {
  165. return 6;
  166. }
  167. if(x>=15 && x<17)
  168. {
  169. return 7;
  170. }
  171. }
  172. void chushihua() //棋盘初始化
  173. {
  174. memset(qipan,0,sizeof(qipan));//0代表此位置没有棋子
  175. qipan[3][3]=qipan[4][4]=-1;//2代表此位置是白色棋子
  176. qipan[3][4]=qipan[4][3]=1;//1代表此位置是黑色棋子
  177. heiqi=baiqi=2;
  178. }
  179. int zhujiemian() //进入游戏的主界面
  180. {
  181. hide();
  182. printf("\n\n\n\n\n\n 黑 ");
  183. Sleep(1000);
  184. printf("白 ");
  185. Sleep(1000);
  186. printf("棋");
  187. Sleep(1000);
  188. printf("\n\n\n __ky\n");
  189. Sleep(1200);
  190. clear_screen();
  191. //initgraph(600,500);
  192. //loadimage(NULL,"主界面1.jpg");
  193. printf("\n\n\n 黑 白 棋\n\n");
  194. printf("\n\n\n 人机对战\n");
  195. printf("\n 人人对战\n");
  196. COORD pos;
  197. pos=get_mouse();
  198. if(pos.X>=31 && pos.X<=37 && pos.Y==8)
  199. {
  200. return 1; //人机对战
  201. }
  202. else if(pos.X>=31 && pos.X<=38 && pos.Y==10)
  203. {
  204. //人人对战
  205. return 2;
  206. }
  207. }
  208. void jiemian() //棋盘函数显示棋盘
  209. {
  210. int i,j;
  211. printf(" 1 2 3 4 5 6 7 8 \n");
  212. printf(" ┏━┳━┳━┳━┳━┳━┳━┳━┓\n");
  213. for(i=0; i<7; i++)
  214. {
  215. printf("%d┃",i+1);
  216. for(j=0; j<8; j++)
  217. {
  218. if(tishi[i][j]==1)
  219. {
  220. printf("╳┃"); //1 提示可以
  221. }
  222. else if(qipan[i][j]==0)
  223. {
  224. printf(" ┃"); //0是没有棋子
  225. }
  226. if(qipan[i][j]==-1)
  227. {
  228. printf("●┃"); //1 黑 (人)
  229. }
  230. if(qipan[i][j]==1)
  231. {
  232. printf("○┃"); //-1 白 ()
  233. }
  234. }
  235. if(i==5)
  236. printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫ 黑 : %d\n",heiqi);
  237. else if(i==6)
  238. printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫ 白 : %d\n",baiqi);
  239. else
  240. printf("\n ┣━╋━╋━╋━╋━╋━╋━╋━┫\n");
  241. }
  242. printf("8┃");
  243. for(j=0; j<8; j++)
  244. {
  245. if(tishi[7][j]==1)
  246. {
  247. printf("╳┃");
  248. }
  249. else if(qipan[7][j]==0)
  250. {
  251. printf(" ┃");
  252. }
  253. if(qipan[7][j]==-1)
  254. {
  255. printf("●┃");
  256. }
  257. if(qipan[7][j]==1)
  258. {
  259. printf("○┃");
  260. }
  261. }
  262. printf("\n ┗━┻━┻━┻━┻━┻━┻━┻━┛\n");
  263. printf(" 黑 ○ 白 ● 可下 ╳\n");
  264. }
  265. int tishiqipan(int qipan[][8],int tishi[][8],int player)
  266. {
  267. int rowdelta, coldelta, row, col, x, y = 0;//row行col列
  268. int iStep = 0;
  269. int opponent = (player == 1) ? -1 : 1; //对方棋子
  270. //printf("\n%d\n",opponent);
  271. int myplayer = -1 * opponent; //我方棋子
  272. //将tishi数组全部清0
  273. for (row = 0; row < 8; row++)
  274. {
  275. for (col = 0; col < 8; col++)
  276. {
  277. tishi[row][col] = 0;
  278. }
  279. }
  280. //循环判断棋盘中哪些单元格可以下子
  281. for (row = 0; row < 8; row++)
  282. {
  283. for (col = 0; col < 8; col++)
  284. {
  285. //若棋盘上对应位置不为空(表示已经有子)
  286. if (qipan[row][col] != 0)
  287. {
  288. continue;//继续处理下一个单元格
  289. }
  290. //循环检查上下行
  291. for (rowdelta = -1; rowdelta <= 1; rowdelta++)
  292. {
  293. //循环检查左右列
  294. for (coldelta = -1; coldelta <= 1; coldelta++)
  295. {
  296. //检查若坐标超过棋盘 或为当前单元格
  297. if (row + rowdelta < 0 || row + rowdelta >= 8
  298. || col + coldelta < 0 || col + coldelta >= 8
  299. || (rowdelta == 0 && coldelta == 0))
  300. {
  301. continue; //继续循环
  302. }
  303. //若(row,col)四周有对手下的子
  304. if (qipan[row + rowdelta][col + coldelta] == opponent)
  305. {
  306. //以对手下子位置为坐标
  307. x = row + rowdelta;
  308. y = col + coldelta;
  309. //对对手下子为起始点,向四周查找自己方的棋子,以攻击对方棋子
  310. while(1)
  311. {
  312. //对手下子的四周坐标
  313. x += rowdelta;
  314. y += coldelta;
  315. //超过棋盘
  316. if (x < 0 || x >= 8 || y < 0 || y >= 8)
  317. {
  318. break; //退出循环
  319. }
  320. //若对应位置为空
  321. if (qipan[x][y] == 0)
  322. {
  323. break;
  324. }
  325. //若对应位置下的子是当前棋手的
  326. if (qipan[x][y] == myplayer)
  327. {
  328. //设置移动数组中对应位置为1 (该位置可下子,形成向对手进攻的棋形)
  329. tishi[row][col] = 1;
  330. iStep++; //累加可下子的位置数量
  331. break;
  332. }
  333. }
  334. }
  335. }
  336. }
  337. }
  338. }
  339. //返回可下的位置数量(若返回值为0,表示没地方可下)
  340. //printf("%d\n",iStep);
  341. return iStep;
  342. }
  343. void xiaqi(int qipan[][8],int row, int col, int player) //指定位置下棋
  344. {
  345. int rowdelta = 0;
  346. int coldelta = 0;
  347. int x = 0;
  348. int y = 0;
  349. char opponent = (player == 1) ? -1 : 1; //对方棋子
  350. char myplayer = -1 * opponent; //我方棋子
  351. qipan[row][col] = myplayer; //保存所下的棋子
  352. //检查所下子四周的棋子
  353. for (rowdelta = -1; rowdelta <= 1; rowdelta++)
  354. {
  355. for (coldelta = -1; coldelta <= 1; coldelta++)
  356. {
  357. //若坐标超过棋盘界限
  358. if (row + rowdelta < 0 || row + rowdelta >= 8 || col + coldelta < 0
  359. || col + coldelta >= 8 || (rowdelta == 0 && coldelta == 0))
  360. {
  361. continue; //继续下一位置
  362. }
  363. //若该位置是对手的棋子
  364. if (qipan[row + rowdelta][col + coldelta] == opponent)
  365. {
  366. //以对手棋为坐标
  367. x = row + rowdelta;
  368. y = col + coldelta;
  369. //在对手棋子四周寻找我方棋子
  370. while(1)
  371. {
  372. x += rowdelta;
  373. y += coldelta;
  374. //若坐标超过棋盘
  375. if (x < 0 || x >= 8 || y < 0 || y >= 8)
  376. {
  377. break; //退出循环
  378. }
  379. //若对应位置为空
  380. if (qipan[x][y] == 0)
  381. {
  382. break; //退出循环
  383. }
  384. //若对应位置是我方模子
  385. if (qipan[x][y] == myplayer)
  386. {
  387. //循环处理
  388. while (qipan[x -= rowdelta][y -= coldelta] == opponent)
  389. {
  390. //将中间的棋子都变成我方棋子
  391. qipan[x][y] = myplayer;
  392. }
  393. break; //退出循环
  394. }
  395. }
  396. }
  397. }
  398. }
  399. }
  400. //获取最佳下子位置
  401. int BestPlay(int qipan[][8], int tishi[][8], int player)
  402. {
  403. int row, col, i, j;
  404. //定义一个临时数组
  405. int chessboard1[8][8] = { 0 };
  406. int MaxScore = 0; //保存最高分
  407. int Score = 0;
  408. int opponent = (player == 1) ? -1 : 1; //对手下的棋子
  409. //循环检查每个单元格
  410. for (row = 0; row < 8; row++)
  411. {
  412. for (col = 0; col < 8; col++)
  413. {
  414. //若该位置不可下子
  415. if (!tishi[row][col])
  416. {
  417. continue; //继续
  418. }
  419. //复制棋盘各单元格下子的状态到临时数组
  420. for (i = 0; i < 8; i++)
  421. {
  422. for (j = 0; j < 8; j++)
  423. {
  424. chessboard1[i][j] = qipan[i][j];
  425. }
  426. }
  427. //在临时数组中的指定行列下子
  428. xiaqi(chessboard1, row, col, player);
  429. //获取下子后可得到的分数
  430. Score = tongji(chessboard1, player);
  431. //若原方案得到的分数小于本次下子的分数
  432. if (MaxScore < Score)
  433. {
  434. MaxScore = Score; //保存最高分
  435. }
  436. }
  437. }
  438. return MaxScore;//返回得到的最高分
  439. }
  440. void renji(int qipan[][8],int tishi[][8],int player)//AI自动下子
  441. {
  442. int row, col, row1, col1, i, j;
  443. //对方可下子提到的分数和最小分数
  444. int Score = 0, MinScore = 100;
  445. //临时数组,保存棋盘下子位置
  446. int chessboard1[8][8];
  447. //临时数组,保存可下子位置
  448. int isDown1[8][8];
  449. char opponent = (player == 1) ? -1 : 1; //对手下的棋子
  450. for (row = 0; row < 8; row++) //循环检查棋盘每个单元格
  451. {
  452. for (col = 0; col < 8; col++)
  453. {
  454. //若不可下子
  455. if (tishi[row][col] == 0)
  456. {
  457. continue;//继续下一个位置
  458. }
  459. //将棋盘原来的棋子复制到临时数组中
  460. for (i = 0; i < 8; i++)
  461. {
  462. for (j = 0; j < 8; j++)
  463. {
  464. chessboard1[i][j] = qipan[i][j];
  465. }
  466. }
  467. //试着在临时棋盘中的一个位子下子
  468. xiaqi(chessboard1, row, col, player);
  469. //检查对手是否有地方可下子
  470. tishiqipan(chessboard1, isDown1, opponent);
  471. //获得临时棋盘中对方下子的得分情况
  472. Score = BestPlay(chessboard1, isDown1, opponent);
  473. //保存对方得分最低的下法
  474. if (Score < MinScore)
  475. {
  476. MinScore = Score;
  477. row1 = row;
  478. col1 = col;
  479. }
  480. }
  481. }
  482. //AI按最优下法下子
  483. xxx=row1+1;
  484. yyy=col1+1;
  485. xiaqi(qipan, row1, col1, player);
  486. }
  487. void renren()
  488. {
  489. int player1=1;
  490. printf("先手执黑,后手执白,点击屏幕开始人人对战\n");
  491. COORD pos;
  492. int t,t1;
  493. pos=get_mouse();
  494. clear_screen();
  495. int flag=0;
  496. while(1)
  497. {
  498. if(heiqi+baiqi>=64)
  499. {
  500. if(heiqi>baiqi)
  501. {
  502. MessageBox(0,"黑棋胜!","恭喜",MB_OK);
  503. break;
  504. }
  505. else
  506. {
  507. MessageBox(0,"白棋胜!","恭喜",MB_OK);
  508. break;
  509. }
  510. break;
  511. }
  512. if(player1==1)
  513. {
  514. t=tishiqipan(qipan,tishi,1);
  515. if(t==0 && t1==0)
  516. {
  517. printf(" 两者都没有位置可下\n");
  518. flag=1;
  519. break;
  520. }
  521. else if(t==0)
  522. {
  523. printf(" 黑棋没有位置可下,白棋下\n");
  524. player1=2;
  525. Sleep(2000);
  526. }
  527. else
  528. {
  529. hide();
  530. clear_screen();
  531. jiemian();
  532. COORD ps;
  533. ps=get_mouse();
  534. int x=int(ps.X);//x是列
  535. int y=int(ps.Y);//y是行
  536. x=zhuanhuax(x);
  537. y=zhuanhuay(y);
  538. if(tishi[y][x]==1)
  539. {
  540. xiaqi(qipan,y,x,1);
  541. tishiqipan(qipan,tishi,2);
  542. tongji(qipan,1);
  543. jiemian();
  544. player1=2;
  545. clear_screen();
  546. }
  547. }
  548. }
  549. if(player1==2)
  550. {
  551. t1=tishiqipan(qipan,tishi,2);
  552. if(t==0 && t1==0)
  553. {
  554. printf(" 两者都没有位置可下\n");
  555. flag=1;
  556. break;
  557. }
  558. else if(t1==0)
  559. {
  560. printf(" 黑棋没有位置可下,白棋下\n");
  561. player1=1;
  562. Sleep(2000);
  563. }
  564. else
  565. {
  566. hide();
  567. clear_screen();
  568. jiemian();
  569. COORD ps;
  570. ps=get_mouse();
  571. int x=int(ps.X);//x是列
  572. int y=int(ps.Y);//y是行
  573. x=zhuanhuax(x);
  574. y=zhuanhuay(y);
  575. if(tishi[y][x]==1)
  576. {
  577. xiaqi(qipan,y,x,2);
  578. tishiqipan(qipan,tishi,1);
  579. tongji(qipan,2);
  580. jiemian();
  581. player1=1;
  582. hide();
  583. clear_screen();
  584. }
  585. }
  586. }
  587. }
  588. tongji(qipan,1);
  589. if(heiqi>baiqi && flag)
  590. {
  591. MessageBox(0,"黑棋胜!","恭喜",MB_OK);
  592. }
  593. else if(flag)
  594. {
  595. MessageBox(0,"白棋胜!","恭喜",MB_OK);
  596. }
  597. }
  598. void renjijiemain()//人机
  599. {
  600. clear_screen();
  601. jiluqipan();//记录棋盘
  602. int player=1;
  603. int t=0,t1=0;
  604. int flag=0;
  605. printf("\n\n\n 请选择\n\n");
  606. printf("\n 新游戏\n\n");
  607. printf("\n 读取存档\n\n");
  608. COORD pos;
  609. pos=get_mouse();
  610. int x=int(pos.X);//x是列
  611. int y=int(pos.Y);//y是行
  612. if(x>=25 && x<=33 && y==6)
  613. {
  614. printf("您执黑,并且先手,点击屏幕开始人机对战,祝你好运\n");
  615. pos=get_mouse();
  616. }
  617. if(x>=27 && x<=34 && y==9)
  618. {
  619. FILE * f = 0;
  620. int i,j;
  621. f = fopen("D:\\heibaiqi.dat", "rb+");
  622. if(!f)
  623. {
  624. printf(" 游戏没有存档\n\n");
  625. }
  626. else
  627. {
  628. clear_screen();
  629. fread(qipan,sizeof(qipan),1,f);
  630. fclose(f);
  631. printf(" 读取存档成功!点击屏幕开始对战\n\n");
  632. pos=get_mouse();
  633. }
  634. }
  635. clear_screen();
  636. while(1)
  637. {
  638. if(heiqi+baiqi>=64)
  639. {
  640. if(heiqi>baiqi)
  641. {
  642. MessageBox(0,"你赢了!","恭喜",MB_OK);
  643. return ;
  644. }
  645. else
  646. {
  647. MessageBox(0,"你输了!","抱歉",MB_OK);
  648. return ;
  649. }
  650. break;
  651. }
  652. if(player==1)
  653. {
  654. t=tishiqipan(qipan,tishi,1);
  655. if(t==0 && t1==0)
  656. {
  657. printf(" 两者都没有位置可下\n");
  658. flag=1;
  659. break;
  660. }
  661. else if(t==0)
  662. {
  663. printf(" 黑棋没有位置可下,白棋下\n");
  664. player=2;
  665. }
  666. else
  667. {
  668. hide();
  669. tongji(qipan,1);
  670. clear_screen();
  671. jiemian();
  672. printf("电脑上一步走的位置< %d , %d> 悔棋(一步) 存档退出\n",xxx,yyy);
  673. COORD ps;
  674. ps=get_mouse();
  675. int x=int(ps.X);//x是列
  676. int y=int(ps.Y);//y是行
  677. //printf("%d %d\n",x,y);
  678. if(x>=35 && x<=44 && y==19)
  679. {
  680. huiqi();
  681. }
  682. else if(x>=51 && x<=58 && y==19)
  683. {
  684. FILE * f = 0;
  685. f = fopen("D:\\heibaiqi.dat", "wb+");
  686. fwrite(qipan,sizeof(qipan),1,f);
  687. fclose(f);
  688. exit(0);
  689. }
  690. else
  691. {
  692. x=zhuanhuax(x);
  693. y=zhuanhuay(y);
  694. if(tishi[y][x]==1)
  695. {
  696. jiluqipan();//记录棋盘
  697. xiaqi(qipan,y,x,1);
  698. tishiqipan(qipan,tishi,2);
  699. tongji(qipan,1);
  700. jiemian();
  701. player=2;
  702. clear_screen();
  703. }
  704. }
  705. }
  706. }
  707. if(player==2)
  708. {
  709. tongji(qipan,1);
  710. int t1=tishiqipan(qipan,tishi,2);
  711. if(t==0 && t1==0)
  712. {
  713. printf(" 两者都没有位置可下\n");
  714. flag=1;
  715. break;
  716. }
  717. else if(t1==0)
  718. {
  719. printf(" 白棋没有位置可下,黑棋下\n");
  720. player=1;
  721. }
  722. else
  723. {
  724. renji(qipan,tishi,2);
  725. player=1;
  726. }
  727. }
  728. }
  729. tongji(qipan,1);
  730. if(heiqi>baiqi && flag)
  731. {
  732. MessageBox(0,"你赢了!","恭喜",MB_OK);
  733. return ;
  734. }
  735. else if(flag)
  736. {
  737. MessageBox(0,"你输了!","抱歉",MB_OK);
  738. return ;
  739. }
  740. }
  741. void game()
  742. {
  743. int ch=0;
  744. chushihua();
  745. tishiqipan(qipan,tishi,1);
  746. ch=zhujiemian();
  747. if(ch==1)//人机对战
  748. {
  749. jiluqipan();//记录棋盘
  750. renjijiemain();
  751. }
  752. if(ch==2)
  753. {
  754. renren();//人人对战
  755. }
  756. }
  757. int main()
  758. {
  759. while(1)
  760. {
  761. clear_screen();
  762. clock_t start, finish;
  763. start = clock();
  764. game();
  765. finish = clock();
  766. double duration = (double)(finish - start) / CLOCKS_PER_SEC;
  767. int i;
  768. char str[99];
  769. sprintf(str,"%s%.2lf%s","总共用时",duration,"秒!是否再来一局?");
  770. i=MessageBox(NULL,str,"系统提示",MB_YESNO);
  771. COORD pos;
  772. pos=get_mouse();
  773. if (i!=6)
  774. {
  775. break;
  776. }
  777. }
  778. return 0;
  779. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/135335
推荐阅读
相关标签
  

闽ICP备14008679号