当前位置:   article > 正文

五子棋(C语言实现)_c语言五子棋代码

c语言五子棋代码

目录

构思

1、主程序

2、初始化

3、游戏菜单

4、打印棋盘

6、玩家下棋

7、判断输赢

 8、功能整合

人机下棋

完整版: 

game.h

game.c

text.c

 测试功能代码


构思

五子棋不必多介绍了,大家小时候都玩过哈。

我们要通过程序实现这个小游戏,大体上的构思得有:

游戏流程:运行游戏>>打印棋盘>>下棋>>判断输赢

由此,我们声明如下函数、棋盘数组和回合数 (用于双人下棋时下不同棋子的判断)。

将这些都放在我创建的头文件game.h中方便其他文件使用: 

  1. #include <stdio.h>
  2. #include <Windows.h>
  3. int map[19][19];//棋盘
  4. int flag;//回合数
  5. //初始化棋盘
  6. void init();
  7. //游戏菜单
  8. void menuView();
  9. //打印棋盘
  10. void gameView_ShowMap();
  11. //玩家下棋
  12. int playerMove(int x, int y);
  13. //判断输赢
  14. int isWin(int x, int y);
  15. //判断输赢
  16. void winView();

1、主程序

先进行游戏下棋,后进行判断输赢,比较符合do—while的特点。 

  1. int main()
  2. {
  3. int input = 0;
  4. do
  5. {
  6. menuView();
  7. printf("请选择:");
  8. scanf("%d", &input);
  9. switch (input) {
  10. case 1:
  11. gameView();
  12. break;
  13. case 0:
  14. printf("退出游戏\n");
  15. break;
  16. default:
  17. printf("输入错误,请重新选择.\n");
  18. break;
  19. }
  20. } while (input);
  21. return 0;
  22. }
  • 首先打印菜单,提示玩家进行选择开始游戏。
  • 通过输入变量input的值,判断是否进行游戏,
  • 值为1则调用gameView函数进行游戏,0则结束游戏。
  • gameView函数对各种功能函数进行整合。

在此之前先将各种功能函数进行实现,最后将它们放入gameView整合。 

2、初始化

  1. void init() {
  2. for (int i = 0; i < 19; i++) {
  3. for (int j = 0; j < 19; j++) {
  4. map[i][j] = 0;
  5. }
  6. }
  7. flag = 0;
  8. }
  • 将棋盘每个格子初始化为0。
  • 回合数初始化为0。

3、游戏菜单

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

4、打印棋盘

这里我选择设计了棋盘格和横纵坐标,我们可以根据需要自行设计。 

  1. void gameView_ShowMap() {
  2. int i, j;
  3. printf(" ");
  4. for (i = 0; i < 19; i++) {//打印横坐标
  5. printf("%3d ",i);
  6. }
  7. printf("\n ");
  8. for (i = 0; i < 19; i++) {
  9. printf("+---");
  10. }
  11. printf("+\n");
  12. for (i = 0; i < 19; i++) {
  13. printf("%2d |", i);//每行输出前都先打印纵坐标
  14. for (j = 0; j < 19; j++) {
  15. printf(" %d ", map[i][j]);//打印棋子
  16. if (j < 18)
  17. printf("|");
  18. }
  19. printf("|\n");
  20. if(i<18)
  21. printf(" |");
  22. if(i==18)
  23. printf(" +");
  24. for (j = 0; j < 19; j++) {
  25. printf("---");
  26. if (j < 18)
  27. printf("+");
  28. }
  29. printf("+\n");
  30. }
  31. }

效果如下: 

6、玩家下棋

  1. int playerMove(int x, int y) {
  2. if (x >= 0 && x < 19 && y >= 0 && y < 19) {
  3. if (map[x][y] == 0) {
  4. if (flag % 2 == 0)
  5. map[x][y] = 1;//下黑子
  6. else
  7. map[x][y] = 2;//下白子
  8. //落子成功
  9. return 1;
  10. }
  11. else {
  12. //该位置已有棋子
  13. return 0;
  14. }
  15. }
  16. else {
  17. //坐标不合法
  18. return -1;
  19. }
  20. }
  • 首先判断下棋位置是否在棋盘0到18的横纵坐标内,如果不在函数返回值-1,
  • 如果在棋盘内,则进行下棋。
  • 棋盘每个格子初始值为0,判断当前格子的值为0才可以下棋,否则返回值为0。
  • 回合数flag初始值为0,当flag为偶数下黑子>>1,奇数下白子>>2,成功下棋返回值为1。

7、判断输赢

  1. int isWin(int x, int y) {
  2. int i, j;
  3. for (i = 0; i < 19; i++) {
  4. for (j = 0; j < 19; j++) {
  5. if (map[i][j] == 0) {
  6. continue;
  7. }
  8. //横着连成五子
  9. if (j < 15)
  10. if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]
  11. && map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])
  12. return map[i][j];
  13. //竖着连成五子
  14. if (i < 15)
  15. if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]
  16. && map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])
  17. return map[i][j];
  18. //左斜着连成五子-> " \ "
  19. if (i < 15 && j < 15)
  20. if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]
  21. && map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])
  22. return map[i][j];
  23. //右斜着连成五子-> " / "
  24. if (i < 15 && j > 4)
  25. if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]
  26. && map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])
  27. return map[i][j];
  28. }
  29. }
  30. return 0;
  31. }
  • i < 15 用于确保在检查垂直和左斜方向的连续五子时,起始位置 (i, j) 之后至少还有4个位置。因为五子连成一线需要五个连续的位置,所以确保从当前位置开始往下检查的时候不会超出数组的边界。

  • j < 15 用于确保在检查水平和左斜方向的连续五子时,起始位置 (i, j) 之后至少还有4个位置。同样,这是为了确保从当前位置开始往右检查的时候不会超出数组的边界。

  • j > 4 用于确保在检查右斜方向的连续五子时,起始位置 (i, j) 之前至少还有4个位置。这是为了确保从当前位置开始往左检查的时候不会超出数组的边界。

 8、功能整合

  1. void gameView()
  2. {
  3. init();
  4. int x = 0, y = 0;
  5. int ret = 0;//辅助判断坐标是否合法
  6. while (1) {
  7. gameView_ShowMap();
  8. printf("请输入要下棋的坐标:");
  9. scanf("%d %d", &x, &y);
  10. if (playerMove(x, y) == 0) {
  11. printf("\n!!!该坐标已被占用!!!\n");
  12. Sleep(2000);
  13. continue;
  14. }
  15. else if (playerMove(x, y) == -1) {
  16. printf("\n!!!请输入合法坐标!!!\n");
  17. Sleep(2000);
  18. continue;
  19. }
  20. else {
  21. flag++;//切换回合
  22. }
  23. if (isWin(x, y) == 0) {
  24. continue;
  25. }
  26. else if (isWin(x, y) == 1) {
  27. printf("黑子获胜\n");
  28. break;
  29. }
  30. else if (isWin(x, y) == 2) {
  31. printf("白子获胜\n");
  32. break;
  33. }
  34. }
  35. }
  •  这里的Sleep函数需要头文件#include <Windows.h>,使用该函数暂停两秒,防止continue后下次循环打印的棋盘将提示信息挡住。
  • 下棋坐标不合法打印提示信息后,进入下次循环重新输入。
  • 成功下棋则flag自增,切换回合。
  • 每次下棋后都要判断输赢,有人赢了则停止循环,否则继续下棋。
  • (其实应该从下棋次数第五次开始判断输赢更合理,读者可以自行添加判断)

人机下棋

想要实现人机下棋可以看看我这篇文章《三子棋》 ,里面实现了人机下棋,读者可以自行模仿改进,实现其功能的重要函数可以在这篇文章中学习 rand&srand函数 。 

完整版: 

game.h

  1. #include <stdio.h>
  2. #include <Windows.h>
  3. int map[19][19];//棋盘
  4. int flag;//回合数
  5. //初始化
  6. void init();
  7. //游戏菜单
  8. void menuView();
  9. //打印棋盘
  10. void gameView_ShowMap();
  11. //玩家下棋
  12. int playerMove(int x, int y);
  13. //判断输赢
  14. int isWin(int x, int y);

game.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. void init() {
  4. for (int i = 0; i < 19; i++) {
  5. for (int j = 0; j < 19; j++) {
  6. map[i][j] = 0;
  7. }
  8. }
  9. flag = 1;
  10. }
  11. int isWin(int x, int y) {
  12. int i, j;
  13. for (i = 0; i < 19; i++) {
  14. for (j = 0; j < 19; j++) {
  15. if (map[i][j] == 0) {
  16. continue;
  17. }
  18. //横着连成五子
  19. if (j < 15)
  20. if (map[i][j] == map[i][j + 1] && map[i][j] == map[i][j + 2]
  21. && map[i][j] == map[i][j + 3] && map[i][j] == map[i][j + 4])
  22. return map[i][j];
  23. //竖着连成五子
  24. if (i < 15)
  25. if (map[i][j] == map[i + 1][j] && map[i][j] == map[i + 2][j]
  26. && map[i][j] == map[i + 3][j] && map[i][j] == map[i + 4][j])
  27. return map[i][j];
  28. //左斜着连成五子-> " \ "
  29. if (i < 15 && j < 15)
  30. if (map[i][j] == map[i + 1][j + 1] && map[i][j] == map[i + 2][j + 2]
  31. && map[i][j] == map[i + 3][j + 3] && map[i][j] == map[i + 4][j + 4])
  32. return map[i][j];
  33. //右斜着连成五子-> " / "
  34. if (i < 15 && j > 4)
  35. if (map[i][j] == map[i + 1][j - 1] && map[i][j] == map[i + 2][j - 2]
  36. && map[i][j] == map[i + 3][j - 3] && map[i][j] == map[i + 4][j - 4])
  37. return map[i][j];
  38. }
  39. }
  40. return 0;
  41. }
  42. int playerMove(int x, int y) {
  43. if (x >= 0 && x < 19 && y >= 0 && y < 19) {
  44. if (map[x][y] == 0) {
  45. if (flag % 2 == 0)
  46. map[x][y] = 1;//下黑子
  47. else
  48. map[x][y] = 2;//下白子
  49. //落子成功
  50. return 1;
  51. }
  52. else {
  53. //该位置已有棋子
  54. return 0;
  55. }
  56. }
  57. else {
  58. //坐标不合法
  59. return -1;
  60. }
  61. }
  62. void menuView() {
  63. printf("*************************\n");
  64. printf("***** 1. play ******\n");
  65. printf("***** 0. exit ******\n");
  66. printf("*************************\n");
  67. }
  68. void gameView_ShowMap() {
  69. int i, j;
  70. printf(" ");
  71. for (i = 0; i < 19; i++) {//打印横坐标
  72. printf("%3d ",i);
  73. }
  74. printf("\n ");
  75. for (i = 0; i < 19; i++) {
  76. printf("+---");
  77. }
  78. printf("+\n");
  79. for (i = 0; i < 19; i++) {
  80. printf("%2d |", i);//每行输出前先都打印纵坐标
  81. for (j = 0; j < 19; j++) {
  82. printf(" %d ", map[i][j]);
  83. if (j < 18)
  84. printf("|");
  85. }
  86. printf("|\n");
  87. if(i<18)
  88. printf(" |");
  89. if(i==18)
  90. printf(" +");
  91. for (j = 0; j < 19; j++) {
  92. printf("---");
  93. if (j < 18)
  94. printf("+");
  95. }
  96. printf("+\n");
  97. }
  98. }

text.c

  1. #define _CRT_SECURE_NO_WARNINGS 1
  2. #include "game.h"
  3. void gameView()
  4. {
  5. init();
  6. int x = 0, y = 0;
  7. int ret = 0;//辅助判断坐标是否合法
  8. while (1) {
  9. gameView_ShowMap();
  10. printf("请输入要下棋的坐标:");
  11. scanf("%d %d", &x, &y);
  12. if (playerMove(x, y) == 0) {
  13. printf("\n!!!该坐标已被占用!!!\n");
  14. Sleep(2000);
  15. continue;
  16. }
  17. else if (playerMove(x, y) == -1) {
  18. printf("\n!!!请输入合法坐标!!!\n");
  19. Sleep(2000);
  20. continue;
  21. }
  22. else {
  23. flag++;//切换回合
  24. }
  25. if (isWin(x, y) == 0) {
  26. continue;
  27. }
  28. else if (isWin(x, y) == 1) {
  29. printf("黑子获胜\n");
  30. break;
  31. }
  32. else if (isWin(x, y) == 2) {
  33. printf("白子获胜\n");
  34. break;
  35. }
  36. }
  37. }
  38. int main()
  39. {
  40. int input = 0;
  41. do
  42. {
  43. menuView();
  44. printf("请选择:");
  45. scanf("%d", &input);
  46. switch (input) {
  47. case 1:
  48. gameView();
  49. break;
  50. case 0:
  51. printf("退出游戏\n");
  52. break;
  53. default:
  54. printf("输入错误,请重新选择.\n");
  55. break;
  56. }
  57. } while (input);
  58. return 0;
  59. }

 测试功能代码

此代码可以替换int main主函数,用于测试函数功能是否正确,可以减少自行下棋测试时间 

成功运行输出如下:

  1. int main()
  2. {
  3. int testflag = 0;
  4. //init测试代码
  5. init();
  6. if (flag != 0) {
  7. printf("init()错误");
  8. exit(0);
  9. }
  10. for (int i = 0; i < 19; i++) {
  11. for (int j = 0; j < 19; j++) {
  12. if (map[i][j]) {
  13. printf("init()错误");
  14. exit(0);
  15. }
  16. }
  17. }
  18. printf("init()测试成功\n");
  19. testflag++;
  20. //playerMove测试代码
  21. int result = 1;
  22. result &= playerMove(2, 2);
  23. result &= playerMove(2, 3);
  24. result &= playerMove(2, 4);
  25. result &= playerMove(2, 5);
  26. if (result != 1 || (map[2][2] && map[2][3] && map[2][4] && map[2][5]) != 1) {
  27. printf("playerMove()错误");
  28. exit(0);
  29. }
  30. flag = 1;
  31. result &= playerMove(2, 5);
  32. if (result != 0 || map[2][5] != 1) {
  33. printf("playerMove()错误");
  34. exit(0);
  35. }
  36. printf("playerMove()测试成功\n");
  37. testflag++;
  38. //isWin测试代码
  39. playerMove(2, 1);
  40. if (isWin(2, 1)) {
  41. printf("isWin()错误");
  42. exit(0);
  43. }
  44. playerMove(1, 0);
  45. playerMove(3, 2);
  46. playerMove(4, 3);
  47. playerMove(5, 4);
  48. if (isWin(1, 0) != 2) {
  49. printf("isWin()错误");
  50. exit(0);
  51. }
  52. printf("isWin()测试成功\n");
  53. testflag++;
  54. if (testflag == 3) {
  55. printf("service代码测试成功\n");
  56. }
  57. return 0;
  58. }

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

闽ICP备14008679号