当前位置:   article > 正文

C语言实现三子棋_c语言打印3*3棋盘

c语言打印3*3棋盘

目录

一、规则简介

二、游戏逻辑

三、菜单打印

四、棋盘的创建和初始化

五、棋盘打印

六、下棋

6.1 玩家下棋

6.2 电脑下棋

6.3 输赢判断

七、总结


一、规则简介

三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。

二、游戏逻辑

首先,我们需要一个游戏菜单,通过玩家的输入进行不同的操作,这里就可以使用 switch 语句实现;根据玩家的不同选择,有两种走向,选择 1、玩游戏  0、退出  以及选择错误时需要给玩家提示。

我们还希望这个游戏可以一直玩下去,直到玩家主动选择退出,因此这里采用一个循环语句,由于刚刚说了玩家需要输入选择,这里循环的控制可以直接根据玩家选择进行设置,这里我采用的是 do while 循环,大家也可以尝试使用 while 循环。

程序文件主要有三个,分别是:主函数文件test.c;包含游戏主要功能的源文件game.c;用来引用各种头文件,声明函数的头文件game.h 。

  1. int main()
  2. {
  3. int input = 0;
  4. do
  5. {
  6. menu();
  7. printf("请选择>:");
  8. scanf("%d", &input);
  9. switch (input)
  10. {
  11. case 1:
  12. game();
  13. break;
  14. case 0:
  15. printf("游戏退出\n");
  16. break;
  17. default:
  18. printf("选择错误,重新选择\n");
  19. break;
  20. }
  21. } while (input);
  22. return 0;
  23. }

三、菜单打印

菜单打印就是简单的输出语句,代码如下:

  1. void menu()
  2. {
  3. printf("**********************\n");
  4. printf("***** 1.play *******\n");
  5. printf("***** 0.exit *******\n");
  6. printf("**********************\n");
  7. }

四、棋盘的创建和初始化

菜单打印完后,就进入到我们的游戏主题  game()  函数,首先是棋盘创建及初始化,我们需要打印一个3x3 的棋盘,首先在头文件中定义全局变量,棋盘的行列,这样方便后续更改。

  1. #include <stdio.h>
  2. #define ROW 3 //行
  3. #define COL 3 //列
  1. void game()
  2. {
  3. char ret = 0;
  4. //生成棋盘
  5. char board[ROW][COL] = { 0 };
  6. //初始化棋盘
  7. initboard(board, ROW, COL);
  8. //打印棋盘
  9. displayboard(board, ROW, COL);
  10. }

初始化棋盘通过函数  initboard() 实现,由于初始化对象是棋盘,因此函数的参数需要:棋盘本身,棋盘行列,代码如下:

  1. void initboard(char board[ROW][COL], int row, int col)
  2. {
  3. int i = 0;
  4. int j = 0;
  5. for (i = 0; i < ROW; i++)
  6. {
  7. for (j = 0; j < COL; j++)
  8. {
  9. board[i][j] = ' ';
  10. }
  11. }
  12. }

在没有下棋时,将棋盘每个位置设为空格

五、棋盘打印

棋盘创建及初始化之后,需要打印出来让玩家看到

棋盘有以下特点:三个棋子行,两个分割行,两个分隔列

  1. // | |
  2. //---|---|---
  3. // | |
  4. //---|---|---
  5. // | |

通过函数 displayboard() 实现,函数参数同样是 棋盘本身及棋盘行列:

  1. void displayboard(char board[ROW][COL], int row, int col)
  2. {
  3. int i = 0;
  4. int j = 0;
  5. for (i = 0; i < row; i++)
  6. {
  7. //棋子行
  8. for (j = 0; j < col; j++)
  9. {
  10. printf(" %c ", board[i][j]);
  11. if (j < col - 1)
  12. printf("|");
  13. }
  14. printf("\n");
  15. //分隔行
  16. if (i < row - 1)
  17. {
  18. for (j = 0; j < col; j++)
  19. {
  20. printf("---");
  21. if (j < col - 1)
  22. printf("|");
  23. }
  24. }
  25. printf("\n");
  26. }
  27. }

这里在打印分割行时设置条件为  i<row-1,j<col-1 因为在棋盘的边缘不需要分割行和分隔列。

打印结果如下:

六、下棋

 棋盘生成后就可以开下棋了,由于需要循环下棋,这里也采用循环语句控制:

  1. void game()
  2. {
  3. char ret = 0;
  4. //生成棋盘
  5. char board[ROW][COL] = { 0 };
  6. //初始化棋盘
  7. initboard(board, ROW, COL);
  8. //打印棋盘
  9. displayboard(board, ROW, COL);
  10. //下棋
  11. while (1)
  12. {
  13. //玩家下
  14. player(board, ROW, COL);
  15. //打印
  16. displayboard(board, ROW, COL);
  17. //判断输赢
  18. ret = win(board, ROW, COL);
  19. if (ret != 'c')
  20. break;
  21. //电脑下
  22. com(board, ROW, COL);
  23. displayboard(board, ROW, COL);
  24. //判断
  25. ret = win(board, ROW, COL);
  26. if (ret != 'c')
  27. break;
  28. }

 下棋又分为玩家下棋以及电脑下棋,并且每次下棋后,希望能够打印出来让玩家看见。此外,每次下棋,无论玩家还是电脑,都有可能使得游戏结束,可能是玩家赢也可能电脑赢,也可能平局,因此每次下棋后还需要判断游戏的输赢

6.1 玩家下棋

玩家下棋时,通过玩家输入棋盘坐标确定下棋的位置.

注意:玩家输入的坐标是从1-3,但棋盘生成是通过数组完成,因此在代码中坐标是从 0-2

在玩家下棋时,要判断该位置是否已经有棋子,或者是否在棋盘范围内,如果不符合上述条件要求玩家重下,因此这里也需要循环

玩家下棋的代码:

  1. void player(char board[ROW][COL], int row, int col)
  2. {
  3. int x = 0;
  4. int y = 0;
  5. scanf("%d %d", &x, &y);
  6. while (1)
  7. {
  8. if (x >= 1 && x <= row && y >= 1 && y <= col)
  9. {
  10. if (board[x - 1][y - 1] == ' ')
  11. {
  12. board[x - 1][y - 1] = '*';
  13. break;
  14. }
  15. else
  16. printf("该坐标被占用,重新输入\n");
  17. }
  18. else
  19. {
  20. printf("输入错误,重新输入\n");
  21. }
  22. }
  23. }

6.2 电脑下棋

电脑下棋要比玩家更简单一些,这里我们通过生成随机数让电脑在棋盘上随机下子

随机数生成需要用到 rand() 和 srand() 函数,同时通过时间戳来设置随机数的起点,因此在头文件 game.h 中需要加上相应的头文件

  1. #include <stdio.h>
  2. #include <stdlib.h> //rand srand
  3. #include <time.h> //time
  4. #define ROW 3 //
  5. #define COL 3 //

由于 srand 只使用一次,所有我们在 game 函数循环的外面进行 srand 

  1. void game()
  2. {
  3. char ret = 0;
  4. //生成棋盘
  5. char board[ROW][COL] = { 0 };
  6. //初始化棋盘
  7. initboard(board, ROW, COL);
  8. //打印棋盘
  9. displayboard(board, ROW, COL);
  10. srand((unsigned int)time(NULL)); //随机数起点设置
  11. while (1)
  12. {
  13. //玩家下
  14. player(board, ROW, COL);
  15. //打印
  16. displayboard(board, ROW, COL);
  17. //判断输赢
  18. ret = win(board, ROW, COL);
  19. if (ret != 'c')
  20. break;
  21. //电脑下
  22. com(board, ROW, COL);
  23. displayboard(board, ROW, COL);
  24. //判断
  25. ret = win(board, ROW, COL);
  26. if (ret != 'c')
  27. break;
  28. }
  29. if (ret == '*')
  30. printf("玩家赢\n");
  31. else if (ret == '#')
  32. printf("电脑赢\n");
  33. else
  34. printf("平局\n");
  35. }

通过随机数对行列分别取余,控制随机数范围在 0-2

电脑下棋代码如下:

  1. void com(char board[ROW][COL], int row, int col)
  2. {
  3. while (1)
  4. {
  5. int x = rand() % row;
  6. int y = rand() % col;
  7. if (board[x][y] == ' ')
  8. {
  9. board[x][y] = '#';
  10. break;
  11. }
  12. }
  13. }

6.3 输赢判断

获胜共有三种方式,横向,竖向,对角组成一线,以及在棋盘下满时若无人获胜则平局

这里通过不同的返回值来确定输赢及平局

返回 * :玩家获胜

返回 #:电脑获胜

返回 c:无人获胜,且棋盘未满,继续游戏

返回 q:棋盘满了,平局

代码如下:

  1. char win(char board[ROW][COL], int row, int col)
  2. {
  3. int i = 0;
  4. //横行
  5. for (i = 0; i < row; i++)
  6. {
  7. if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
  8. {
  9. return board[i][0];
  10. }
  11. }
  12. //竖行
  13. for (i = 0; i < row; i++)
  14. {
  15. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
  16. {
  17. return board[0][1];
  18. }
  19. }
  20. //对角
  21. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
  22. {
  23. return board[0][0];
  24. }
  25. if (full(board, ROW, COL) == 1)
  26. return 'q';
  27. return 'c';
  28. }

这里在判断棋盘是否满时,又另外封装了一个函数,通过返回值判读棋盘是否满了

返回1:满了

返回0:未满

  1. int full(char board[ROW][COL], int row, int col)
  2. {
  3. int i = 0;
  4. int j = 0;
  5. for (i = 0; i < row; i++)
  6. {
  7. for (j = 0; j < col; j++)
  8. {
  9. if (board[i][j] == ' ')
  10. return 0;
  11. }
  12. }
  13. return 1;
  14. }

由于输赢判断函数有返回值,所以在 game 函数中需要一个变量接受该返回值,最后通过判断该变量的值确定输赢:

  1. void game()
  2. {
  3. char ret = 0;//用于接收输赢判断函数返回值的变量
  4. //生成棋盘
  5. char board[ROW][COL] = { 0 };
  6. //初始化棋盘
  7. initboard(board, ROW, COL);
  8. //打印棋盘
  9. displayboard(board, ROW, COL);
  10. srand((unsigned int)time(NULL));//随机数起点设置
  11. while (1)
  12. {
  13. //玩家下
  14. player(board, ROW, COL);
  15. //打印
  16. displayboard(board, ROW, COL);
  17. //判断输赢
  18. ret = win(board, ROW, COL);
  19. if (ret != 'c')
  20. break;
  21. //电脑下
  22. com(board, ROW, COL);
  23. displayboard(board, ROW, COL);
  24. //判断
  25. ret = win(board, ROW, COL);
  26. if (ret != 'c')
  27. break;
  28. }
  29. if (ret == '*')
  30. printf("玩家赢\n");
  31. else if (ret == '#')
  32. printf("电脑赢\n");
  33. else
  34. printf("平局\n");
  35. }

七、总结

至此,三子棋的基本功能都完成了,我们来看下各个文件中的代码:

首先是头文件 game.h :

  1. # define _CRT_SECURE_NO_WARNINGS 1
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #define ROW 3
  6. #define COL 3
  7. void menu();
  8. void game();
  9. void initboard(char board[ROW][COL], int row, int col);
  10. void displayboard(char board[ROW][COL], int row, int col);
  11. void player(char board[ROW][COL], int row, int col);
  12. char win(char board[ROW][COL], int row, int col);
  13. void com(char board[ROW][COL], int row, int col);

游戏文件 game.c:

  1. # define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. void menu()
  4. {
  5. printf("**********************\n");
  6. printf("***** 1.play *******\n");
  7. printf("***** 0.exit *******\n");
  8. printf("**********************\n");
  9. }
  10. // | |
  11. //---|---|---
  12. // | |
  13. //---|---|---
  14. // | |
  15. void initboard(char board[ROW][COL], int row, int col)
  16. {
  17. int i = 0;
  18. int j = 0;
  19. for (i = 0; i < ROW; i++)
  20. {
  21. for (j = 0; j < COL; j++)
  22. {
  23. board[i][j] = ' ';
  24. }
  25. }
  26. }
  27. void displayboard(char board[ROW][COL], int row, int col)
  28. {
  29. int i = 0;
  30. int j = 0;
  31. for (i = 0; i < row; i++)
  32. {
  33. //棋子行
  34. for (j = 0; j < col; j++)
  35. {
  36. printf(" %c ", board[i][j]);
  37. if (j < col - 1)
  38. printf("|");
  39. }
  40. printf("\n");
  41. //分隔行
  42. if (i < row - 1)
  43. {
  44. for (j = 0; j < col; j++)
  45. {
  46. printf("---");
  47. if (j < col - 1)
  48. printf("|");
  49. }
  50. }
  51. printf("\n");
  52. }
  53. }
  54. void player(char board[ROW][COL], int row, int col)
  55. {
  56. int x = 0;
  57. int y = 0;
  58. scanf("%d %d", &x, &y);
  59. while (1)
  60. {
  61. if (x >= 1 && x <= row && y >= 1 && y <= col)
  62. {
  63. if (board[x - 1][y - 1] == ' ')
  64. {
  65. board[x - 1][y - 1] = '*';
  66. break;
  67. }
  68. else
  69. printf("该坐标被占用,重新输入\n");
  70. }
  71. else
  72. {
  73. printf("输入错误,重新输入\n");
  74. }
  75. }
  76. }
  77. int full(char board[ROW][COL], int row, int col)
  78. {
  79. int i = 0;
  80. int j = 0;
  81. for (i = 0; i < row; i++)
  82. {
  83. for (j = 0; j < col; j++)
  84. {
  85. if (board[i][j] == ' ')
  86. return 0;
  87. }
  88. }
  89. return 1;
  90. }
  91. char win(char board[ROW][COL], int row, int col)
  92. {
  93. int i = 0;
  94. //横行
  95. for (i = 0; i < row; i++)
  96. {
  97. if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
  98. {
  99. return board[i][0];
  100. }
  101. }
  102. //竖行
  103. for (i = 0; i < row; i++)
  104. {
  105. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
  106. {
  107. return board[0][1];
  108. }
  109. }
  110. //对角
  111. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
  112. {
  113. return board[0][0];
  114. }
  115. if (full(board, ROW, COL) == 1)
  116. return 'q';
  117. return 'c';
  118. }
  119. void com(char board[ROW][COL], int row, int col)
  120. {
  121. while (1)
  122. {
  123. int x = rand() % row;
  124. int y = rand() % col;
  125. if (board[x][y] == ' ')
  126. {
  127. board[x][y] = '#';
  128. break;
  129. }
  130. }
  131. }
  132. void game()
  133. {
  134. char ret = 0;
  135. //生成棋盘
  136. char board[ROW][COL] = { 0 };
  137. //初始化棋盘
  138. initboard(board, ROW, COL);
  139. //打印棋盘
  140. displayboard(board, ROW, COL);
  141. srand((unsigned int)time(NULL));
  142. while (1)
  143. {
  144. //玩家下
  145. player(board, ROW, COL);
  146. //打印
  147. displayboard(board, ROW, COL);
  148. //判断输赢
  149. ret = win(board, ROW, COL);
  150. if (ret != 'c')
  151. break;
  152. //电脑下
  153. com(board, ROW, COL);
  154. displayboard(board, ROW, COL);
  155. //判断
  156. ret = win(board, ROW, COL);
  157. if (ret != 'c')
  158. break;
  159. }
  160. if (ret == '*')
  161. printf("玩家赢\n");
  162. else if (ret == '#')
  163. printf("电脑赢\n");
  164. else
  165. printf("平局\n");
  166. }

主函数文件 test.c:

  1. # define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. int main()
  4. {
  5. int input = 0;
  6. do
  7. {
  8. menu();
  9. printf("请选择>:");
  10. scanf("%d", &input);
  11. switch (input)
  12. {
  13. case 1:
  14. game();
  15. break;
  16. case 0:
  17. printf("游戏退出\n");
  18. break;
  19. default:
  20. printf("选择错误,重新选择\n");
  21. break;
  22. }
  23. } while (input);
  24. return 0;
  25. }

现在让我们来试试游戏吧:

 

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

闽ICP备14008679号