目录
在了解了二维数组之后,我们便可以完成我们的第二个游戏——三子棋(N子棋)
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而对方就算输了,但是三子棋在很多时候会出现和棋的局面。

设计一切程序的开始,都要确立好主函数。
而N子棋本质上便是一个行为N、列为N的二维函数。
由于二维数组的行和列只能为常量表达式,所以我们选择在头文件中用“#define“”定义全局变量N作为二维数组的行和列。
以下程序的撰写皆以三子棋为例
如此我们便初步得到了一个主函数
- int main()
- {
- char arr[N][N];
- return 0;
- }
为保证主函数的简便,我们将其他部分打包为自定义函数。
为了使游戏更加整洁,我们选择将数组所有元素初始化为‘ ’
- void new(char arr[N][N])
- {
- int i,j;
- for(i=0;i<N;i++)
- {
- for(j=0;j<N;j++)
- {
- arr[i][j]=' ';
- }
- }
- }
- int main()
- {
- char arr[N][N];
- new(arr);
- return 0;
- }
首先游戏需要有一个菜单供玩家选择游玩
由于这是一个简单的游戏,所以我们可以设置开始游戏与退出两个选项。
- int menu()
- {
- int input=0;
- printf("1——开始游戏 2——退出\n");
- printf("请选择=>");
- scanf("%d",&input);
- if(input==1)
- {
- printf("加载中---\n");
- sleep(1);
- return 1;
- }
- else if(input==2)
- printf("正在退出\n");
- else
- printf("输入错误,请重新输入\n");
- }
在这里我们自定义了一个具有返回值的函数menu(),而这个返回值将决定游戏的运行
由上述代码可知,当返回值为1时开始游戏
首先先将自定义函数game(arr)作为游戏主体放置在主函数中
- int main()
- {
- char arr[N][N];
- new(arr);
- if(menu()==1)
- {
- game(arr);
- }
- return 0;
- }
在开始下棋之前,我们需要有一个棋盘来让我们更加直观的观看下棋的过程
- void list(char arr[N][N])
- {
- int i,j;
- for(i=0;i<N;i++)
- {
- for(j=0;j<N;j++)
- {
- if(j<N-1)
- printf(" %c |",arr[i][j]);
- else if(j==N-1&&i!=N-1)
- {
- printf(" %c \n",arr[i][j]);
- for(j=0;j<N;j++)
- {
- if(j<N-1)
- printf("---|");
- else
- printf("---\n");
- }
- }
- else
- printf(" %c \n",arr[i][j]);
- }
- }
- }
这样我们便可以得到一个这样的棋盘

随着二维数组的改变,这个棋盘也会不断变化,所以我们需要多次引用这个自定义函数
首先,我们将我们下一步棋(选用O)与电脑下一步棋(选用X)算作一个整体
我们便可以以这个整体作循环来完成下棋这一过程
a.自己下棋
首先我们先写出一个基础的主体
- int x,y;
- printf("请输入坐标=>");
- scanf("%d%d",&x,&y);
- arr[x-1][y-1]='O';
之后我们便可以为此加“亿点点”细节
首先为了避免在已经下过棋子的位置上重复下棋,或者为了避免输入的坐标不合法(超出数组范围),我们都可以使用分支与循环函数。
而为了美观和便利,我们可以选择使用清屏函数——system("cls")和上面讲到的list(arr)函数。
- while(1)
- {
- system("cls");
- list(arr);
- int x,y;
- printf("请输入坐标=>");
- scanf("%d%d",&x,&y);
- if(x>0&&x<=N&&y>0&&y<=N)
- {
- if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
- {
- arr[x-1][y-1]='O';
- break;
- }
- else
- printf("该位置存在棋子,请重新输入\n");
- }
- else
- printf("不存在该坐标,请重新输入\n");
- }
这样我们自己下一步棋的代码便初步完成了。
b.电脑下棋
想要让电脑在任意空位置下棋(在数组中为任意一个为‘ ’的元素赋值为‘X’),我们要运用到之前在猜数字游戏中学习到的随机数。
而想要让随机值在一次游戏中顺序不变,我们选择将srand()函数放置在主函数中。
- int main()
- {
- srand((unsigned int) time(NULL));
- char arr[N][N];
- new(arr);
- if(menu()==1)
- {
- game(arr);
- }
- return 0;
- }
- while(1)
- {
- int a,b;
- a=rand()%N;//使随机值范围在数组范围之内
- b=rand()%N;//使随机值范围在数组范围之内
- if(arr[a][b]!='O'&&arr[a][b]!='X')
- {
- printf("电脑思考中---\n");
- sleep(2);
- arr[a][b]='X';
- list(arr);
- break;
- }
- }
而sleep()函数与list()函数也是让程序更加美观便利。
c.整合
在完成上述两方的下棋后,我们便可以将其整合
- while(1)
- {
- while(1)
- {
- system("cls");
- list(arr);
- int x,y;
- printf("请输入坐标=>");
- scanf("%d%d",&x,&y);
- if(x>0&&x<=N&&y>0&&y<=N)
- {
- if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
- {
- arr[x-1][y-1]='O';
- count++;
- break;
- }
- else
- printf("该位置存在棋子,请重新输入\n");
- }
- else
- printf("不存在该坐标,请重新输入\n");
- }
- while(1)
- {
- int a,b;
- a=rand()%N;
- b=rand()%N;
- if(arr[a][b]!='O'&&arr[a][b]!='X')
- {
- printf("电脑思考中---\n");
- sleep(2);
- arr[a][b]='X';
- count++;
- list(arr);
- break;
- }
- }
- }
上述代码是自动选择玩家先手,我们也可以通过分支语句来让玩家选择先手情况,这里就不再多做赘述。
当我们完成上述代码后,在一定程度上便可以开始游玩,但我们还需要判断游戏的胜负来终止这一次的游戏。
而这种判断,应该在每一步棋子下完之后就进行一次。
胜负应该如何判断呢?
我们知道,三子棋胜负有三种判断方式——横向连一行、纵向连一列或者对角线连成一排
所以我们要通过三次不同的判断来完成胜负的判断
在这里,我选用的是通过count变量,当一排数组内存在‘O’或‘X’,我们将count “+1”或“-1”,这样当count=3或-3时,便能判断出胜负
- int end(char arr[N][N])
- {
- int count_1=0,count_2=0,count_3=0;
- int i,j;
- for(i=0;i<N;i++)
- {
- count_1=0;
- for(j=0;j<N;j++)
- {
- if (arr[i][j]=='O')
- count_1++;
- else if(arr[i][j]=='X')
- count_1--;
- }
- if (count_1==N||count_1==-N)
- break;
- }
- int a,b;
- for(a=0;a<N;a++)
- {
- count_2=0;
- for(b=0;b<N;b++)
- {
- if (arr[b][a]=='O')
- count_2++;
- else if(arr[b][a]=='X')
- count_2--;
- }
- if (count_2==N||count_2==-N)
- break;
- }
- int c,d;
- for(c=0,d=0;c<N&&d<N;c++,d++)
- {
- if (arr[c][d]=='O')
- count_3++;
- else if(arr[c][d]=='X')
- count_3--;
- }
- if((count_1==N||count_2==N)||count_3==N)
- {
- printf("胜利");
- return 1;
- }
- else if((count_1==-N||count_2==-N)||count_3==-N)
- {
- printf("失败");
- return 1;
- }
- }
当然游戏不只是胜负,还存在平局的情况
三子棋平局时便是将棋盘填满
我们选择变量count,在下每一步棋时,我们将count+1,当变量等于9时,若没有判断出胜负,便是平局的情况。
- int end(char arr[N][N],int count)
- {
- int count_1=0,count_2=0,count_3=0;
- int i,j;
- for(i=0;i<N;i++)
- {
- count_1=0;
- for(j=0;j<N;j++)
- {
- if (arr[i][j]=='O')
- count_1++;
- else if(arr[i][j]=='X')
- count_1--;
- }
- if (count_1==N||count_1==-N)
- break;
- }
- int a,b;
- for(a=0;a<N;a++)
- {
- count_2=0;
- for(b=0;b<N;b++)
- {
- if (arr[b][a]=='O')
- count_2++;
- else if(arr[b][a]=='X')
- count_2--;
- }
- if (count_2==N||count_2==-N)
- break;
- }
- int c,d;
- for(c=0,d=0;c<N&&d<N;c++,d++)
- {
- if (arr[c][d]=='O')
- count_3++;
- else if(arr[c][d]=='X')
- count_3--;
- }
- if(count<N*N)
- {
- if((count_1==N||count_2==N)||count_3==N)
- {
- printf("胜利");
- return 1;
- }
- else if((count_1==-N||count_2==-N)||count_3==-N)
- {
- printf("失败");
- return 1;
- }
- else
- return 2;
- }
- else
- {
- printf("平局");
- return 1;
- }
- }
这样,我们便可以将这件代码组合在一起,完成程序的设计
- #include <stdio.h>
- #include"mean.h"
- void game(char arr[N][N])
- {
- int count=0;
- list(arr);
- while(1)
- {
- while(1)
- {
- system("cls");
- list(arr);
- int x,y;
- printf("请输入坐标=>");
- scanf("%d%d",&x,&y);
- if(x>0&&x<=N&&y>0&&y<=N)
- {
- if(arr[x-1][y-1]!='O'&&arr[x-1][y-1]!='X')
- {
- arr[x-1][y-1]='O';
- count++;
- break;
- }
- else
- printf("该位置存在棋子,请重新输入\n");
- }
- else
- printf("不存在该坐标,请重新输入\n");
- }
- int m=0;
- m=end(arr,count);
- if(m==1)
- {
- list(arr);
- break;
- }
- while(1)
- {
- int a,b;
- a=rand()%N;
- b=rand()%N;
- if(arr[a][b]!='O'&&arr[a][b]!='X')
- {
- printf("电脑思考中---\n");
- sleep(2);
- arr[a][b]='X';
- count++;
- list(arr);
- break;
- }
- }
- m=end(arr,count);
- if(m==1)
- {
- list(arr);
- break;
- }
- }
- }
-
- int main()
- {
- srand((unsigned int) time(NULL));
- char arr[N][N];
- new(arr);
- if(menu()==1)
- {
- game(arr);
- }
- return 0;
- }
- #include<stdio.h>
- #include"mean.h"
- int menu()
- {
- int input=0;
- printf("1——开始游戏 2——退出\n");
- printf("请选择=>");
- scanf("%d",&input);
- if(input==1)
- {
- printf("加载中---\n");
- sleep(1);
- return 1;
- }
- else if(input==2)
- printf("正在退出\n");
- else
- printf("输入错误,请重新输入\n");
- }
- void list(char arr[N][N])
- {
- int i,j;
- for(i=0;i<N;i++)
- {
- for(j=0;j<N;j++)
- {
- if(j<N-1)
- printf(" %c |",arr[i][j]);
- else if(j==N-1&&i!=N-1)
- {
- printf(" %c \n",arr[i][j]);
- for(j=0;j<N;j++)
- {
- if(j<N-1)
- printf("---|");
- else
- printf("---\n");
- }
- }
- else
- printf(" %c \n",arr[i][j]);
- }
- }
- }
- void new(char arr[N][N])
- {
- int i,j;
- for(i=0;i<N;i++)
- {
- for(j=0;j<N;j++)
- {
- arr[i][j]=' ';
- }
- }
- }
- int end(char arr[N][N],int count)
- {
- int count_1=0,count_2=0,count_3=0;
- int i,j;
- for(i=0;i<N;i++)
- {
- count_1=0;
- for(j=0;j<N;j++)
- {
- if (arr[i][j]=='O')
- count_1++;
- else if(arr[i][j]=='X')
- count_1--;
- }
- if (count_1==N||count_1==-N)
- break;
- }
- int a,b;
- for(a=0;a<N;a++)
- {
- count_2=0;
- for(b=0;b<N;b++)
- {
- if (arr[b][a]=='O')
- count_2++;
- else if(arr[b][a]=='X')
- count_2--;
- }
- if (count_2==N||count_2==-N)
- break;
- }
- int c,d;
- for(c=0,d=0;c<N&&d<N;c++,d++)
- {
- if (arr[c][d]=='O')
- count_3++;
- else if(arr[c][d]=='X')
- count_3--;
- }
- if(count<N*N)
- {
- if((count_1==N||count_2==N)||count_3==N)
- {
- printf("胜利");
- return 1;
- }
- else if((count_1==-N||count_2==-N)||count_3==-N)
- {
- printf("失败");
- return 1;
- }
- else
- return 2;
- }
- else
- {
- printf("平局");
- return 1;
- }
- }
- #define N 3
- void list(char arr[N][N]);
- int menu();
- void new(char arr[N][N]);
- int end(char arr[N][N],int count);