资讯专栏INFORMATION COLUMN

【三子棋(井字棋)】如何用C语言实现

jsbintask / 3157人阅读

摘要:三子棋目录一问题介绍三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的井字,多称为井字棋。

三子棋

目录

一、问题介绍


        三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的“井”字,多称为“井字棋”。

三子棋的游戏规则十分的简单:

在3×3的棋盘双方轮流下棋(先手一般的棋子为“X”,后手为“O”),当有一方所下的棋子连成一条直线即为胜利!

二、实现思路


  1.  创建游戏菜单
  2. 初始化棋盘
  3. 打印棋盘
  4. 玩家下棋(判断是否胜利)
  5. 电脑下棋(判断是否胜利)
  6. 游戏结束

三、实现流程


1.创建游戏菜单

</>复制代码

  1. //菜单函数void menu(void){
  2. printf("|---------------|/n");
  3. printf("|--- 1.START ---|/n");
  4. printf("|--- 0.EXIT ---|/n");
  5. printf("|---------------|/n");}

1.开始游戏      0.退出游戏

2.初始化棋盘

使用全局变量创建3×3的棋盘

使用全局变量的原因:

  1. 后续修改棋盘大小更为便捷
  2. 代码可读性加强

</>复制代码

  1. //定义行、列#define ROW 3#define COL 3

</>复制代码

  1. //初始化棋盘函数void InitChessBoard(char Board[ROW][COL], int row, int col){
  2. int i = 0;
  3. int j = 0;
  4. for (i = 0; i < row; i++)
  5. {
  6. for (j = 0; j < col; j++)
  7. { //把数组中每个元素初始化为空格
  8. Board[i][j] = " ";
  9. }
  10. }}

3.打印棋盘

在这里,为了后续棋盘的大小方便改变,将分割行分别打印

</>复制代码

  1. //打印棋盘函数void DisplayChessBoard(char Board[ROW][COL], int row, int col){
  2. int i = 0;
  3. int j = 0;
  4. for (i = 0; i < row; i++)
  5. {
  6. for (j = 0; j < col; j++)
  7. { //打印“ 字符 | 字符 | 字符 ”
  8. printf(" %c ", Board[i][j]);
  9. if (j < col - 1)
  10. {
  11. printf("|");
  12. }
  13. } //打印完一行之后换行
  14. printf("/n");
  15. if (i

4.玩家下棋

玩家需通过输入[1,3]区间内的数字来落子“x”

  • 当玩家输入超出棋盘大小的坐标时,提醒玩家输入坐标错误并重新输入
  • 当玩家输入已被占用的棋盘坐标时,提醒玩家输入坐标错误并重新输入

</>复制代码

  1. //玩家下棋函数void PlayerMove(char Board[ROW][COL], int row, int col){
  2. int x = 0;
  3. int y = 0;
  4. while (1)
  5. {
  6. printf("player(行 列):>");
  7. //玩家输入坐标
  8. scanf("%d %d", &x, &y);
  9. if (x >= 1 && x <= row && y >= 1 && y <= col)
  10. {
  11. //玩家输入区间为[1, 3]
  12. if (Board[x - 1][y - 1] == " ")
  13. {
  14. Board[x - 1][y - 1] = "x";
  15. break;
  16. }
  17. else
  18. {
  19. printf("该坐标已被占用,请重新输入!/a/n/n");
  20. }
  21. }
  22. else
  23. {
  24. printf("输入坐标非法,请重新输入!/a/n/n");
  25. }
  26. }}

5.电脑下棋

电脑下棋需要使用生成随机数种子,并且保证电脑在空的坐标上落子

在主调函数中使用生成随机数函数, 确保生成的随机数为随机:

</>复制代码

  1. srand((unsigned int)time(NULL));//time的函数返回类型是time_t//在这里使用强制转换类型(unsigned int)

</>复制代码

  1. //电脑下棋函数void ComputerMove(char Board[ROW][COL], int row, int col){
  2. int x = 0;
  3. int y = 0;
  4. printf("computer:/n");
  5. while (1)
  6. {
  7. //获取时间随机数
  8. x = rand() % row;
  9. y = rand() % col;
  10. if (Board[x][y] == " ")
  11. {
  12. Board[x][y] = "o";
  13. break;
  14. }
  15. }
  16. }

6.判断游戏胜利

在这一步我们需要定义两个函数:

  • IsWin函数(判断是否胜利)
  • IsFull函数(判断棋盘是否下满)

我们约定当返回“x”时玩家胜利

返回“o”时电脑胜利

返回“q”时代表平局

返回“c”时代表棋盘未被填满游戏继续

</>复制代码

  1. //判断是否胜利函数char IsWin(char Board[ROW][COL], int row, int col){
  2. int i = 0;
  3. //判断行
  4. for (i = 0; i < row; i++)
  5. {
  6. if (Board[i][0] == Board[i][1]
  7. && Board[i][1] == Board[i][2]
  8. && Board[i][1] != " ")
  9. {
  10. return Board[i][1];
  11. }
  12. }
  13. //判断列
  14. for (i = 0; i < col; i++)
  15. {
  16. if (Board[0][i] == Board[1][i]
  17. && Board[1][i] == Board[2][i]
  18. && Board[1][i] != " ")
  19. {
  20. return Board[1][i];
  21. }
  22. }
  23. //判断对角线"/"
  24. if (Board[0][0] == Board[1][1]
  25. && Board[1][1] == Board[2][2]
  26. && Board[1][1] != " ")
  27. {
  28. return Board[1][1];
  29. }
  30. //判断对角线"/"
  31. if (Board[0][2] == Board[1][1]
  32. && Board[1][1] == Board[2][0]
  33. && Board[1][1] != " ")
  34. {
  35. return Board[1][1];
  36. }
  37. //检查棋盘是否填满
  38. if (IsFull == 1)
  39. {
  40. //返回平局
  41. return "q";
  42. }
  43. //返回继续
  44. return "c";}

</>复制代码

  1. //判断棋盘是否被填满函数int IsFull(char Board[ROW][COL], int row, int col){
  2. int i = 0;
  3. int j = 0;
  4. for(i = 0; i < row; i++)
  5. {
  6. for (j = 0; j < col; j++)
  7. {
  8. if (Board[i][j] == " ")
  9. return 0;
  10. }
  11. }
  12. return 1;}

7.游戏函数和主调函数

</>复制代码

  1. //游戏实现函数void Game(char Board[ROW][COL], int row, int col){
  2. InitChessBoard(Board, ROW, COL);
  3. DisplayChessBoard(Board, ROW, COL);
  4. while (1)
  5. {
  6. PlayerMove(Board, ROW, COL);
  7. DisplayChessBoard(Board, ROW, COL);
  8. if (IsWin(Board, ROW, COL) != "c")
  9. break;
  10. ComputerMove(Board, ROW, COL);
  11. DisplayChessBoard(Board, ROW, COL);
  12. if (IsWin(Board, ROW, COL) != "c")
  13. break;
  14. }
  15. if (IsWin(Board, ROW, COL) == "x")
  16. printf("PLAYER WIN!/n/n");
  17. else if (IsWin(Board, ROW, COL) == "o")
  18. printf("COMPUTER WIN!/n/n");
  19. else
  20. printf("平局!/n/n");}

</>复制代码

  1. //主调函数int main(void){
  2. srand((unsigned int)time(NULL));
  3. char Board[ROW][COL] = { 0 };
  4. int input = 0;
  5. do
  6. {
  7. menu();
  8. printf("please enter:>");
  9. scanf("%d", &input);
  10. switch (input)
  11. {
  12. case 1:
  13. printf("GAME START/n");
  14. Game(Board, ROW, COL);
  15. break;
  16. case 0:
  17. printf("GAME EXIT/n/a");
  18. break;
  19. default:
  20. printf("ERROR!/n/a");
  21. }
  22. } while (input);
  23. return 0;}




四、代码总览


</>复制代码

  1. #define _CRT_SECURE_NO_WARNINGS 1//程序所需头文件#include #include #include //定义行、列#define ROW 3#define COL 3//菜单函数void menu(void){
  2. printf("|---------------|/n");
  3. printf("|--- 1.START ---|/n");
  4. printf("|--- 0.EXIT ---|/n");
  5. printf("|---------------|/n");}//初始化棋盘函数void InitChessBoard(char Board[ROW][COL], int row, int col){
  6. int i = 0;
  7. int j = 0;
  8. for (i = 0; i < row; i++)
  9. {
  10. for (j = 0; j < col; j++)
  11. {
  12. Board[i][j] = " ";
  13. }
  14. }}//打印棋盘函数void DisplayChessBoard(char Board[ROW][COL], int row, int col){
  15. int i = 0;
  16. int j = 0;
  17. for (i = 0; i < row; i++)
  18. {
  19. for (j = 0; j < col; j++)
  20. {
  21. printf(" %c ", Board[i][j]);
  22. if (j < col - 1)
  23. {
  24. printf("|");
  25. }
  26. }
  27. printf("/n");//打印完一行之后换行
  28. if (i ");
  29. //玩家输入坐标
  30. scanf("%d %d", &x, &y);
  31. if (x >= 1 && x <= row && y >= 1 && y <= col)
  32. {
  33. //玩家输入区间为[1, 3]
  34. if (Board[x - 1][y - 1] == " ")
  35. {
  36. Board[x - 1][y - 1] = "x";
  37. break;
  38. }
  39. else
  40. {
  41. printf("该坐标已被占用,请重新输入!/a/n/n");
  42. }
  43. }
  44. else
  45. {
  46. printf("输入坐标非法,请重新输入!/a/n/n");
  47. }
  48. }}//电脑下棋函数void ComputerMove(char Board[ROW][COL], int row, int col){
  49. int x = 0;
  50. int y = 0;
  51. printf("computer:/n");
  52. while (1)
  53. {
  54. //获取时间随机数
  55. x = rand() % row;
  56. y = rand() % col;
  57. if (Board[x][y] == " ")
  58. {
  59. Board[x][y] = "o";
  60. break;
  61. }
  62. }
  63. }//判断棋盘是否被填满函数int IsFull(char Board[ROW][COL], int row, int col){
  64. int i = 0;
  65. int j = 0;
  66. for(i = 0; i < row; i++)
  67. {
  68. for (j = 0; j < col; j++)
  69. {
  70. if (Board[i][j] == " ")
  71. return 0;
  72. }
  73. }
  74. return 1;}//判断是否胜利函数char IsWin(char Board[ROW][COL], int row, int col){
  75. int i = 0;
  76. //判断行
  77. for (i = 0; i < row; i++)
  78. {
  79. if (Board[i][0] == Board[i][1]
  80. && Board[i][1] == Board[i][2]
  81. && Board[i][1] != " ")
  82. {
  83. return Board[i][1];
  84. }
  85. }
  86. //判断列
  87. for (i = 0; i < col; i++)
  88. {
  89. if (Board[0][i] == Board[1][i]
  90. && Board[1][i] == Board[2][i]
  91. && Board[1][i] != " ")
  92. {
  93. return Board[1][i];
  94. }
  95. }
  96. //判断对角线"/"
  97. if (Board[0][0] == Board[1][1]
  98. && Board[1][1] == Board[2][2]
  99. && Board[1][1] != " ")
  100. {
  101. return Board[1][1];
  102. }
  103. //判断对角线"/"
  104. if (Board[0][2] == Board[1][1]
  105. && Board[1][1] == Board[2][0]
  106. && Board[1][1] != " ")
  107. {
  108. return Board[1][1];
  109. }
  110. //检查棋盘是否填满
  111. if (IsFull == 1)
  112. {
  113. //返回平局
  114. return "q";
  115. }
  116. //返回继续
  117. return "c";}//游戏实现函数void Game(char Board[ROW][COL], int row, int col){
  118. InitChessBoard(Board, ROW, COL);
  119. DisplayChessBoard(Board, ROW, COL);
  120. while (1)
  121. {
  122. PlayerMove(Board, ROW, COL);
  123. DisplayChessBoard(Board, ROW, COL);
  124. if (IsWin(Board, ROW, COL) != "c")
  125. break;
  126. ComputerMove(Board, ROW, COL);
  127. DisplayChessBoard(Board, ROW, COL);
  128. if (IsWin(Board, ROW, COL) != "c")
  129. break;
  130. }
  131. if (IsWin(Board, ROW, COL) == "x")
  132. printf("PLAYER WIN!/n/n");
  133. else if (IsWin(Board, ROW, COL) == "o")
  134. printf("COMPUTER WIN!/n/n");
  135. else
  136. printf("平局!/n/n");}//主调函数int main(void){
  137. srand((unsigned int)time(NULL));
  138. char Board[ROW][COL] = { 0 };
  139. int input = 0;
  140. do
  141. {
  142. menu();
  143. printf("please enter:>");
  144. scanf("%d", &input);
  145. switch (input)
  146. {
  147. case 1:
  148. printf("GAME START/n");
  149. Game(Board, ROW, COL);
  150. break;
  151. case 0:
  152. printf("GAME EXIT/n/a");
  153. break;
  154. default:
  155. printf("ERROR!/n/a");
  156. }
  157. } while (input);
  158. return 0;}



五、代码注意事项


  • 程序中哪里需要使用循环,哪里不需要使用循环应仔细分清
  • Game()函数中,每当玩家下棋或是电脑下棋都需要判断是否胜利

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123083.html

相关文章

  • C语言实现入门级小游戏——三子(万字长篇)

    摘要:今天博主将为大家带来语言入门级小游戏三子棋井字棋的详细介绍,希望这篇文章对大家能有帮助。在这里,我们使用函数来实现这一功能。        今天博主将为大家带来C语言入门级小游戏——三子棋(井字棋)的详细介绍,希望这篇文章对大家能有帮助 。       在编程的学习过程中,编写一些中这样...

    meteor199 评论0 收藏0
  • 三子游戏设计及代码实现

    摘要:三子棋三子棋游戏介绍规则游戏设计思路代码分析文件代码分析。玩家下棋实现。三子棋是一种民间传统游戏,又叫九宫棋圈圈叉叉一条龙井字棋等。落子后打印棋盘以显示。假设平局时判定输赢的函数返回后面代码实现时详细讲。 ...

    Ku_Andrew 评论0 收藏0
  • Minimax 和 Alpha-beta 剪枝算法简介,以及以此实现井字游戏(Tic-tac-t

    摘要:我们在前文中考虑的那张图就来自这篇文章,之后我们会用剪枝算法来改进之前的解决方案。剪枝算法的实现接下来讨论如何修改前面实现的算法,使其变为剪枝算法。现在我们已经有了现成的和剪枝算法,只要加上一点儿细节就能完成这个游戏了。 前段时间用 React 写了个2048 游戏来练练手,准备用来回顾下 React 相关的各种技术,以及试验一下新技术。在写这个2048的过程中,我考虑是否可以在其中加...

    wemall 评论0 收藏0
  • Minimax 和 Alpha-beta 剪枝算法简介,以及以此实现井字游戏(Tic-tac-t

    摘要:我们在前文中考虑的那张图就来自这篇文章,之后我们会用剪枝算法来改进之前的解决方案。剪枝算法的实现接下来讨论如何修改前面实现的算法,使其变为剪枝算法。现在我们已经有了现成的和剪枝算法,只要加上一点儿细节就能完成这个游戏了。 前段时间用 React 写了个2048 游戏来练练手,准备用来回顾下 React 相关的各种技术,以及试验一下新技术。在写这个2048的过程中,我考虑是否可以在其中加...

    Eirunye 评论0 收藏0
  • C语言入门》三子C语言实现(详细版)

    摘要:简单介绍了三子棋原理后接下来为大家讲解分步目标及代码如何实现。电脑下棋我们实现了玩家和电脑的下棋后,我们需要编写一个函数来判断双方的输赢。我们使用函数来实现这一目标。 目录 1.三子棋原理 2.分块代码实现 3.总结 1.首先向大家介绍一下三子棋的原理 首先我们需要有一个棋盘,初始时棋...

    妤锋シ 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<