小游戏系列——低配版井字棋

举报
安然无虞 发表于 2022/05/26 23:22:55 2022/05/26
【摘要】 目录   一、测试游戏逻辑 二、 封装游戏函数 1.游戏菜单 2.棋盘创建 3.初始化棋盘 4.打印棋盘 5.玩家下棋 6.电脑下棋 7.判断输赢 三、玩两把试试 1.玩家赢演示 2.电脑赢演示 3.平局 ​  四、完整代码 1.声明部分  2.定义部分 3.测试部分 ...

目录

 

一、测试游戏逻辑

二、 封装游戏函数

1.游戏菜单

2.棋盘创建

3.初始化棋盘

4.打印棋盘

5.玩家下棋

6.电脑下棋

7.判断输赢

三、玩两把试试

1.玩家赢演示

2.电脑赢演示

3.平局

​ 

四、完整代码

1.声明部分

 2.定义部分

3.测试部分

五、结语 


【前言】:

经过一定时间的学习,想必大家都有一定的基础啦,所以这里推出一款小游戏,用于巩固之前学习过的知识,加油哦。

一、测试游戏逻辑


  
  1. #include<stdio.h>
  2. void menu()
  3. {
  4. printf("*************************\n");
  5. printf("******** 1.play *********\n");
  6. printf("******** 0.exit *********\n");
  7. printf("*************************\n");
  8. }
  9. void test()
  10. {
  11. int input = 0;
  12. do
  13. {
  14. menu();
  15. printf("请选择:>");
  16. scanf("%d", &input);
  17. switch (input)
  18. {
  19. case 1:
  20. printf("三子棋\n");
  21. break;
  22. case 0:
  23. printf("退出游戏\n");
  24. break;
  25. default:
  26. printf("选择错误,请重新选择\n");
  27. break;
  28. }
  29. } while (input);
  30. }
  31. int main()
  32. {
  33. test();
  34. return 0;
  35. }

经过测试发现以上代码逻辑没有问题,我们只需要将“三子棋”那块内容封装成函数即可。

二、 封装游戏函数

先简单看一下封装后运行效果:

 哈哈,看起来还不错哦,那来看看具体步骤吧...

1.游戏菜单

选择1:玩游戏;

选择0:结束

代码执行:


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

2.棋盘创建

由于是三子棋,所以棋盘肯定就是3行3列,我们可以选择二维字符数组来表示。


  
  1. #define ROW 3
  2. #define COL 3
  3. char board[ROW][COL] = { 0 };

【敲黑板】:之所以选择宏定义的方式,有两点原因:

一是方便程序的修改;

二可以提高程序的可读性

3.初始化棋盘

代码执行:


  
  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. }

刚开始将棋盘内容全部初始化为空格

4.打印棋盘

【敲黑板】:打印棋盘这块内容比较难想哦,所以要格外注意一下。

代码执行:


  
  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. {
  13. printf("|");
  14. }
  15. }
  16. printf("\n");
  17. //分割行
  18. if (i < row - 1)
  19. {
  20. for (j = 0; j < col; j++)
  21. {
  22. printf("---");
  23. if (j < col - 1)
  24. {
  25. printf("|");
  26. }
  27. }
  28. }
  29. printf("\n");
  30. }
  31. }

运行效果:

5.玩家下棋

代码执行:


  
  1. void player_move(char board[ROW][COL], int row, int col)
  2. {
  3. printf("玩家下棋:>");
  4. int x = 0;
  5. int y = 0;
  6. while (1)
  7. {
  8. scanf("%d %d", &x, &y);
  9. //判断坐标是否合法
  10. if (x >= 1 && x <= row && y >= 1 && y <= col)
  11. {
  12. //坐标-1,以及坐标合法性的判断都是非常重要的
  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;

二是要判断坐标的合法性,是否被占用,是否合法

6.电脑下棋

代码执行:


  
  1. void computer_move(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. x = rand() % ROW;//0~2--->所以不用判断合法性了
  9. y = rand() % COL;//0~2
  10. if (board[x][y] == ' ')
  11. {
  12. board[x][y] = '#';
  13. break;
  14. }
  15. }
  16. }

【注意】:因为行列已经指定0~2范围了,所以电脑下棋这部分就不用判断合法性了

但是要在test函数中使用srand((unsigned int)time(NULL));将时间作为随机数种子,确保得到的行列坐标真随机值。这个在上篇关于猜数字的游戏中详细讲解过,所以在这里就不过多赘述了。

7.判断输赢

这里我们规定一下:

//玩家赢 - 返回'*'
//电脑赢 - 返回'#
//平局 - 返回'Q'
//继续 - 返回'C'

代码执行:


  
  1. char is_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][1] != ' ')
  8. {
  9. return board[i][1];
  10. }
  11. }
  12. //判断三列
  13. for (i = 0; i < col; i++)
  14. {
  15. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
  16. {
  17. return board[1][i];
  18. }
  19. }
  20. //判断对角线
  21. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
  22. {
  23. return board[1][1];
  24. }
  25. if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
  26. {
  27. return board[1][1];
  28. }
  29. //判断平局
  30. if (1 == is_full(board, row, col))
  31. {
  32. return 'Q';
  33. }
  34. else
  35. {
  36. return 'C';
  37. }
  38. }

当然这里面还调用了一个判断平局的函数,因为判断平局是一个特定的功能,在后面还可能遇到,随意在这里特意将它封装成一个函数。


  
  1. int is_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. {
  11. return 0;
  12. }
  13. }
  14. }
  15. return 1;
  16. }

三、玩两把试试

1.玩家赢演示

2.电脑赢演示

3.平局

四、完整代码

这个小游戏是按照项目工程来写的,分为声明、定义和测试。

1.声明部分


  
  1. //此处需要自己定义一个头文件:game.h
  2. #pragma once
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<time.h>
  6. #define ROW 3
  7. #define COL 3
  8. //初始化棋盘
  9. void InitBoard(char board[ROW][COL], int row, int col);
  10. //打印棋盘
  11. void DisplayBoard(char board[ROW][COL], int row, int col);
  12. //玩家下棋
  13. void player_move(char board[ROW][COL], int row, int col);
  14. //电脑下棋
  15. void computer_move(char board[ROW][COL], int row, int col);
  16. //判断输赢
  17. char is_win(char board[ROW][COL], int row, int col);

 2.定义部分


  
  1. //此处需要自己定义一个源文件:game.c
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include"game.h"
  4. void InitBoard(char board[ROW][COL], int row, int col)
  5. {
  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. }
  15. }
  16. //打印函数挺重要的,注意分析哦
  17. void DisplayBoard(char board[ROW][COL], int row, int col)
  18. {
  19. int i = 0;
  20. int j = 0;
  21. for (i = 0; i < row; i++)
  22. {
  23. //数据
  24. for (j = 0; j < col; j++)
  25. {
  26. printf(" %c ", board[i][j]);
  27. if (j < col - 1)
  28. {
  29. printf("|");
  30. }
  31. }
  32. printf("\n");
  33. //分割行
  34. if (i < row - 1)
  35. {
  36. for (j = 0; j < col; j++)
  37. {
  38. printf("---");
  39. if (j < col - 1)
  40. {
  41. printf("|");
  42. }
  43. }
  44. }
  45. printf("\n");
  46. }
  47. }
  48. void player_move(char board[ROW][COL], int row, int col)
  49. {
  50. printf("玩家下棋:>");
  51. int x = 0;
  52. int y = 0;
  53. while (1)
  54. {
  55. scanf("%d %d", &x, &y);
  56. //判断坐标是否合法
  57. if (x >= 1 && x <= row && y >= 1 && y <= col)
  58. {
  59. //坐标-1,以及坐标合法性的判断都是非常重要的
  60. if (board[x - 1][y - 1] == ' ')
  61. {
  62. board[x - 1][y - 1] = '*';
  63. break;
  64. }
  65. else
  66. {
  67. printf("该坐标被占用,请重新输入\n");
  68. }
  69. }
  70. else
  71. {
  72. printf("坐标非法,请重新输入\n");
  73. }
  74. }
  75. }
  76. void computer_move(char board[ROW][COL], int row, int col)
  77. {
  78. int x = 0;
  79. int y = 0;
  80. printf("电脑下棋:>\n");
  81. while (1)
  82. {
  83. x = rand() % ROW;//0~2--->所以不用判断合法性了
  84. y = rand() % COL;//0~2
  85. if (board[x][y] == ' ')
  86. {
  87. board[x][y] = '#';
  88. break;
  89. }
  90. }
  91. }
  92. //判断棋盘满了没(平局)
  93. int is_full(char board[ROW][COL], int row, int col)
  94. {
  95. int i = 0;
  96. int j = 0;
  97. for (i = 0; i < row; i++)
  98. {
  99. for (j = 0; j < col; j++)
  100. {
  101. if (board[i][j] == ' ')
  102. {
  103. return 0;
  104. }
  105. }
  106. }
  107. return 1;
  108. }
  109. char is_win(char board[ROW][COL], int row, int col)
  110. {
  111. int i = 0;
  112. //判断三行
  113. for (i = 0; i < row; i++)
  114. {
  115. if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
  116. {
  117. return board[i][1];
  118. }
  119. }
  120. //判断三列
  121. for (i = 0; i < col; i++)
  122. {
  123. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
  124. {
  125. return board[1][i];
  126. }
  127. }
  128. //判断对角线
  129. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
  130. {
  131. return board[1][1];
  132. }
  133. if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
  134. {
  135. return board[1][1];
  136. }
  137. //判断平局
  138. if (1 == is_full(board, row, col))
  139. {
  140. return 'Q';
  141. }
  142. else
  143. {
  144. return 'C';
  145. }
  146. }

3.测试部分


  
  1. //此处需要自己定义一个源文件:test.c
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include"game.h"
  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. //下棋
  20. char ret = 0;
  21. while (1)
  22. {
  23. player_move(board, ROW, COL);
  24. DisplayBoard(board, ROW, COL);
  25. ret = is_win(board, ROW, COL);
  26. if (ret != 'C')
  27. {
  28. break;
  29. }
  30. computer_move(board, ROW, COL);
  31. DisplayBoard(board, ROW, COL);
  32. ret = is_win(board, ROW, COL);
  33. if (ret != 'C')
  34. {
  35. break;
  36. }
  37. }
  38. if (ret == '*')
  39. {
  40. printf("玩家赢\n");
  41. }
  42. else if (ret == '#')
  43. {
  44. printf("电脑赢\n");
  45. }
  46. else
  47. {
  48. printf("平局\n");
  49. }
  50. }
  51. void test()
  52. {
  53. int input = 0;
  54. srand((unsigned int)time(NULL));
  55. do
  56. {
  57. menu();
  58. printf("请选择(0/1):>");
  59. scanf("%d", &input);
  60. switch (input)
  61. {
  62. case 1:
  63. game();
  64. break;
  65. case 0:
  66. printf("退出游戏\n");
  67. break;
  68. default:
  69. printf("选择错误,请重新选择\n");
  70. break;
  71. }
  72. } while (input);
  73. }
  74. int main()
  75. {
  76. test();
  77. return 0;
  78. }

也就像下面这样:

五、结语 

感兴趣的小伙伴可以自己实现哦,笔者的编译器选择的是VS2019,这里暂时就没有对界面进行设置,等到后期发一些小游戏的时候搞一波好看点的界面,嘿嘿,那就这样哈,加油哦。

文章来源: bit-runout.blog.csdn.net,作者:安然无虞,版权归原作者所有,如需转载,请联系作者。

原文链接:bit-runout.blog.csdn.net/article/details/121211801

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。