• c语言入门——三子棋(N子棋)


    目录

    前言

    一.什么是三子棋?

    二.三子棋(N子棋)设计思路

    1.主函数

    2.数组的初始化

    3.菜单

    4.游戏主体

    (1).棋盘

     (2).下棋

    (3).判断胜负

    三.最终代码

    源文件1

    源文件2

    头文件


    前言

    在了解了二维数组之后,我们便可以完成我们的第二个游戏——三子棋(N子棋)



    一.什么是三子棋?

    三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。



    二.三子棋(N子棋)设计思路

    1.主函数

    设计一切程序的开始,都要确立好主函数。

    而N子棋本质上便是一个行为N、列为N的二维函数。

    由于二维数组的行和列只能为常量表达式,所以我们选择在头文件中用“#define“”定义全局变量N作为二维数组的行和列。

    以下程序的撰写皆以三子棋为例

    如此我们便初步得到了一个主函数

    1. int main()
    2. {
    3. char arr[N][N];
    4. return 0;
    5. }

    为保证主函数的简便,我们将其他部分打包为自定义函数。


    2.数组的初始化

    为了使游戏更加整洁,我们选择将数组所有元素初始化为‘ ’

    1. void new(char arr[N][N])
    2. {
    3. int i,j;
    4. for(i=0;i<N;i++)
    5. {
    6. for(j=0;j<N;j++)
    7. {
    8. arr[i][j]=' ';
    9. }
    10. }
    11. }
    1. int main()
    2. {
    3. char arr[N][N];
    4. new(arr);
    5. return 0;
    6. }

    3.菜单

    首先游戏需要有一个菜单供玩家选择游玩

    由于这是一个简单的游戏,所以我们可以设置开始游戏与退出两个选项。

    1. int menu()
    2. {
    3. int input=0;
    4. printf("1——开始游戏 2——退出\n");
    5. printf("请选择=>");
    6. scanf("%d",&input);
    7. if(input==1)
    8. {
    9. printf("加载中---\n");
    10. sleep(1);
    11. return 1;
    12. }
    13. else if(input==2)
    14. printf("正在退出\n");
    15. else
    16. printf("输入错误,请重新输入\n");
    17. }

    在这里我们自定义了一个具有返回值的函数menu(),而这个返回值将决定游戏的运行

    由上述代码可知,当返回值为1时开始游戏

    4.游戏主体

    首先先将自定义函数game(arr)作为游戏主体放置在主函数中

    1. int main()
    2. {
    3. char arr[N][N];
    4. new(arr);
    5. if(menu()==1)
    6. {
    7. game(arr);
    8. }
    9. return 0;
    10. }

    (1).棋盘

    在开始下棋之前,我们需要有一个棋盘来让我们更加直观的观看下棋的过程

    1. void list(char arr[N][N])
    2. {
    3. int i,j;
    4. for(i=0;i<N;i++)
    5. {
    6. for(j=0;j<N;j++)
    7. {
    8. if(j<N-1)
    9. printf(" %c |",arr[i][j]);
    10. else if(j==N-1&&i!=N-1)
    11. {
    12. printf(" %c \n",arr[i][j]);
    13. for(j=0;j<N;j++)
    14. {
    15. if(j<N-1)
    16. printf("---|");
    17. else
    18. printf("---\n");
    19. }
    20. }
    21. else
    22. printf(" %c \n",arr[i][j]);
    23. }
    24. }
    25. }

    这样我们便可以得到一个这样的棋盘

    随着二维数组的改变,这个棋盘也会不断变化,所以我们需要多次引用这个自定义函数

     (2).下棋

    首先,我们将我们下一步棋(选用O)与电脑下一步棋(选用X)算作一个整体

    我们便可以以这个整体作循环来完成下棋这一过程

    a.自己下棋

    首先我们先写出一个基础的主体

    1. int x,y;
    2. printf("请输入坐标=>");
    3. scanf("%d%d",&x,&y);
    4. arr[x-1][y-1]='O';

    之后我们便可以为此加“亿点点”细节

    首先为了避免在已经下过棋子的位置上重复下棋,或者为了避免输入的坐标不合法(超出数组范围),我们都可以使用分支与循环函数。

    而为了美观和便利,我们可以选择使用清屏函数——system("cls")和上面讲到的list(arr)函数。

    1. while(1)
    2. {
    3. system("cls");
    4. list(arr);
    5. int x,y;
    6. printf("请输入坐标=>");
    7. scanf("%d%d",&x,&y);
    8. if(x>0&&x<=N&&y>0&&y<=N)
    9. {
    10. if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
    11. {
    12. arr[x-1][y-1]='O';
    13. break;
    14. }
    15. else
    16. printf("该位置存在棋子,请重新输入\n");
    17. }
    18. else
    19. printf("不存在该坐标,请重新输入\n");
    20. }

    这样我们自己下一步棋的代码便初步完成了。

    b.电脑下棋

    想要让电脑在任意空位置下棋(在数组中为任意一个为‘ ’的元素赋值为‘X’),我们要运用到之前在猜数字游戏中学习到的随机数。

    而想要让随机值在一次游戏中顺序不变,我们选择将srand()函数放置在主函数中。

    1. int main()
    2. {
    3. srand((unsigned int) time(NULL));
    4. char arr[N][N];
    5. new(arr);
    6. if(menu()==1)
    7. {
    8. game(arr);
    9. }
    10. return 0;
    11. }
    1. while(1)
    2. {
    3. int a,b;
    4. a=rand()%N;//使随机值范围在数组范围之内
    5. b=rand()%N;//使随机值范围在数组范围之内
    6. if(arr[a][b]!='O'&&arr[a][b]!='X')
    7. {
    8. printf("电脑思考中---\n");
    9. sleep(2);
    10. arr[a][b]='X';
    11. list(arr);
    12. break;
    13. }
    14. }

    而sleep()函数与list()函数也是让程序更加美观便利。

    c.整合

    在完成上述两方的下棋后,我们便可以将其整合

    1. while(1)
    2. {
    3. while(1)
    4. {
    5. system("cls");
    6. list(arr);
    7. int x,y;
    8. printf("请输入坐标=>");
    9. scanf("%d%d",&x,&y);
    10. if(x>0&&x<=N&&y>0&&y<=N)
    11. {
    12. if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
    13. {
    14. arr[x-1][y-1]='O';
    15. count++;
    16. break;
    17. }
    18. else
    19. printf("该位置存在棋子,请重新输入\n");
    20. }
    21. else
    22. printf("不存在该坐标,请重新输入\n");
    23. }
    24. while(1)
    25. {
    26. int a,b;
    27. a=rand()%N;
    28. b=rand()%N;
    29. if(arr[a][b]!='O'&&arr[a][b]!='X')
    30. {
    31. printf("电脑思考中---\n");
    32. sleep(2);
    33. arr[a][b]='X';
    34. count++;
    35. list(arr);
    36. break;
    37. }
    38. }
    39. }

    上述代码是自动选择玩家先手,我们也可以通过分支语句来让玩家选择先手情况,这里就不再多做赘述。

    (3).判断胜负

    当我们完成上述代码后,在一定程度上便可以开始游玩,但我们还需要判断游戏的胜负来终止这一次的游戏。

    而这种判断,应该在每一步棋子下完之后就进行一次。

    胜负应该如何判断呢?

    我们知道,三子棋胜负有三种判断方式——横向连一行、纵向连一列或者对角线连成一排

    所以我们要通过三次不同的判断来完成胜负的判断

    在这里,我选用的是通过count变量,当一排数组内存在‘O’或‘X’,我们将count “+1”或“-1”,这样当count=3或-3时,便能判断出胜负

    1. int end(char arr[N][N])
    2. {
    3. int count_1=0,count_2=0,count_3=0;
    4. int i,j;
    5. for(i=0;i<N;i++)
    6. {
    7. count_1=0;
    8. for(j=0;j<N;j++)
    9. {
    10. if (arr[i][j]=='O')
    11. count_1++;
    12. else if(arr[i][j]=='X')
    13. count_1--;
    14. }
    15. if (count_1==N||count_1==-N)
    16. break;
    17. }
    18. int a,b;
    19. for(a=0;a<N;a++)
    20. {
    21. count_2=0;
    22. for(b=0;b<N;b++)
    23. {
    24. if (arr[b][a]=='O')
    25. count_2++;
    26. else if(arr[b][a]=='X')
    27. count_2--;
    28. }
    29. if (count_2==N||count_2==-N)
    30. break;
    31. }
    32. int c,d;
    33. for(c=0,d=0;c<N&&d<N;c++,d++)
    34. {
    35. if (arr[c][d]=='O')
    36. count_3++;
    37. else if(arr[c][d]=='X')
    38. count_3--;
    39. }
    40. if((count_1==N||count_2==N)||count_3==N)
    41. {
    42. printf("胜利");
    43. return 1;
    44. }
    45. else if((count_1==-N||count_2==-N)||count_3==-N)
    46. {
    47. printf("失败");
    48. return 1;
    49. }
    50. }

    当然游戏不只是胜负,还存在平局的情况

    三子棋平局时便是将棋盘填满

    我们选择变量count,在下每一步棋时,我们将count+1,当变量等于9时,若没有判断出胜负,便是平局的情况。

    1. int end(char arr[N][N],int count)
    2. {
    3. int count_1=0,count_2=0,count_3=0;
    4. int i,j;
    5. for(i=0;i<N;i++)
    6. {
    7. count_1=0;
    8. for(j=0;j<N;j++)
    9. {
    10. if (arr[i][j]=='O')
    11. count_1++;
    12. else if(arr[i][j]=='X')
    13. count_1--;
    14. }
    15. if (count_1==N||count_1==-N)
    16. break;
    17. }
    18. int a,b;
    19. for(a=0;a<N;a++)
    20. {
    21. count_2=0;
    22. for(b=0;b<N;b++)
    23. {
    24. if (arr[b][a]=='O')
    25. count_2++;
    26. else if(arr[b][a]=='X')
    27. count_2--;
    28. }
    29. if (count_2==N||count_2==-N)
    30. break;
    31. }
    32. int c,d;
    33. for(c=0,d=0;c<N&&d<N;c++,d++)
    34. {
    35. if (arr[c][d]=='O')
    36. count_3++;
    37. else if(arr[c][d]=='X')
    38. count_3--;
    39. }
    40. if(count<N*N)
    41. {
    42. if((count_1==N||count_2==N)||count_3==N)
    43. {
    44. printf("胜利");
    45. return 1;
    46. }
    47. else if((count_1==-N||count_2==-N)||count_3==-N)
    48. {
    49. printf("失败");
    50. return 1;
    51. }
    52. else
    53. return 2;
    54. }
    55. else
    56. {
    57. printf("平局");
    58. return 1;
    59. }
    60. }

    这样,我们便可以将这件代码组合在一起,完成程序的设计



    三.最终代码

    源文件1

    1. #include <stdio.h>
    2. #include"mean.h"
    3. void game(char arr[N][N])
    4. {
    5. int count=0;
    6. list(arr);
    7. while(1)
    8. {
    9. while(1)
    10. {
    11. system("cls");
    12. list(arr);
    13. int x,y;
    14. printf("请输入坐标=>");
    15. scanf("%d%d",&x,&y);
    16. if(x>0&&x<=N&&y>0&&y<=N)
    17. {
    18. if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
    19. {
    20. arr[x-1][y-1]='O';
    21. count++;
    22. break;
    23. }
    24. else
    25. printf("该位置存在棋子,请重新输入\n");
    26. }
    27. else
    28. printf("不存在该坐标,请重新输入\n");
    29. }
    30. int m=0;
    31. m=end(arr,count);
    32. if(m==1)
    33. {
    34. list(arr);
    35. break;
    36. }
    37. while(1)
    38. {
    39. int a,b;
    40. a=rand()%N;
    41. b=rand()%N;
    42. if(arr[a][b]!='O'&&arr[a][b]!='X')
    43. {
    44. printf("电脑思考中---\n");
    45. sleep(2);
    46. arr[a][b]='X';
    47. count++;
    48. list(arr);
    49. break;
    50. }
    51. }
    52. m=end(arr,count);
    53. if(m==1)
    54. {
    55. list(arr);
    56. break;
    57. }
    58. }
    59. }
    60. int main()
    61. {
    62. srand((unsigned int) time(NULL));
    63. char arr[N][N];
    64. new(arr);
    65. if(menu()==1)
    66. {
    67. game(arr);
    68. }
    69. return 0;
    70. }

    源文件2

    1. #include<stdio.h>
    2. #include"mean.h"
    3. int menu()
    4. {
    5. int input=0;
    6. printf("1——开始游戏 2——退出\n");
    7. printf("请选择=>");
    8. scanf("%d",&input);
    9. if(input==1)
    10. {
    11. printf("加载中---\n");
    12. sleep(1);
    13. return 1;
    14. }
    15. else if(input==2)
    16. printf("正在退出\n");
    17. else
    18. printf("输入错误,请重新输入\n");
    19. }
    20. void list(char arr[N][N])
    21. {
    22. int i,j;
    23. for(i=0;i<N;i++)
    24. {
    25. for(j=0;j<N;j++)
    26. {
    27. if(j<N-1)
    28. printf(" %c |",arr[i][j]);
    29. else if(j==N-1&&i!=N-1)
    30. {
    31. printf(" %c \n",arr[i][j]);
    32. for(j=0;j<N;j++)
    33. {
    34. if(j<N-1)
    35. printf("---|");
    36. else
    37. printf("---\n");
    38. }
    39. }
    40. else
    41. printf(" %c \n",arr[i][j]);
    42. }
    43. }
    44. }
    45. void new(char arr[N][N])
    46. {
    47. int i,j;
    48. for(i=0;i<N;i++)
    49. {
    50. for(j=0;j<N;j++)
    51. {
    52. arr[i][j]=' ';
    53. }
    54. }
    55. }
    56. int end(char arr[N][N],int count)
    57. {
    58. int count_1=0,count_2=0,count_3=0;
    59. int i,j;
    60. for(i=0;i<N;i++)
    61. {
    62. count_1=0;
    63. for(j=0;j<N;j++)
    64. {
    65. if (arr[i][j]=='O')
    66. count_1++;
    67. else if(arr[i][j]=='X')
    68. count_1--;
    69. }
    70. if (count_1==N||count_1==-N)
    71. break;
    72. }
    73. int a,b;
    74. for(a=0;a<N;a++)
    75. {
    76. count_2=0;
    77. for(b=0;b<N;b++)
    78. {
    79. if (arr[b][a]=='O')
    80. count_2++;
    81. else if(arr[b][a]=='X')
    82. count_2--;
    83. }
    84. if (count_2==N||count_2==-N)
    85. break;
    86. }
    87. int c,d;
    88. for(c=0,d=0;c<N&&d<N;c++,d++)
    89. {
    90. if (arr[c][d]=='O')
    91. count_3++;
    92. else if(arr[c][d]=='X')
    93. count_3--;
    94. }
    95. if(count<N*N)
    96. {
    97. if((count_1==N||count_2==N)||count_3==N)
    98. {
    99. printf("胜利");
    100. return 1;
    101. }
    102. else if((count_1==-N||count_2==-N)||count_3==-N)
    103. {
    104. printf("失败");
    105. return 1;
    106. }
    107. else
    108. return 2;
    109. }
    110. else
    111. {
    112. printf("平局");
    113. return 1;
    114. }
    115. }

    头文件

    1. #define N 3
    2. void list(char arr[N][N]);
    3. int menu();
    4. void new(char arr[N][N]);
    5. int end(char arr[N][N],int count);

  • 相关阅读:
    【Android开发】学习笔记(一)
    深入剖析计算机网络和操作系统:面试必备知识解析
    VR虚拟现实:VR技术如何进行原型制作
    C++ replace,replace_if和replace_copy函数用法详解(深入了解,一文学会)
    nacos 问题
    2024第八届图像、信号处理和通信国际会议 (ICISPC 2024)即将召开!
    GPT-Chinese 复现
    Golang爬虫如何触发JavaScript代码
    flutter app开发环境搭建
    nginx下载与安装教程
  • 原文地址:https://blog.csdn.net/finish_speech/article/details/127756464