c语言系列三子棋版
- 🍁 个人主页:爱编程的Tom
- 🎐 CSDN新晋作者
- 💫 本篇博文收录专栏:c系列小游戏
- ✨ 目前其它专栏:c语言系列--万物的开始
- 🎉 欢迎 👍点赞✍评论⭐收藏💖三连支持一下博主🤞
- 🧨每一次的学习都是一次进步,坚持下去,您将注定非凡🎨
目录
前言
还记得小时候,在没事的闲暇时刻里,总喜欢用三子棋来消磨时光,它承载了童年的欢声笑语和那些已经逝去的时光。三子棋,顾名思义就是在一个3x3的棋盘中,任意三子连成一条直线即为赢。如下图所示:
那么今天我们就通过所学的c语言知识(主要包括数组和函数)来实现一个三子棋,梦回少年时代!
1.设计思路
我们知道,要想让三子棋获胜,就要使得一条直线上的三个棋子相同(即行、列、对角任意一个满足即玩家获胜),反之则电脑获胜,这里由于是适用于初学者,所以电脑落子采用随机落子。因此,可能还会出现平局的现象。在考虑到这些情况之后,我们便可以动手来编写自己的三子棋了。
2.设计流程
这里为方便三子棋游戏的需要,我们采用多文件的形式来分别进行编码。这里我们将其划分为(test.c文件\\game.c文件\\game.h文件)这三个文件。
其中,test.c文件里面写三子棋的整体框架和运行逻辑;game.c文件中实现三子棋游戏中各个函数具体的功能;game.h文件里放入整个函数所需要的函数声明以及头文件,并将其作为test.c文件和game.c文件的头文件使用。
3.文件的创建
1.test.c文件
这里我们首先创建一个菜单,让它通过主函数实现一个功能的选择,即输入1---开始游戏;输入0--退出游戏;输入其他----返回错误,请重新输入。然后我们需要while循环来维持游戏的进行,使用switch语句来进行的游戏的选择,此外,在这里我们还要实现game()函数的主体框架。
👀菜单函数
-
void menu()
-
{
-
printf("************************\n");
-
printf("****** 1.play ******\n");
-
printf("****** 0.exit ******\n");
-
printf("************************\n");
-
}
函数实现结果:
👀主函数main()
-
int main()
-
{
-
srand((unsigned int)time(NULL));//随机数的生成
-
int input = 0;
-
do
-
{
-
menu();
-
printf("请选择>");
-
scanf("%d", &input);
-
switch (input)
-
{
-
case 1:
-
game();
-
break;
-
case 0:
-
printf("退出游戏\n");
-
break;
-
default:
-
printf("输入有误,请重新输入:\n");
-
}
-
} while (input);
-
return 0;
-
}
这里定义一个input变量,来作为do while和switch的判断条件,程序打印菜单,然后根据不同的选择情况进行不同的操作。
函数实现结果:
在test.c文件中,实现game()函数是比较难的,这里我们重点来说明一下
👀游戏函数game()
这里的函数主要实现的是游戏内部的逻辑,实现的功能分别是
1.创建棋盘 2.棋盘初始化 3.打印棋盘 4.玩家下棋 5.电脑下棋 6.判断游戏输赢
这其中玩家下棋和电脑下棋的先后顺序可以自行决定。
-
void game()
-
{
-
char ret = 0;
-
char board[3][3];
-
InitBoard(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
while (1)
-
{
-
PlayerMove(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
//判断输赢
-
ret = IsWin(board, ROW, COL);
-
if (ret != 'C')
-
{
-
break;
-
}
-
ComputerMore(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
//判断输赢
-
ret = IsWin(board, ROW, COL);
-
if (ret != 'C')
-
{
-
break;
-
}
-
}
-
if (ret == '*')
-
{
-
printf("玩家赢\n");
-
}
-
else if (ret == '#')
-
{
-
printf("电脑赢\n");
-
}
-
else
-
{
-
printf("双方平局\n");
-
}
-
}
在这里,我们规定一下:
//玩家赢---'*'
//电脑赢----'#'
//平局---'Q'
//游戏继续---'C'
使用while循环来进行电脑与玩家之间的博弈。通过if-else语句来进行相应的判断,利用IsWin函数判断获胜的标准。不等于C则判断哪方赢,若返回*,则判定玩家赢;返回#,判定电脑赢;返回Q,判定双方平局。
函数运行截图:
在game()函数里实现的各个函数会在game.c文件中实现,下面将继续深入!
2.game.c文件
✨棋盘初始化函数
-
void InitBoard(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 )
-
{
-
board[i][j] = ' ';
-
}
-
}
-
}
这里初始化为三行三列的一个棋盘,以及表示行和列的两个形参,利用简单的for循环实现棋盘的初始化为’ ‘
✨打印棋盘函数
-
void DisplayBoard(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 )
-
{
-
printf(" %c ", board[i][j]);
-
if (j < col - 1)
-
printf("|");
-
}
-
printf("\n");
-
//再打印分割行
-
if (i < row - 1)
-
{
-
for (j = 0; j < col; j )
-
{
-
printf("---");
-
if (j < col - 1)
-
printf("|");
-
}
-
}
-
printf("\n");
-
}
-
}
这里利用for循环分别打印第一行的%c|%c|%c以及---|---|---来作为棋盘的基础数据,,循环往复3次,便可打印处想要的棋盘复现!
✨玩家下棋函数
这里由于我们设定的是玩家先下棋,所以在这里设定玩家下棋的函数思路
-
void PlayerMove(char board[ROW][COL], int row, int col)
-
{
-
int x = 0;
-
int y = 0;
-
printf("玩家下棋\n");
-
while (1)
-
{
-
printf("请输入要下棋的坐标:>");
-
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");
-
}
-
}
-
}
这里需要注意的是:由于数组是从下标[0][0]开始的,所以玩家下棋的第一行要减去1,即可得到玩家下棋的第一个位置。此外,这里考虑两种情况:
一、玩家输入下棋坐标不正确,通过if~else语句来进行判断是否符合棋盘范围,如果输入错误,则打印“您输入的坐标不正确,请重新输入”来进行相应的返回。
二、若玩家下棋坐标正确,但输入的坐标点已经有棋子,导致该位置被占用,这时候通过else语句来打印“该位置被占用,请重新落子”来提示玩家。
下图为程序运行实例:
✨电脑下棋函数
-
void ComputerMore(char board[ROW][COL], int row, int col)
-
{
-
printf("电脑下棋\n");
-
int x = 0;
-
int y = 0;
-
while (1)
-
{
-
x = rand() % row;
-
y = rand() % col;
-
if (board[x][y] == ' ')
-
{
-
board[x][y] = '#';
-
break;
-
}
-
}
-
}
🧐由于适用于新手所用的教程,所以这里电脑下棋只采用简单的随机数生成算法函数,方便大家的使用。
-
//test.c
-
srand((unsigned int)time(NULL));//随机数的生成
使用srand函数在主函数中调用来设置随机数生成,在此函数中设置rand函数随机数的限制范围,即0~2,令其分别取row和col的模,让电脑在3*3的棋盘上落子。
-
x = rand() % row;
-
y = rand() % col;
然后利用while循环来检测棋盘中是否存在空格,来判断这里是否已经下过棋,从而实现电脑落子
✨检测棋盘是否下满函数
-
static int IsFull(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;
-
}
这里需要创造一个函数为后续判断输赢提供条件,由于return返回值类型是0或1,所以这里采用int整形的方式返回。这个函数规定仅限在当前game.c文件中使用,所以这里使用static静态变量的方式限制函数,利用for循环来遍历棋盘中是否存在空格’ ‘,有返回0;没有返回1。
✨判断胜负输赢函数
-
char IsWin(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 (IsFull(board, row, col))
-
{
-
return 'Q';
-
}
-
return 'C';
-
-
}
因为三子棋获胜的决定性条件就是任意一条直线(包括对角线)三子相同,即可获胜,所以在这个函数中将所有可能的情况写出来,到这里,我们用上之前所记的规定:
//玩家赢---'*' //电脑赢---'#' //平局---'Q' //游戏继续---'C'
这里可以利用for循环来进行相应的判断,此外,
使用之前定义的棋盘下满的函数,可作为判断是否平局的依据,若棋盘下满还未分出胜负,则判定平局,返回C。这里一旦判定输赢之后,可直接将所下棋盘的数据展示出来,亦可不必返回所规定的字符。
3.game.h文件
🍳头文件的相关使用
🍳棋盘行列的定义
这里使用了#define定义的宏定义,使代码具有更好的可读性以及复用性,减少代码冗余,方便我们对于代码能够进行很好的维护,此外我们还可以自行修改,从而达到一个多子棋的功能实现。由于这里是预处理阶段编译的,提高了代码的执行效率。
🍳期盼初始化
-
void InitBoard(char board[ROW][COL],int row,int col);
-
//初始化棋盘
🍳棋盘的打印
-
void DisplayBoard(char board[ROW][COL], int row, int col);
-
//打印棋盘
🍳玩家下棋
-
void PlayerMove(char board[ROW][COL], int row, int col);
-
//玩家下棋
🍳电脑下棋
-
void ComputerMore(char board[ROW][COL], int row, int col);
-
//电脑下棋
🍳按照规则判断输赢
-
char IsWin(char board[ROW][COL], int row, int col);
-
//判断输赢
-
//判断标准
-
//判断输赢的四种情况
-
玩家赢---'*'
-
电脑赢---'#'
-
平局---'Q'
-
游戏继续---'C'
4.完整代码示例
💙game.h文件代码
-
-
-
-
-
-
-
-
-
void InitBoard(char board[ROW][COL],int row,int col);
-
//初始化棋盘
-
-
void DisplayBoard(char board[ROW][COL], int row, int col);
-
//打印棋盘
-
-
void PlayerMove(char board[ROW][COL], int row, int col);
-
//玩家下棋
-
-
void ComputerMore(char board[ROW][COL], int row, int col);
-
//电脑下棋
-
-
char IsWin(char board[ROW][COL], int row, int col);
-
//判断输赢
💙game.c文件代码
-
-
-
void InitBoard(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 )
-
{
-
board[i][j] = ' ';
-
}
-
}
-
}
-
void DisplayBoard(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 )
-
{
-
printf(" %c ", board[i][j]);
-
if (j < col - 1)
-
printf("|");
-
}
-
printf("\n");
-
//再打印分割行
-
if (i < row - 1)
-
{
-
for (j = 0; j < col; j )
-
{
-
printf("---");
-
if (j < col - 1)
-
printf("|");
-
}
-
}
-
printf("\n");
-
}
-
}
-
void PlayerMove(char board[ROW][COL], int row, int col)
-
{
-
int x = 0;
-
int y = 0;
-
printf("玩家下棋\n");
-
while (1)
-
{
-
printf("请输入要下棋的坐标:>");
-
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 ComputerMore(char board[ROW][COL], int row, int col)
-
{
-
printf("电脑下棋\n");
-
int x = 0;
-
int y = 0;
-
while (1)
-
{
-
x = rand() % row;
-
y = rand() % col;
-
if (board[x][y] == ' ')
-
{
-
board[x][y] = '#';
-
break;
-
}
-
}
-
}
-
static int IsFull(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;
-
}
-
//判断输赢,应该是有四种情况
-
//玩家赢-'*'
-
//电脑赢-'#'
-
//平局---'Q'
-
//游戏继续--'C'
-
char IsWin(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 (IsFull(board, row, col))
-
{
-
return 'Q';
-
}
-
return 'C';
-
-
}
💙test.c文件测试代码
-
-
-
void menu()
-
{
-
printf("************************\n");
-
printf("****** 1.play ******\n");
-
printf("****** 0.exit ******\n");
-
printf("************************\n");
-
}
-
void game()
-
{
-
char ret = 0;
-
char board[3][3];
-
InitBoard(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
while (1)
-
{
-
PlayerMove(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
//判断输赢
-
ret = IsWin(board, ROW, COL);
-
if (ret != 'C')
-
{
-
break;
-
}
-
ComputerMore(board, ROW, COL);
-
DisplayBoard(board, ROW, COL);
-
//判断输赢
-
ret = IsWin(board, ROW, COL);
-
if (ret != 'C')
-
{
-
break;
-
}
-
}
-
if (ret == '*')
-
{
-
printf("玩家赢\n");
-
}
-
else if (ret == '#')
-
{
-
printf("电脑赢\n");
-
}
-
else
-
{
-
printf("双方平局\n");
-
}
-
}
-
int main()
-
{
-
srand((unsigned int)time(NULL));//设置随机数的生成起点
-
int input = 0;
-
do
-
{
-
menu();
-
printf("请选择>");
-
scanf("%d", &input);
-
switch (input)
-
{
-
case 1:
-
game();
-
break;
-
case 0:
-
printf("退出游戏\n");
-
break;
-
default:
-
printf("输入有误,请重新输入:\n");
-
}
-
} while (input);
-
return 0;
-
}
💙程序部分运行截图:
5.总结
三子棋是一个非常有意思的小游戏,这里从设计它便可感受到内在的逻辑,思维还是非常缜密的。通过实现这个三子棋的小游戏,我们学习并了解了c语言中很多的知识。如循环,数组界定,思维逻辑,算法实现等等。愿本篇博文能够带你领略c语言的魅力所在,激发你对c语言编程的兴趣。相信通过不断的学习和坚持,你也会创造出许多优秀的作品。如果您有任何的疑问和建议,也欢迎在我的评论区进行留言与我分享哦,愿你我未来如星河灿烂!
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgggbhg
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13