三子棋(C语言)

川长思鸟来 2023-10-09 23:52 34阅读 0赞

目录

1.代码结果演示

2.三子棋实现

2.1游戏思路

2.2分步实现

2.2.1分别创建头文件game.h、源文件game.c和test.c

2.2.2创建菜单并实现选择是否玩游戏

2.2.3创建棋盘并完成初始化

2.2.4打印棋盘

2.2.5玩家下棋

2.2.6电脑下棋

2.2.7判断输赢

3.完整代码

game.h

game.c

test.c


1.代码结果演示

84ff12ee143643d8ba3dfaf125fc692e.png

2.三子棋实现

2.1游戏思路

(1)创建菜单选择开始游戏或退出

(2)创建棋盘并完成初始化

(3)打印棋盘

(4)玩家下棋

(5)电脑自动下棋

(6)判断胜负

2.2分步实现

2.2.1分别创建头文件game.h、源文件game.c和test.c

b1112627ff274dd0ac4960d130e2d927.png

game.h :用于存放自定义函数的声明、引用的标准库头文件等

game.c:用于存放函数的定义

test.c:用于程序测试

2.2.2创建菜单并实现选择是否玩游戏

首先创建菜单提供选项

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

再在main函数中实现选择

  1. void menu()//打印菜单
  2. {
  3. printf("***************************\n");
  4. printf("*********1. play **********\n");
  5. printf("*********0. exit **********\n");
  6. printf("***************************\n");
  7. }
  8. int main()
  9. {
  10. int input = 0;
  11. while (1)
  12. {
  13. //打印菜单
  14. menu();
  15. printf("请选择:>");
  16. scanf("%d", &input);
  17. //判断选择,也可以使用switch
  18. if (input == 1)
  19. {
  20. printf("三子棋游戏现在开始!\n");
  21. //game();//玩游戏
  22. }
  23. else if (input == 0)
  24. {
  25. printf("游戏结束\n");
  26. break;//退出游戏
  27. }
  28. else
  29. {
  30. printf("选择错误,请重新选择\n");
  31. }
  32. }
  33. return 0;
  34. }

测试结果

560c0e228d3742ddab535d34cd8fb15a.png

注:在函数实现的每一步都进行测试,能够及时找到错误并改正

2.2.3创建棋盘并完成初始化

在游戏开始时,棋盘上没有任何棋子,因此我们要对棋盘进行初始化,清空棋盘,保证后续游戏的进行

这里我们创建3*3大小的棋盘,对于数组行和列的大小,我们可以选择使用宏定义,若是想要修改行和列的大小,则只需要修改define定义的行列大小

  1. //在game.h中定义行和列的大小
  2. #define ROW 3
  3. #define COL 3

在game()函数中创建棋盘

  1. #inclide "game.h"//记得引自定义头文件
  2. void game()
  3. {
  4. //创建二维数组用于存放下棋数据
  5. char board[ROW][COL] = { 0 };
  6. //初始化棋盘
  7. InitBoard(board, ROW, COL);
  8. }

接下来我们实现初始化棋盘函数

  1. //初始化棋盘
  2. void InitBoard(char board[ROW][COL], int row, int col)
  3. {
  4. for (int i = 0; i < row; i++)
  5. {
  6. for (int j = 0; j < col; j++)
  7. {
  8. board[i][j] = ' ';//将数组中所有元素初始化为空格
  9. }
  10. }
  11. }

注:在game.h中定义InitBoard函数,在game.c中实现InitBoard函数

调试结果

0bea819048044d01b8c0ae2d236fadd7.png

2.2.4打印棋盘

在实现棋盘的初始化后,我们要将已初始化的棋盘展现出来,以便玩家下棋

  1. //打印棋盘
  2. void DisplayBoard(char board[ROW][COL], int row, int col)
  3. {
  4. for (int i = 0; i < row; i++)
  5. {
  6. for (int 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 < row - 1)//打印---|---以隔开不同行的棋子
  16. {
  17. for (int j = 0; j < col; j++)
  18. {
  19. printf("---");
  20. if (j < col - 1)
  21. {
  22. printf("|");
  23. }
  24. }
  25. printf("\n");
  26. }
  27. }
  28. }

测试结果

6e4808a02d4644cc97b3d23255b2230a.png

2.2.5玩家下棋

在实现玩家下棋时,我们要先接收玩家输入的下棋位置

再判断输入的位置是否在棋盘范围内,是否已有棋子

最后将棋子放入对应位置

  1. //玩家下棋
  2. void PlayerMove(char board[ROW][COL], int row, int col)
  3. {
  4. int x = 0;
  5. int y = 0;
  6. printf("玩家走:>\n");
  7. while (1)
  8. {
  9. printf("请输入坐标(中间以空格隔开):>");
  10. scanf("%d %d", &x, &y);
  11. if ((x > 0 && x <= ROW) && (y > 0 && y <= COL))
  12. {
  13. if (board[x - 1][y - 1] == ' ')
  14. {
  15. board[x - 1][y - 1] = '*';
  16. break;
  17. }
  18. else
  19. {
  20. printf("坐标已被占用,请重新输入!\n");
  21. }
  22. }
  23. else
  24. {
  25. printf("输入坐标错误,请重新输入!\n");
  26. }
  27. }
  28. }

注:玩家下棋时默认棋盘位置是从1开始的,而不是0

运行结果

9eb988572b9d41b5ab2846079902ec62.png

2.2.6电脑下棋

在实现电脑自动下棋时,我们要生成随机数,并判断生成的坐标是否已有棋子

  1. void ComputerMove(char board[ROW][COL], int row, int col)
  2. {
  3. int x = 0;
  4. int y = 0;
  5. printf("电脑下棋:>\n");
  6. while (1)
  7. {
  8. //在使用rand()时,要引用对应头文件
  9. //要使用srand((unsigned int)time(NULL))来进行初始化
  10. x = rand() % row;
  11. y = rand() % col;
  12. if (board[x][y] == ' ')
  13. {
  14. board[x][y] = '#';
  15. break;
  16. }
  17. }
  18. }

在game.h中引用头文件

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>

在main函数中使用srand

  1. int main()
  2. {
  3. srand((unsigned int)time(NULL));
  4. int input = 0;
  5. while (1)
  6. {
  7. //打印菜单
  8. menu();
  9. printf("请选择:>");
  10. scanf("%d", &input);
  11. if (input == 1)
  12. {
  13. printf("三子棋游戏现在开始!\n");
  14. game();//玩游戏
  15. }
  16. else if (input == 0)
  17. {
  18. printf("游戏结束\n");
  19. break;//退出游戏
  20. }
  21. else
  22. {
  23. printf("选择错误,请重新选择\n");
  24. }
  25. }
  26. return 0;
  27. }

运行结果

faf712431e684b4094b9e763e179dd10.png

2.2.7判断输赢

在下棋过程中,我们要在玩家和电脑每一步下棋后判断是否有一方胜出,若没有且棋盘未满,则游戏继续

若玩家赢 -> 函数返回‘*’

若电脑赢 -> 返回’#‘

若平局 -> 返回‘Q’

游戏继续 - > 返回‘C’

  1. char IsWin(char board[ROW][COL], int row, int col)
  2. {
  3. int i = 0;
  4. int j = 0;
  5. int flag = 1;
  6. for (i = 0; i < row; i++)//判断行是否相等
  7. {
  8. flag = 1;
  9. for (j = 0; j < col; j++)
  10. {
  11. if (board[i][j] != board[i][0] || board[i][j] == ' ')//一行的每一个元素是否相同
  12. {
  13. flag = 0;
  14. break;
  15. }
  16. }
  17. if (flag == 1)
  18. {
  19. return board[i][0];
  20. }
  21. }
  22. for (j = 0; j < col; j++)//判断列是否相等
  23. {
  24. flag = 1;
  25. for (i = 0; i < row; i++)//判断一列的元素是否相同
  26. {
  27. if (board[i][j] != board[0][j] || board[i][j] == ' ')
  28. {
  29. flag = 0;
  30. break;
  31. }
  32. }
  33. if (flag == 1)
  34. {
  35. return board[0][j];
  36. }
  37. }
  38. flag = 1;
  39. for (i = 0; i < row; i++)//主对角线元素是否相同
  40. {
  41. if (board[i][i] != board[0][0] || board[i][i] == ' ')
  42. {
  43. flag = 0;
  44. break;
  45. }
  46. }
  47. if (flag == 1)
  48. {
  49. return board[0][0];
  50. }
  51. flag = 1;
  52. for (i = 0, j = col - 1; i < row; i++, j--)//判断副对角线元素是否相同
  53. {
  54. if (board[i][j] != board[0][col - 1] || board[i][j] == ' ')
  55. {
  56. flag = 0;
  57. break;
  58. }
  59. }
  60. if (flag == 1)
  61. {
  62. return board[0][col - 1];
  63. }
  64. //平局
  65. for (int i = 0; i < row; i++)
  66. {
  67. for (int j = 0; j < col; j++)
  68. {
  69. if (board[i][j] == ' ')
  70. {
  71. //还有未下棋的坐标,游戏继续
  72. return 'C';
  73. }
  74. }
  75. }
  76. return 'Q';
  77. }

在完成判断输赢函数后,我们在game()函数中实现循环,当一方胜出或平局时结束游戏

  1. void game()
  2. {
  3. //二维数组用于存放下棋数据
  4. char board[ROW][COL] = { 0 };
  5. //初始化棋盘
  6. InitBoard(board, ROW, COL);
  7. //打印棋盘
  8. DisplayBoard(board, ROW, COL);
  9. char ret = 0;
  10. while (1)
  11. {
  12. //玩家下棋
  13. PlayerMove(board, ROW, COL);
  14. //打印棋盘
  15. DisplayBoard(board, ROW, COL);
  16. //判断输赢
  17. ret = IsWin(board, ROW, COL);
  18. if (ret != 'C')
  19. {
  20. break;
  21. }
  22. //电脑下棋
  23. ComputerMove(board, ROW, COL);
  24. //打印棋盘
  25. DisplayBoard(board, ROW, COL);
  26. //判断输赢
  27. ret = IsWin(board, ROW, COL);
  28. if (ret != 'C')
  29. {
  30. break;
  31. }
  32. }

运行结果

d7fde226f2e44adfacd3c3c6e13c77ff.png

3.完整代码

game.h

  1. #pragma once
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #define ROW 3
  6. #define COL 3
  7. void InitBoard(char board[ROW][COL], int row, int col);
  8. void DisplayBoard(char board[ROW][COL], int row, int col);
  9. void PlayerMove(char board[ROW][COL], int row, int col);
  10. char IsWin(char board[ROW][COL], int row, int col);
  11. void ComputerMove(char board[ROW][COL], int row, int col);

game.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. //初始化棋盘
  4. void InitBoard(char board[ROW][COL], int row, int col)
  5. {
  6. for (int i = 0; i < row; i++)
  7. {
  8. for (int j = 0; j < col; j++)
  9. {
  10. board[i][j] = ' ';
  11. }
  12. }
  13. }
  14. //打印棋盘
  15. void DisplayBoard(char board[ROW][COL], int row, int col)
  16. {
  17. for (int i = 0; i < row; i++)
  18. {
  19. for (int 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 < row - 1)
  29. {
  30. for (int j = 0; j < col; j++)
  31. {
  32. printf("---");
  33. if (j < col - 1)
  34. {
  35. printf("|");
  36. }
  37. }
  38. printf("\n");
  39. }
  40. }
  41. }
  42. //玩家下棋
  43. void PlayerMove(char board[ROW][COL], int row, int col)
  44. {
  45. int x = 0;
  46. int y = 0;
  47. printf("玩家下棋\n");
  48. while (1)
  49. {
  50. printf("请输入坐标(中间以空格隔开):>");
  51. scanf("%d %d", &x, &y);
  52. if ((x > 0 && x <= ROW) && (y > 0 && y <= COL))
  53. {
  54. if (board[x - 1][y - 1] == ' ')
  55. {
  56. board[x - 1][y - 1] = '*';
  57. break;
  58. }
  59. else
  60. {
  61. printf("坐标已被占用,请重新输入!\n");
  62. }
  63. }
  64. else
  65. {
  66. printf("输入坐标错误,请重新输入!\n");
  67. }
  68. }
  69. }
  70. //判断输赢
  71. //玩家赢 -- 返回*
  72. //电脑赢 -- 返回#
  73. //平局 -- 返回Q
  74. //继续 -- 返回C
  75. char IsWin(char board[ROW][COL], int row, int col)
  76. {
  77. int i = 0;
  78. int j = 0;
  79. int flag = 1;
  80. for (i = 0; i < row; i++)//判断行是否相等
  81. {
  82. flag = 1;
  83. for (j = 0; j < col; j++)
  84. {
  85. if (board[i][j] != board[i][0] || board[i][j] == ' ')//一行的每一个元素是否相同
  86. {
  87. flag = 0;
  88. break;
  89. }
  90. }
  91. if (flag == 1)
  92. {
  93. return board[i][0];
  94. }
  95. }
  96. for (j = 0; j < col; j++)//判断列是否相等
  97. {
  98. flag = 1;
  99. for (i = 0; i < row; i++)//判断一列的元素是否相同
  100. {
  101. if (board[i][j] != board[0][j] || board[i][j] == ' ')
  102. {
  103. flag = 0;
  104. break;
  105. }
  106. }
  107. if (flag == 1)
  108. {
  109. return board[0][j];
  110. }
  111. }
  112. flag = 1;
  113. for (i = 0; i < row; i++)//主对角线元素是否相同
  114. {
  115. if (board[i][i] != board[0][0] || board[i][i] == ' ')
  116. {
  117. flag = 0;
  118. break;
  119. }
  120. }
  121. if (flag == 1)
  122. {
  123. return board[0][0];
  124. }
  125. flag = 1;
  126. for (i = 0, j = col - 1; i < row; i++, j--)//判断副对角线元素是否相同
  127. {
  128. if (board[i][j] != board[0][col - 1] || board[i][j] == ' ')
  129. {
  130. flag = 0;
  131. break;
  132. }
  133. }
  134. if (flag == 1)
  135. {
  136. return board[0][col - 1];
  137. }
  138. //平局
  139. for (int i = 0; i < row; i++)
  140. {
  141. for (int j = 0; j < col; j++)
  142. {
  143. if (board[i][j] == ' ')
  144. {
  145. //还有未下棋的坐标,游戏继续
  146. return 'C';
  147. }
  148. }
  149. }
  150. return 'Q';
  151. }
  152. //电脑下棋
  153. void ComputerMove(char board[ROW][COL], int row, int col)
  154. {
  155. int x = 0;
  156. int y = 0;
  157. printf("电脑下棋:>\n");
  158. while (1)
  159. {
  160. x = rand() % row;
  161. y = rand() % col;
  162. if (board[x][y] == ' ')
  163. {
  164. board[x][y] = '#';
  165. break;
  166. }
  167. }
  168. }

test.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. //打印菜单
  4. void menu()
  5. {
  6. printf("***************************\n");
  7. printf("*********1. play **********\n");
  8. printf("*********0. exit **********\n");
  9. printf("***************************\n");
  10. }
  11. void game()
  12. {
  13. //二维数组用于存放下棋数据
  14. char board[ROW][COL] = { 0 };
  15. //初始化棋盘
  16. InitBoard(board, ROW, COL);
  17. //打印棋盘
  18. DisplayBoard(board, ROW, COL);
  19. char ret = 0;
  20. while (1)
  21. {
  22. //玩家下棋
  23. PlayerMove(board, ROW, COL);
  24. //打印棋盘
  25. DisplayBoard(board, ROW, COL);
  26. //判断输赢
  27. ret = IsWin(board, ROW, COL);
  28. if (ret != 'C')
  29. {
  30. break;
  31. }
  32. //电脑下棋
  33. ComputerMove(board, ROW, COL);
  34. //打印棋盘
  35. DisplayBoard(board, ROW, COL);
  36. //判断输赢
  37. ret = IsWin(board, ROW, COL);
  38. if (ret != 'C')
  39. {
  40. break;
  41. }
  42. }
  43. if (ret == '*')
  44. {
  45. printf("玩家赢!\n");
  46. }
  47. else if(ret == '#')
  48. {
  49. printf("电脑赢!\n");
  50. }
  51. else
  52. {
  53. printf("平局\n");
  54. }
  55. }
  56. int main()
  57. {
  58. srand((unsigned int)time(NULL));
  59. int input = 0;
  60. while (1)
  61. {
  62. //打印菜单
  63. menu();
  64. printf("请选择:>");
  65. scanf("%d", &input);
  66. if (input == 1)
  67. {
  68. printf("三子棋游戏现在开始!\n");
  69. game();//玩游戏
  70. }
  71. else if (input == 0)
  72. {
  73. printf("游戏结束\n");
  74. break;//退出游戏
  75. }
  76. else
  77. {
  78. printf("选择错误,请重新选择\n");
  79. }
  80. }
  81. return 0;
  82. }

发表评论

表情:
评论列表 (有 0 条评论,34人围观)

还没有评论,来说两句吧...

相关阅读