❤️ 简单C语言知识实现三子棋
前言:
在学习编程过程中,我之前总是存在一个误区。那就是我得学富五车,才高八斗之后才能去尝试写一些高级的东西。我想肯定也有许多同学和我有相同的想法。其实这个观点是极其错误的,它甚至严重阻碍了我们进一步的去探索,去创新。比如,今天我们所写的三子棋代码,其实就是简单的用了函数、数组以及循环就轻轻松松做出来的。
查看详细代码移步到代码仓库------------>三子棋
文章目录
💗 三子棋游戏实现思想
代码实现的过程
- 先打印出目录,让玩家选择是否开始游戏,在玩家玩完一局游戏后,再次打印目录,让玩家选择是否再次进行游戏
- 定义一个二维数组作为棋盘,同时初始化它。
- 打印棋盘,让玩家可视。
- 将玩家所下的棋储存到棋盘中
- 判断游戏状态(输、赢、平局、继续)
- 将电脑所下的棋储存到棋盘中
- 判断游戏状态(输、赢、平局、继续)
💙 代码实现
🐱 打印目录
void list()
{
printf("**********************************\n");
printf("**********************************\n");
printf("*********开始游戏—> 1**************\n");
printf("*********退出游戏—> 0**************\n");
printf("**********************************\n");
printf("**********************************\n");
}
记得提示玩家输入 1 开始游戏,输入0退出游戏!
🐶 初始化棋盘
void init_chess(char arr[ROW][COL],int row,int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
arr[i][j] = ' '; //单个字符要用单引号
}
}
}
我们肯定希望在玩家和电脑都未下棋时,棋盘上就不显示内容,所以这时可以用空格这一字符来初始化棋盘,制造一种什么都没有的假象!
但这里笔者比较愚蠢的是,忽略了在C语言中单个字符只能用单引号表示,而不能用双引号,最近学python学傻了。希望大家吸取教训!
🐑 打印棋盘
void print_chess(char arr[ROW][COL],int row,int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (j < col - 1)
{
printf(" %c |", arr[i][j]);
}
else
{
printf(" %c ", arr[i][j]);
}
}
printf("\n"); //注意换行
for (j = 0; j < col; j++)
{
printf("----");
}
printf("\n");
}
}
打印棋盘的时候,大家按照自己想要的棋盘格式打印就可,每个人有每个人的风格,这里仅供参考!
但是还是有些需要注意的地方:比如换行,换行代码所在的位置务必放置正确,否则会出现输出格式错误的现象。应当是每行打印完之后再换,既放在i++之前!
🐰 玩家下棋
void game_chess(char arr[ROW][COL], int row, int col)
{
while (1)
{
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);// 1 11
if ((x<1 || x>row) || (y<1 || y>col))//条件满足就进入
{
printf("坐标违法,请重新输入\n");
}
else
{
if (arr[x-1][y-1] == ' ') //注意这里也要减
{
arr[x - 1][y - 1] = '#'; //优化为 √
break;
}
else
{
printf("该位置已被占用,请重新输入坐标\n");
}
}
}
}
玩家下棋只需要输入坐标即可,但是难免不了一些同学调皮地输入违法的坐标,因此我们需要对玩家输入的坐标进行判断后再执行下一步。如果坐标输入违法,应当给出温馨的提示!
当玩家输入正确的坐标后,我们还得进行判断该位置是否已经被下棋了,然后才能执行下一步。如果被提前下了,应当给出温馨的提示!
当玩家输入正确后即可将该位置下棋!
下好棋后进行棋局状态判断!
同时打印出棋盘!
🐒 判断棋局状态
char win(char arr[ROW][COL], int row, int col)
{
//判断行
int i = 0;
int j = 0;
int num = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col-1; j++)
{
if (arr[i][j] == arr[i][j + 1] && arr[i][j] != ' ')
{
num = num+1;
}
else
{
num = 0; //只要中间隔了一次不相等,num就重新赋值为0
}
if (dragon - 1 == num) //判断到底是几字成龙即可获胜 如果是五子成龙,则count等于四即可
{
return arr[i][j];
}
}
}
//判断列
num = 0; //此处要将num重新赋值为0 因为经过上面的代码后count的值已经发生变化
for (i = 0; i < col; i++)
{
for (j = 0; j < row - 1; j++)
{
if (arr[j][i] == arr[j + 1][i] && arr[j][i] != ' ')
{
num = num + 1;
}
else
{
num = 0;
}
if (dragon - 1 == num) //判断到底是几字成龙即可获胜 如果是五子成龙,则num等于四即可
{
return arr[j][i]; //返回arr[j][i] 而不是i j
}
}
}
//判读对角线
num = 0; //再次给num赋值
for (i = 0,j = 0; i < row; i++,j++)
{
if (arr[i][j] == arr[i + 1][j + 1] && arr[i][j] != ' ')
{
num = num + 1;
}
else
{
num = 0;
}
if (dragon - 1 == num)
{
return arr[i][j];
}
}
num = 0; //再次给num重新赋值
for (i = 0,j = col-1 ; i <row&&j>=0; i++,j--)
{
if (arr[i][j] == arr[i + 1][j - 1] && arr[i][j] != ' ')
{
num = num + 1;
}
else
{
num = 0;
}
if (dragon - 1 == num)
{
return arr[i][j];
}
}
//判断是平局还是继续
num = 0;//再次给count重新赋值
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ') //为空格就进入条件
{
num = 1;
}
}
}
if (num == 0) //是判断不是赋值
{
return 'E'; //返回就意味着平局
}
else
{
return 'C'; //返回就意味着继续游戏
}
}
if (final != 'C')
{
if (final == '#')
{
printf("玩家获胜\n");
print_chess(arr, row, col);
}
else if (final == '*')
{
printf("电脑获胜\n");
print_chess(arr, row, col);
}
else
{
printf("平局\n");
print_chess(arr, row, col);
}
break;
}
判断棋局状态无非就四种:赢、输、平局、游戏继续
方法就是:判断行、列以及两条对角线上是否连线成龙即可。
若游戏继续,则进行电脑下棋。
🐘 电脑下棋
void computer_chess(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
x = rand() % row; //范围为0~~9
y = rand() % col;
if (arr[x][y] == ' ')
{
arr[x][y] = '*';
break;
}
}
}
电脑下棋就比玩家下棋要简单一些,这里需要提到的一个知识点就是这个rand函数。
rand:生成一个伪随机数
rand函数原型------->int rand (void)
调用rand函数前要先调用srand函数,以便每次产生的随机数不同。对于代码中存在的多个rand函数,只需要将一个srand函数放在主函数之中调用一次即可。
srand函数原型------->>void srand( unsigned int seed )
为了能产生不同的随机数,srand函数的应写成 srand((unsigned int )time(NULL))
time函数原型-------->time_t time(time_t *timer )
time函数返回从1970年1月1日00:00:00到当前时刻的秒数(转化为整数),因此每秒返回的值都不相同。
rand函数和srand函数对应的头文件为<stdlib.h> time函数对应的头文件为<time.h>
rand函数好比一块土壤,土壤上需要种子去播种,如果没有种子播种,那么土壤上长出的东西必然是单一的。而srand就好比种子库,里面可以存放各式各样的种子,但是仓库中要想有各式各样的种子,那我们就得提前放入各式各样的种子,否则土壤上还是贫瘠的。而time函数就是这个放入各式各样种子的人。之后就可以保证土壤上每次长出的东西不同了。
电脑下好棋后同样也得先进行判断游戏状态,再打印出电脑下好棋之后的棋盘。
如果游戏继续,则再次进行玩家下棋。
于是可以看出,这里其实为一个循环结构,我们将它放入while循环中即可。
💚 代码书写过程中应该注意的事项
- 游戏进行时,应尽可能给玩家合理的提示,让玩家知晓游戏的运行方式。
- 编写代码的时候要进行合理的注释,方便自己或他人看懂代码。
- 代码编写的时候,英文字母的大小写往往有不成文的规则,应当善用字母大小写。
这里我只给出了每个功能相应的函数代码,大家若想看整个详细的代码实现,可以移步到仓库进行查看!
💛 总结
从来都是以为,只有一切准备好了之后再出发,才会有十足的勇气!可是学习的道路中,到底什么是准备好,什么是学富五车,谁也不能下个定义吧。不妨自己先走走,走出一条属于自己的路子来!