C语言学习-数组应用-三子棋(4.1)
创始人
2024-04-05 13:03:47
0

目录

三子棋的设计思路:

1. 游戏菜单功能的实现

2. 游戏功能具体实现

 2.1 棋盘的初始化与打印

2.2 玩家与电脑对战的实现

2.3 判断胜负平局的实现

3. 三子棋源码

写在最后:


三子棋的设计思路:

我们创建三个文件拆分三子棋的实现过程:

一个测试文件(test.c)游戏实现文件(game.c)头文件(game.h)

我们先对测试文件进行编辑。

1. 游戏菜单功能的实现

在 test.c 中写一个主函数:

int main()//主函数尽量放的东西少一点
{test();//可以通过创建一个函数实现其他功能return 0;
}

我们通过刚刚创建的 test 函数实现一些功能:

1. 玩一把不过瘾,在玩一把

2. 创建游戏菜单

3. 创建游戏实现函数

void test()
{int choice = 0;do  //我们使用一个do while循环,如果玩一把三子棋不过瘾,可以再玩一把{menu();printf("请选择:>");scanf("%d", &choice);//接收玩家输入的值switch (choice){case 1:printf("三子棋游戏开始\n");game();//我们将游戏的实现分装成一个函数break;case 0:printf("游戏已退出\n");break;default:printf("输入错误,请重新输入\n");break;}} while (choice);
}

这是我们的游戏菜单:

void menu()//打印游戏菜单界面
{printf("***************************************\n");printf("*****  开始游戏:1    退出游戏:0  *****\n");printf("***************************************\n");}

写到这里,我们可以先测试一下代码运行的结果:

这样,我们就完成了菜单逻辑的制作

2. 游戏功能具体实现

接下来我们要具体实现函数 game 。

 2.1 棋盘的初始化与打印

实现思路:

首先,我们需要记录玩家和电脑的落子情况

 通过分析,能落子的地方有九个,

我们可以通过创建一个3*3的数组对其进行记录。

我们在头文件中用#define定义常量,便于日后观察或修改

 再在测试文件中引用:

#include "game.h"//引用自己的头文件void game()//三子棋的实现
{char board[ROW][COL];//存放玩家或电脑的落子情况
}

接下来我们需要让落子位置初始化,并将三子棋的棋盘打印出来:

我们将初始化和棋盘打印这两个步骤分装成两个函数并在 game.c 中实现:

 为了能够使用这两个函数,我们需要在头文件中声明:

void init_board(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);

初始化棋盘的具体实现:

void init_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ' ';//将落子位置初始化成空格}}
}

打印棋盘的具体实现:

void print_board(char board[ROW][COL], int row, int col){int i = 0;for (i = 0; i < col; i++){printf("  %d ", i + 1);//添加纵坐标}printf("\n");for (i = 0; i < row; i++){int j = 0;printf("%d", i + 1);//添加横坐标for (j = 0; j < col; j++){printf(" %c ", board[i][j]);//打印三行,每行三个 %c if (j < col - 1)//井字棋的棋盘只需要中间两排竖着的分割线{printf("|");//打印三行,每行两个‘|’}}printf("\n");if (i < row - 1)//只需要两行分割线{printf(" ");//对齐for (j = 0; j < col; j++){printf("---");//打印两行,每行三个‘---’if (j < col - 1){printf("|");//打印两行,每行两个‘|’}}}printf("\n");}}

最后呈现的结果是这样的:

2.2 玩家与电脑对战的实现

 接下来就是下棋了,我们把下棋分为两步:

1. 玩家回合

2. 电脑回合

并且每次下完把棋盘打印出来:

然后将函数在头文件中声明,在 game.c 中实现:

声明:

void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);

 玩家回合的实现:

	void player_move(char board[ROW][COL], int row, int col){printf("玩家回合\n");while (1){printf("请输入要下的坐标:>");int x = 0;int y = 0;scanf("%d %d", &x, &y);//坐标合法(在棋盘中)if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' ')//坐标是空的{board[x - 1][y - 1] = '*';break;//选择成功后就跳出循环}else{printf("那个位置已经被占了,请重新选择\n");}}else{printf("你选的坐标不在棋盘内,请重新选择\n");}}}

电脑回合的实现:

	void computer_move(char board[ROW][COL], int row, int col){printf("电脑回合\n");while (1){int x = rand() % row;//生成随机数int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}}

生成随机数时:

现在就到了最后一步,

2.3 判断胜负平局的实现

判断输赢:

void game()//三子棋的实现
{char ret = 0;//我们通过返回字符判断输赢char board[ROW][COL];//存放玩家或电脑的落子情况init_board(board, ROW, COL);//初始化棋盘print_board(board, ROW, COL);//打印棋盘while (1)//创建一个循环,直到分出胜负或平局再跳出{player_move(board, ROW, COL);//玩家下print_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')//判断游戏是否继续{break;//当ret不等于C时,跳出循环,判断输赢}computer_move(board, ROW, COL);//电脑下print_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}//判断输赢if (ret == '*'){printf("你赢了\n");}else if (ret == '#'){printf("电脑获胜\n");}else if (ret == 'Q'){printf("平局\n");}
}

这样,当ret返回 * 是玩家获胜,返回 # 时电脑获胜,都不返回则平局。

接下来需要实现 is_win 函数:

(实现函数时,别忘了在头文件中声明哦)

	char is_win(char board[ROW][COL], int row, int col){int i = 0;//判断三行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){return board[i][0];}}//判断三列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){return board[0][i];}}//判断对角线if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}}

还有平局的情况,可以再分装成一个函数实现:

//平局if (is_full(board, row, col) == 1)//判断棋盘是否满了{return 'Q';}return 'C';

函数 is_full 的实现:

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

现在,三子棋就做完了,我们一起赢一把看看效果:

 学会了吗?

快去试试吧!

3. 三子棋源码

这里是源码:

1. test.c 文件:

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"//引用自己的头文件void menu()//打印游戏菜单界面
{printf("***************************************\n");printf("*****  开始游戏:1   退出游戏:0  *****\n");printf("***************************************\n");}void game()//三子棋的实现
{char ret = 0;//我们通过返回字符判断输赢char board[ROW][COL];//存放玩家或电脑的落子情况init_board(board, ROW, COL);//初始化棋盘print_board(board, ROW, COL);//打印棋盘while (1)//创建一个循环,直到分出胜负或平局再跳出{player_move(board, ROW, COL);//玩家下print_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')//判断游戏是否继续{break;//当ret不等于C时,跳出循环,判断输赢}computer_move(board, ROW, COL);//电脑下print_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}//判断输赢if (ret == '*'){printf("你赢了\n");}else if (ret == '#'){printf("电脑获胜\n");}else if (ret == 'Q'){printf("平局\n");}
}void test()
{srand((unsigned int)time(NULL));//通过时间戳生成随机数int choice = 0;do  //我们使用一个do while循环,如果玩一把三子棋不过瘾,可以再玩一把{menu();printf("请选择:>");scanf("%d", &choice);//接收玩家输入的值switch (choice){case 1:printf("三子棋游戏开始:\n");game();//我们将游戏的实现分装成一个函数break;case 0:printf("游戏已退出\n");break;default:printf("输入错误,请重新输入\n");break;}} while (choice);
}int main()//主函数尽量放的东西少一点
{test();//可以通过创建一个函数实现其他功能return 0;
}

2. game.h 文件:

#pragma once#include
#include
#include#define ROW 3 
#define COL 3void init_board(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);char  is_win(char board[ROW][COL], int row, int col);

3. game.c 文件:

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void init_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ' ';//将落子位置初始化成空格}}
}void print_board(char board[ROW][COL], int row, int col){int i = 0;for (i = 0; i < col; i++){printf("  %d ", i + 1);//添加纵坐标}printf("\n");for (i = 0; i < row; i++){int j = 0;printf("%d", i + 1);//添加横坐标for (j = 0; j < col; j++){printf(" %c ", board[i][j]);//打印三行,每行三个 %c if (j < col - 1)//井字棋的棋盘只需要中间两排竖着的分割线{printf("|");//打印三行,每行两个‘|’}}printf("\n");if (i < row - 1)//只需要两行分割线{printf(" ");//对齐for (j = 0; j < col; j++){printf("---");//打印两行,每行三个‘---’if (j < col - 1){printf("|");//打印两行,每行两个‘|’}}}printf("\n");}}void player_move(char board[ROW][COL], int row, int col){printf("玩家回合\n");while (1){printf("请输入要下的坐标:>");int x = 0;int y = 0;scanf("%d %d", &x, &y);//坐标合法(在棋盘中)if (x >= 1 && x <= row && y >= 1 && y <= col){if (board[x - 1][y - 1] == ' ')//坐标是空的{board[x - 1][y - 1] = '*';break;//选择成功后就跳出循环}else{printf("那个位置已经被占了,请重新选择\n");}}else{printf("你选的坐标不在棋盘内,请重新选择\n");}}}void computer_move(char board[ROW][COL], int row, int col){printf("电脑回合\n");while (1){int x = rand() % row;//生成随机数int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}}int is_full(char board[ROW][COL], int row, int col){int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;}char is_win(char board[ROW][COL], int row, int col){int i = 0;//判断三行for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){return board[i][0];}}//判断三列for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' '){return board[0][i];}}//判断对角线if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//平局if (is_full(board, row, col) == 1)//判断棋盘是否满了{return 'Q';}return 'C';}

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...