Hello!大家好,我是刚加入CSDN的一名小写手MO_lion,今天要为大家带来的文章是刚刚掌握的傻瓜版三子棋的实现。
目录
一、棋盘的完成和打印
1)棋盘的初始化
2)棋盘的打印
二、玩家和电脑分别下棋
1)玩家的下棋
2)电脑下棋
三、判断是否继续
想必大家小时候都曾经接触过三子棋的游戏,也许是朋友间的嬉戏,又或许是和家长之间的玩闹,那么游戏的规则不必多说,我们来看算法的思路以及实现。
在开始具体的敲代码环节之前,我们需要对我们程序的设计有一个大概的思路并将任务分配给我们将要设计出的函数。根据函数高内聚低耦合的原则,我将代码的主要部分先分为“菜单和游戏的初始化”和“游戏主体”两个部分。
那么首先我们来看打印菜单和游戏初始化的部分,我们玩游戏当然是要重复的初始化和打印菜单界面,大部分的游戏直接退出都是由菜单界面选择退出,我们的傻瓜三子棋自然也不例外。为了循环重复我们的菜单初始化界面,我们将它放入循环中去,并且为了让玩家自主选择是否开始游戏,我利用 scanf函数 接受玩家的输入以完成交互并将“是否开始游戏”设计为 switch语句 引导的分支语句。
int main()
{
int input = 0;
do
{
menu();
printf("请选择是否开始游戏:>");
scanf("%d", &input);
switch(input)
{
case 1:
printf("开始游戏\n");
game();
break;
case 0:
printf("退出游戏。\n");
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
我们可以看到菜单初始化中涉及的函数有:“菜单的打印”menu()以及“傻瓜三子棋游戏主体的实现”game()。
menu()的实现大家可以自行设计,对游戏的内容和运行影响不大,我觉得简洁美观一些为好,下面是我的menu(),大家可以参考一下:
void menu()
{
printf("*** *三子棋* ***\n");
printf("*** 1.play ***\n");
printf("*** 0.exit ***\n");
printf("***************************\n");
}
以上我们就将“菜单与游戏初始化”完成了,那么接下来的就是整个游戏的核心,即game()函数的实现:
在敲代码之前,我们可以先想想我们玩三子棋的流程,首先,我们要有一个三子棋的棋盘(记得在我小时候和朋友一起玩三子棋,这种棋盘经常是用粉笔在地上画出来的),接着我们要设计双方棋手的棋子模型,然后便是喜闻乐见的下棋环节,下棋时我们会注意是否有一方将要获胜或者是否平局,毕竟有一方获胜我们就没必要继续下去了,最后的部分当然就是不可或缺的庆祝一方的胜利或者宣告可喜可贺(ps:在傻瓜三子棋中,平局比胜利更难)的平局了。
思考完三子棋的玩法和流程以后,我们便可以开始着手实现game()函数,那么根据以上的讨论我们将之分为:
- 设置棋盘和打印棋盘
- 玩家和电脑分别下棋
- 判断胜利并庆祝可悲的胜利和可喜的平局(bushi)
我将棋盘初始化和打印棋盘分为两个步骤和两个函数来实现:
既然棋盘是一个3*3的平面结构,那我们可以用一个二维数组board[H][L] (我将H、设置为两个常量值都为3并在以后的传参中都输入H、L,方便后续可以扩大棋盘) 来当作棋盘存放棋子,并在一开始将棋盘上都放上空格以表示没有棋子占用棋盘,这里我设计了一个chushi()函数来完成这个动作。
void chushi(char board[H][L], int h, int l)
{
int i = 0;
int j = 0;
for (i = 0; i < h; i++)
{
for (j = 0; j < l; j++)
{
board[i][j] = ' ';
}
}
}
为了将棋盘打印得尽量美观,我们需要一些设计:
void dayin(char board[H][L], int h, int l)
{
int i = 0;
int j = 0;
for (i = 0; i < h; i++)
{
for (j = 0; j < l; j++)
{
printf(" %c ",board[i][j]);
if (j < l - 1)
{
printf("|");
}
}
printf("\n");
if (i < h - 1)
{
for (j = 0; j < l; j++)
{
printf("---");
if (j < l - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
这样我们就完成了棋盘的打印函数,我将之命名为 dayin()(由于太懒了直接上拼音(笑))。在今后的节目中,我准备了许多我自己作词....(胡言乱语,手动滑稽)咳咳,不好意思串台了。(重新来一遍)在后续的 game() 函数实现中我们也可以使用它来为我们显示下棋后的棋盘状态给玩家作为参考。
我们在上面已经完成了棋盘的设置和初始化,那么我们就可以直接通过改变二维数组的元素内容来实现下棋这一动作。我将玩家的棋子设置为‘*’,将电脑的棋子设置为‘#’,下面是两者的下棋实现。
在玩家的下棋过程中,我们的主要行动就是要改变原来棋盘上的‘ ’为‘*’号或者‘#’号,为了完成这个目的我们要判断该坐标是否被占用(毕竟我们玩三子棋也不能把别人的棋子丢掉放我们的棋子)以及该棋子坐标是否超出了棋盘的范围。这样我们就需要一个循环结构,我用的是 while 循环,我们利用循环结构就可以让玩家反复执行下棋动作直到玩家下到合适的地方。
值得一提的是,玩家输入的坐标是1~3而数组下标是0~2,那么我们需要对这里的数据进行一定的处理(指减去一个1)。
void player(char board[H][L], int h, int l)
{
printf("玩家下*:\n");
int i = 0;
int j = 0;
while (1)
{
scanf("%d%d",&i,&j);
if (i >= 1 && i <= h && j >= 1 && j <= l)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("坐标已被占用,请重新输入!\n");
}
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
}
电脑的下棋动作我利用 srand (srand可以直接在主函数开头设置) 和 rand 随机生成小于等于2(数组三个元素那么下标即为0~2)的值作为坐标,这时我们需要像上面一样验证坐标的合理性,但是这时候我们就不需要对玩家进行解释了,只需要用一个 while 语句就可以了。
void computer(char board[H][L], int h, int l)
{
while (1)
{
int i = rand() % 3;
int j = rand() % 3;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
三子棋有三种获胜方式即‘横’、‘竖’、‘斜’,我们可以在玩家和电脑下完棋后,设计函数返回值来判断胜利及平局等情况,后续利用返回值的分支就可以令程序呈现出判断后的结果。
char is_win(char board[H][L], int h, int l)
{
int i = 0;
int j = 0;
for (i = 0; i < h; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
return board[i][0];
}
for (j = 0; j < l; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
return board[0][j];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[0][0];
if(board[0][2]== board[1][1]&&board[1][1]==board[2][0]&&board[1][1]!=' ')
return board[0][0];
int tmp = 0;
for (i = 0; i < h; i++)
{
for (j = 0; j < l; j++)
{
if (board[i][j] == ' ')
tmp = 1;
}
}
if (tmp == 0)
return 'p';
else
return 'c';
}
最后只要将上述的函数按照我们三子棋的大致流程在game()中完成排序和整合就可以了,这里用循环结构执行双方下棋的前后流程。
void game()
{
char board[H][L];
char ret = 0;
chushi(board, H, L);
dayin(board, H, L);
while (1)
{
player(board, H, L);
dayin(board, H, L);
ret = is_win(board, H, L);
if (ret != 'c')
break;
computer(board, H, L);
dayin(board, H, L);
ret = is_win(board, H, L);
if (ret != 'c')
break;
}
if (ret == '*')
{
printf("玩家获胜。。。\n");
}
else if (ret == '#')
{
printf("电脑获胜!\n");
}
else if(ret == 'p')
{
printf("平局!\n");
}
}
以上的文章中,我们一起学习了C语言基础中的经典节目 三子棋 ,在今后的日子中,小狮子希望自己能保持常常更新博客的好习惯,和大家一起成长进步!
本狮的能力有限,这个三子棋的小游戏会有更多的优化空间,大家可以期待一下我的后续,或者大家在看完我的文章后也可以帮我优化下代码噢❤️!
在文章的最后,谢谢大家的观看,这里希望大家可以为我的第一篇博客打分૮(˶ᵔ ᵕ ᵔ˶)ა