> 文档中心 > C语言实战项目【2】三子棋

C语言实战项目【2】三子棋

基于二维数组的学习之后,我们可以利用二维数组来做一个简易的三子棋游戏

我们在写一个项目之前要先分析需要的操作

目录

1.首先要有一个目录,让玩家选择开始或者结束游戏

2.要设计一个棋盘

3.要设计让玩家下棋,并且提供一些操作指南

4.要让电脑下棋

5.要有判胜负的系统


1.首先要有一个目录,让玩家选择开始或者结束游戏

void menu(){printf("*\n");printf("*1.play    *\n");printf("*0.exit \n");printf("*\n");}

做出来之后,效果是这样的

做出目录之后,要做出让玩家选择的操作

这里我选择在main函数中使用do......while来实现,用do……while函数还有一个好处就是让玩家在上一次的游戏结束之后再次进行选择,是进行游戏还是退出游戏

int main(){int input;do{menu();Init(arr,ROW,COL);scanf("%d", &input);switch(input){case 1:{game(arr,ROW,COL);break;}case 0:{printf("退出游戏\n");break;}default:{printf("输入错误\n");break;}}} while (input);

在玩家输入input之后,给出对应的操作

2.要设计一个棋盘

而在此之前我们要把二维数组初始化成   ’ ‘,这样在棋盘中就不会有多余的随机数出现了

void Init(char arr[ROW][COL], int row, int col){int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++)arr[i][j] = ' ';}}
void print_board(char arr[ROW][COL], int row, int col){int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (j == col-1){printf(" %c ", arr[i][j]);}elseprintf(" %c |",arr[i][j]);}printf("\n");if(i < row )for (j = 0; j < col ; j++){if(j == col - 1)printf("___");elseprintf("___|");}printf("\n");}}

这里我们把上面两段代码执行之后,效果是这样的

 这样可以让玩家清晰的看到自己棋盘并且选择下棋的位置

3.要设计让玩家下棋,并且提供一些操作指南

这里我们可以让玩家选择在二维数组里面输入对应的位置进行下弈子,我们用*来表示玩家下的棋,每下完一颗棋子,就要让玩家知道自己下哪了,所以打印一下棋盘

可以调用上面的打印棋盘的函数print_board

并且这里我们给玩家下棋的时候,让我们的参数-1,这样就可以让玩家用常规的思路,行数从第一行开始了

然后我们要考虑到玩家输入出错的情况或者棋盘上已经有棋子的情况,这时候我们可以提醒他输入出错了,并且让他重新输入

玩家下棋的代码如下

void player_chess(char arr[ROW][COL], int row, int col){int x = 0;int y = 0;while (1){printf("玩家下棋:>\n");scanf("%d %d", &x, &y);if (x > row || y > col || x < 1 || y < 1 ||arr[x-1][y-1] !=' '){printf("输入错误,重新输入\n");}else{arr[x - 1][y - 1] = '*';print_board(arr, ROW, COL);break;}}}

效果是这样的

4.要让电脑下棋

电脑下棋其实就比较简单了,我们之前的项目中解释了(具体请看C语言实战项目【1】猜数字)生成随机数函数和时间戳的配合使用然后在对行和列进行取余,就可以让我们的随机数只会是行和列了,就不会导致数组越界的问题了

具体代码如下

void computer_chess(char arr[ROW][COL], int row, int col){int x = 0;int y = 0;printf("电脑下棋\n");while (1){x = rand() % ROW;y = rand() % COL;if (arr[x ][y] == ' '){arr[x ][y ] = '#';break;}}print_board(arr, ROW, COL);}

执行这个代码,配合前面的一起使用,就基本完成了玩游戏的框架运行结果是这样的

5.要有判胜负的系统

在进行完上面的操作之后,还应该有一个判断胜负的操作,这时候我们可以利用二维数组来进行,让三子成行,或者三子成列,亦或者斜着凑成三个的胜,这里我们用一个小技巧,让函数的返回值是char类型,然后我们在进行接收的时候直接就可以用*或者#来判断胜负了

整个判断胜负的代码如下

char is_win(char arr[ROW][COL], int row, int coL){int i,j;for (i = 0; i < ROW - 1; i++){if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][0] != ' '){return arr[i][0];}}for (j = 0; j<COL - 1; j++){if (arr[0][j] == arr[1][j] && arr[1][j]==arr[2][j] && arr[0][j] !=' '){return arr[0][j];}}if (arr[0][0] == arr[1][1] && arr[0][0] == arr[2][2] && arr[0][j] != ' ')return arr[1][1];if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][j] != ' ')return arr[1][1];return ' ';}

当然了,我们玩三子棋都知道,还会出现平局的情况,这时候就需要我们再设计一个平局的情况

int is_full(char arr[ROW][COL], int row, int coL)    {int record,i,j;record = 1;for (i = 0; i < ROW; i++){for (j = 0; j < COL; j++){if (arr[i][j] == ' '){record = 0;}}}return record;}

这里看似我们已经完成了所有的操作,但是还有一个问题就是我们让玩家下棋之后,电脑下棋,然后我们还应该让他们继续下棋,知道胜负出现,这里我们就可以把我们的函数打包成一个game函数,来进行整合判断,大体逻辑就是这样

代码如下

void game(char arr[ROW][COL], int row, int col){srand((unsigned int )time(NULL));int full;char win;print_board(arr, ROW, COL);while (1){win = is_win(arr, ROW, COL);full = is_full(arr, ROW, COL);if (win != ' ' || full == 1)break;player_chess(arr, ROW, COL);computer_chess(arr, ROW, COL);}if (win == '*')printf("玩家赢\n");if (win == '#')printf("电脑赢\n");if (full == 1)printf("平局\n");}

这里的srand函数同样,在上面的猜数字项目中都有详细的解答其实就是一个控制随机数的函数,

然后就可以到最后一步

最后整合的代码就是

#include#include"game.h"void menu(){printf("*\n");printf("*1.play    *\n");printf("*0.exit \n");printf("*\n");}void Init(char arr[ROW][COL], int row, int col){int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++)arr[i][j] = ' ';}}void print_board(char arr[ROW][COL], int row, int col){int i, j;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (j == col-1){printf(" %c ", arr[i][j]);}elseprintf(" %c |",arr[i][j]);}printf("\n");if(i < row )for (j = 0; j \n");scanf("%d %d", &x, &y);if (x > row || y > col || x < 1 || y < 1 ||arr[x-1][y-1] !=' '){printf("输入错误,重新输入\n");}else{arr[x - 1][y - 1] = '*';print_board(arr, ROW, COL);break;}}}void computer_chess(char arr[ROW][COL], int row, int col){int x = 0;int y = 0;printf("电脑下棋\n");while (1){x = rand() % ROW;y = rand() % COL;if (arr[x ][y] == ' '){arr[x ][y ] = '#';break;}}print_board(arr, ROW, COL);}char is_win(char arr[ROW][COL], int row, int coL)//判胜{int i,j;for (i = 0; i < ROW - 1; i++){if (arr[i][0] == arr[i][1] && arr[i][0] == arr[i][2] && arr[i][0] != ' '){return arr[i][0];}}for (j = 0; j<COL - 1; j++){if (arr[0][j] == arr[1][j] && arr[1][j]==arr[2][j] && arr[0][j] !=' '){return arr[0][j];}}if (arr[0][0] == arr[1][1] && arr[0][0] == arr[2][2] && arr[0][j] != ' ')return arr[1][1];if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][j] != ' ')return arr[1][1];return ' ';}int is_full(char arr[ROW][COL], int row, int coL)    //判平{int record,i,j;record = 1;for (i = 0; i < ROW; i++){for (j = 0; j < COL; j++){if (arr[i][j] == ' '){record = 0;}}}return record;}void game(char arr[ROW][COL], int row, int col){srand((unsigned int )time(NULL));int full;char win;print_board(arr, ROW, COL);while (1){win = is_win(arr, ROW, COL);full = is_full(arr, ROW, COL);if (win != ' ' || full == 1)break;player_chess(arr, ROW, COL);computer_chess(arr, ROW, COL);}if (win == '*')printf("玩家赢\n");if (win == '#')printf("电脑赢\n");if (full == 1)printf("平局\n");}int main(){int input;char arr[ROW][COL];Init(arr,ROW,COL);do{menu();Init(arr,ROW,COL);scanf("%d", &input);switch(input){case 1:{game(arr,ROW,COL);break;}case 0:{printf("退出游戏\n");break;}default:{printf("输入错误\n");break;}}} while (input);return 0;}

这段代码整体的运行情况是这样的

 这是比较简易的小项目,便于初学者更加好理解二维数组的,还请大佬指点

88读书网