• C语言从0到1之《三子棋》的实现


    🕺作者@启明星使

    🎃专栏:《数据库》《C语言》

    🏇分享一句话:

    沉香:差一点,怎么总是差一点

    杨戬:一定是练功的时候总是差不多,到了关键的时候就是差一点

    大家一起加油🏄‍♂️🏄‍♂️🏄‍♂️

    希望得到大家的支持,如果有帮助希望得到的大家三连~~~afbae359ff6c469aa4242bd6dcb5e558.jpeg

    前言

    新手小白想学好编程,一定要注重代码实现

    所以今天我将带领大家写一个小游戏《三子棋》

    需要具备的知识有循环·数组·函数

    是不是都学过了呢?

    那么我们来动手实操检验一下成果~~~

    思路

    1. 首先我们要有个菜单,选择开始或者退出

    2. 我们要有个井字格来划分区域

    3. 我们要能下棋

    4. 电脑要和我们对局

    5. 要判断是否胜利

    具体实现

    菜单

    1. void memu() {
    2. printf("********************************\n");
    3. printf("************* 1->开始 **********\n");
    4. printf("************* 0->退出 **********\n");
    5. printf("********************************\n");
    6. printf("->");
    7. }

    这里我们用到printf打印一个界面

    接下来就要输入1或者0来选择

    是不是非常简单,我们接着往下看~

    主函数

    一个switch语句进行选择

    1. int main() {
    2. memu();
    3. srand((unsigned int)time(NULL));//电脑随机下棋,后续会有解释
    4. int input;
    5. scanf("%d", &input);
    6. switch(input) {
    7. case 0:
    8. exit(0);//强制退出程序
    9. break;
    10. case 1:
    11. game();//后续接着进入游戏
    12. break;
    13. default:
    14. printf("输入错误!");
    15. break;
    16. }
    17. }
     

    初始化数组

    我们要使用一个char型数组来存储棋子

    先将数组初始化

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

    打印界面

    我们定义一个函数专门打印界面

    打印用数组存储下的棋

    以及分割的符号

    我们定义row为行,col为列

    1. void print(char board[ROW][COL], int row, int col) {
    2. for (int i = 0; i < row; i++) {
    3. for (int j = 0; j < col; j++) {
    4. printf(" %c ", board[i][j]);
    5. if (j<col-1) {
    6. printf("|");
    7. }
    8. }
    9. printf("\n");
    10. if (i < row - 1)
    11. {
    12. for (int j = 0; j < col; j++)
    13. {
    14. printf("---");
    15. if (j < col - 1)
    16. printf("|");
    17. }
    18. printf("\n");
    19. }
    20. }
    21. }

    接下来我们就要开始下棋了

    tip:玩家为* 电脑为#

    玩家先手

    这里我们要考虑几个问题:

    1. 输入的坐标并不是数组的下标

    2. 输入坐标超过数组的界限怎么办

    1. void player_move(char board[ROW][COL], int row, int col) {
    2. while (1)
    3. {
    4. printf("请输入要下棋的坐标:>");
    5. int x = 0;
    6. int y = 0;
    7. scanf("%d %d", &x, &y);
    8. if (x >= 1 && x <= row && y >= 1 && y <= col)
    9. //在这里我们判断是否在数组内
    10. {
    11. if (board[x - 1][y - 1] == ' ')
    12. {
    13. board[x - 1][y - 1] = '*';
    14. //判断该位置为空则可以下,否则位置错误重新输入
    15. break;
    16. }
    17. else
    18. {
    19. printf("坐标错误\n");
    20. }
    21. }
    22. else
    23. //如果不在数组内则位置错误,重新输入
    24. {
    25. printf("坐标错误\n");
    26. }
    27. }
    28. }

    判断棋盘是否满了

    在对局中我们每次下棋都要判断棋盘是否满了

    如果已经满了还未分出胜负,则为平局

    1. void is_full(char board[ROW][COL], int row, int col) {
    2. int flag = 0;
    3. for (int i = 0; i < row; i++) {
    4. for (int j = 0; j < col; j++) {
    5. if (board[i][j] == ' ') {
    6. flag++;
    7. }
    8. }
    9. }
    10. if (flag == 0) {
    11. printf("平局\n");
    12. exit(0);
    13. }
    14. }

    电脑对局

    在这里我们用随机数的方式实现电脑下棋

    1. void computer_move(char board[ROW][COL], int row, int col) {
    2. printf("AI下棋:\n");
    3. while (1) {
    4. is_full(board, ROW, COL);
    5. int x = rand() % row;
    6. int y = rand() % col;
    7. //使用rand()函数
    8. //之前我们使用srand((unsigned int)time(NULL))
    9. //就是以时间来求随机数以求更随机
    10. if (board[x][y] == ' ') {
    11. board[x][y] = '#';
    12. break;
    13. }
    14. }
    15. }

    判断胜负

    三子棋的规则是什么?

    三个相同的棋在同行同列或者对角线上即为胜利

    1. char is_win(char board[ROW][COL], int row, int col) {
    2. for (int i = 0; i < row; i++)
    3. {
    4. if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
    5. {
    6. return board[i][0];
    7. }
    8. }
    9. for (int i = 0; i < col; i++)
    10. {
    11. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
    12. {
    13. return board[0][i];
    14. }
    15. }
    16. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    17. {
    18. return board[1][1];
    19. }
    20. if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    21. {
    22. return board[1][1];
    23. }
    24. is_full(board, ROW, COL);
    25. }

    这里我们返回符合条件的*或者#,在game()函数中判断返回值,即可判断胜利

    game()函数

    使用一个循环,如果有一方胜利或者平局则打破循环结束游戏

    1. void game() {
    2. char board[ROW][COL];
    3. char res = 0;
    4. Init(board, ROW, COL);
    5. print(board, ROW, COL);
    6. while (1) {
    7. player_move(board, ROW, COL);
    8. print(board, ROW, COL);
    9. is_win(board, ROW, COL);
    10. Sleep(1000);
    11. computer_move(board, ROW, COL);
    12. print(board, ROW, COL);
    13. is_win(board, ROW, COL);
    14. res= is_win(board, ROW, COL);
    15. if (res == '*') {
    16. printf("玩家胜!\n");
    17. break;
    18. }
    19. else if(res=='#') {
    20. printf("AI胜!\n");
    21. break;
    22. }
    23. }
    24. }

    总结

    在写代码的过程中,遇到问题解决问题是提升最快的方式。

    当你碰到不会的,不懂的,不要害怕,这正是你所能够进步的地方!

    我是分模块写的,源码如下:

    fun.c

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include "sanziqi.h"
    3. void memu() {
    4. printf("********************************\n");
    5. printf("************* 1->开始 **********\n");
    6. printf("************* 0->退出 **********\n");
    7. printf("********************************\n");
    8. printf("->");
    9. }
    10. void game() {
    11. char board[ROW][COL];
    12. char res = 0;
    13. Init(board, ROW, COL);
    14. print(board, ROW, COL);
    15. while (1) {
    16. player_move(board, ROW, COL);
    17. print(board, ROW, COL);
    18. is_win(board, ROW, COL);
    19. Sleep(1000);
    20. computer_move(board, ROW, COL);
    21. print(board, ROW, COL);
    22. is_win(board, ROW, COL);
    23. res= is_win(board, ROW, COL);
    24. if (res == '*') {
    25. printf("玩家胜!\n");
    26. break;
    27. }
    28. else if(res=='#') {
    29. printf("AI胜!\n");
    30. break;
    31. }
    32. }
    33. }
    34. void Init(char board[ROW][COL], int row, int col) {
    35. for (int i=0; i < row; i++) {
    36. for (int j=0; j < col; j++) {
    37. board[i][j] = ' ';
    38. }
    39. }
    40. }
    41. void print(char board[ROW][COL], int row, int col) {
    42. for (int i = 0; i < row; i++) {
    43. for (int j = 0; j < col; j++) {
    44. printf(" %c ", board[i][j]);
    45. if (j<col-1) {
    46. printf("|");
    47. }
    48. }
    49. printf("\n");
    50. if (i < row - 1)
    51. {
    52. for (int j = 0; j < col; j++)
    53. {
    54. printf("---");
    55. if (j < col - 1)
    56. printf("|");
    57. }
    58. printf("\n");
    59. }
    60. }
    61. }
    62. void player_move(char board[ROW][COL], int row, int col) {
    63. while (1)
    64. {
    65. printf("请输入要下棋的坐标:>");
    66. int x = 0;
    67. int y = 0;
    68. scanf("%d %d", &x, &y);
    69. if (x >= 1 && x <= row && y >= 1 && y <= col)
    70. {
    71. if (board[x - 1][y - 1] == ' ')
    72. {
    73. board[x - 1][y - 1] = '*';
    74. break;
    75. }
    76. else
    77. {
    78. printf("坐标错误\n");
    79. }
    80. }
    81. else
    82. {
    83. printf("坐标错误\n");
    84. }
    85. }
    86. }
    87. void computer_move(char board[ROW][COL], int row, int col) {
    88. printf("AI下棋:\n");
    89. while (1) {
    90. is_full(board, ROW, COL);
    91. int x = rand() % row;
    92. int y = rand() % col;
    93. if (board[x][y] == ' ') {
    94. board[x][y] = '#';
    95. break;
    96. }
    97. }
    98. }
    99. char is_win(char board[ROW][COL], int row, int col) {
    100. for (int i = 0; i < row; i++)
    101. {
    102. if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
    103. {
    104. return board[i][0];
    105. }
    106. }
    107. for (int i = 0; i < col; i++)
    108. {
    109. if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
    110. {
    111. return board[0][i];
    112. }
    113. }
    114. if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
    115. {
    116. return board[1][1];
    117. }
    118. if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
    119. {
    120. return board[1][1];
    121. }
    122. is_full(board, ROW, COL);
    123. }
    124. void is_full(char board[ROW][COL], int row, int col) {
    125. int flag = 0;
    126. for (int i = 0; i < row; i++) {
    127. for (int j = 0; j < col; j++) {
    128. if (board[i][j] == ' ') {
    129. flag++;
    130. }
    131. }
    132. }
    133. if (flag == 0) {
    134. printf("平局\n");
    135. exit(0);
    136. }
    137. }

    main.c

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include "sanziqi.h"
    3. int main() {
    4. memu();
    5. srand((unsigned int)time(NULL));
    6. int input;
    7. scanf("%d", &input);
    8. switch(input) {
    9. case 0:
    10. exit(0);
    11. break;
    12. case 1:
    13. game();
    14. break;
    15. default:
    16. printf("输入错误!");
    17. break;
    18. }
    19. }

    sanziqi.h

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define ROW 3
    7. #define COL 3
    8. void memu();//菜单
    9. void game();//进入游戏
    10. void Init(char board[ROW][COL], int row, int col);//初始化
    11. void print(char board[ROW][COL],int row,int col);//打印界面
    12. void player_move(char board[ROW][COL], int row, int col);//玩家下棋
    13. void computer_move(char board[ROW][COL], int row, int col);//AI下棋
    14. char is_win(char board[ROW][COL], int row, int col);//判断胜利
    15. void is_full(char board[ROW][COL], int row, int col);//判断是否填满,平局

  • 相关阅读:
    android学习笔记(四)
    实用的数据集成方式
    c++高精度乘法
    华为机试真题 Python 实现【字符串重新排列】【2022.11 Q4新题】
    Reids Cluster集群部署
    在Blazor中使用Chart.js快速创建图表
    Effective HPA:预测未来的弹性伸缩产品
    学习STM32第十八天
    (区别、详解、使用)module.exports与exports,export与export default,import 与require
    怎么架设魔兽世界服务器?
  • 原文地址:https://blog.csdn.net/m0_67759533/article/details/127754693