意在加深自己的代码逻辑
前言
提示:这里可以添加本文要记录的大概内容:
在经过初步的c语言的学习后(函数,循环,if else等),我们可以用所学的知识写一个简单的小项目,为三子棋。
三子棋的游戏玩法:两个下棋手在一个3 x 3 的方格中下棋,当一方的棋子可以横向,或者竖向,斜向满三个时,即为胜利。
本文介绍的小游戏为人机对战,机器没有实现下棋逻辑,就是单纯的乱下,要输也很难。。在日后学的更多时应该会升级成有逻辑的对战。
一,整体思路:
用 | 号和 --- 号拼凑成一副棋盘,在他们的相隔处用一个3 x 3的数组中的元素作为棋子,将数组填满不可见的空格符号,后续对数组元素的空格操作并改为可视化元素,最后进行胜负的判断 if 语句及可。
首先进入准备工作,创建一个3 x 3的数组 :
#define ROW 3 //使用宏定义让程序具有更高的操作性,比如让棋盘变为4 x 4,5 x 5等;
#define LINE 3
int main()
{
char arr[ROW][LINE];
return 0;
}
接下来把里面的元素都改为空格(看不见的元素):用一个函数写,参数使用数组,row 和 line 表示遍历的数组的大小;
void InitBorad(char arr[ROW][LINE], int row, int line)//初始化棋盘
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < line; j++)
{
arr[i][j] = ' ';
}
}
}
二,实现:
1,下棋第一件事即为棋盘和棋子:在本程序中采用的棋盘如下:
void PrintBorad(char arr[ROW][LINE], int row, int line)//打印棋盘
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < line; ++j)
{
printf(" %c ", arr[i][j]);//在棋盘中插入数据
if (j < line - 1)//少打印一个 | ,使看起来更美观
printf("|");
}
printf("\n");//换行,打印下一行
for (int j = 0; j < line; ++j)//组成本行与下一行的分界线
{
printf("---");
if (j < line - 1)
printf("|");
}
printf("\n");//换行
}
printf("\n");
}
棋子:玩家用 * 号当作棋子,电脑则用 #
2,有了棋盘和棋子,接下来首先实现玩家和电脑下棋代码:
思路:用【】操作符更改数组中的元素,让玩家输入横竖两个数组,代表坐标,检查里面是否空格,是的话代表空位,可以用 玩家的棋子替代( * ),如果不为空格,代表已有元素,运用循环让玩家重新输入:
void PlayerMove(char arr[ROW][LINE], int row, int line)
{
int x = 0; // 两个坐标,按自己喜欢的来就行
int y = 0;
while (1)
{
printf("请玩家输入,两个数字之间用空格隔开:");
scanf("%d %d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= line)//输入的数字要符合数字下标的大小:即为坐标合法
{
if (arr[x - 1][y - 1] == ' ')//查看是否为空格
{
printf("输入成功\n");
arr[x - 1][y - 1] = '*';//是的话即替代
PrintBorad(arr, ROW, LINE);//输入完成后可以打印棋盘观看情况,看个人意愿;
break;
}
else
{
printf("该位置已有棋子,请重新输入\n");
}
}
else
{
printf("坐标不合法,请重新输入\n");
}
}
}
同理:实现机器的输入,但是输入的两个数为随机值,即没有逻辑的乱输入:运用rand函数 和 %函数即可
void ComputerMove(char arr[ROW][LINE], int row, int line)//机器输入
{
int x = 0;
int y = 0;
while (1)
{
x = rand() % row; // 任何一个数a % 一个数b 就会产生 0 到 b- 1的数字,很简单的数学,不同随便查查就好了
y = rand() % line;
if (arr[x][y] == ' ')
{
printf("机器输入:\n");
arr[x][y] = '#';
PrintBorad(arr, ROW, LINE);
break;
}
}
}
3,检查输赢:
写一个函数来检查,希望函数实现下面四个功能:
- 判断玩家胜利 (参考三子棋规则)
- 判断电脑胜利(这能输就真蠢了)
- 判断是否为平局
- 无事发生,继续下棋
char Win(char arr[ROW][LINE], int row, int line)
{
//1 判断玩家胜利,返回*
//2 判断电脑胜利,返回#
//3 平局,返回%
//游戏继续$
//为何要返回符号,参考下面一张图!!!!!
for (int i = 0; i < row; ++i)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][2] != ' ')
{
return arr[i][0];
}//判断横向相同
}
for (int i = 0; i < row; ++i)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[2][i] != ' ')
{
return arr[0][i];
}//判断竖向相同
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[2][2] != ' ')
{
return arr[0][0];
}//判断从左到右的斜向是否相同相同
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
{
return arr[0][2];
}//判断从右到左的
if (BoradFull(arr, row, line))//检查棋盘满了没,为平局的基本条件:
{
return '%';
}
char z = '$';
return z;
}
int BoradFull(char arr[ROW][LINE], int row, int line)
{
//检查棋盘满了没,一个辅助的函数罢了
//要是有空格代表没满,返回值作判断条件,什么类型都可以
for (int i = 0; i < row; i++)
{
for (int j = 0; j < line; j++)
{
if(arr[i][j] == ' ')//注意这个== 号, 我写的时候不小心写出 = 号了,调了半个多小时
return 0;
}
}
}
要让程序自动进行下去,我们可以写一个循环:
void game()
{
char arr[ROW][LINE] = { 0 };
srand((unsigned int)time(NULL));//这是rand函数用的
InitBorad(arr, ROW, LINE);
PrintBorad(arr, ROW, LINE);
char j = 0;//用这个接受检查输赢的返回值
while (1)
{
PlayerMove(arr, ROW, LINE);
j = Win(arr, ROW, LINE);//每次输入都要判断一下
if (j != '$')
break;//要是有结果了就退出循环
ComputerMove(arr, ROW, LINE);
j = Win(arr, ROW, LINE);
if (j != '$')
break;
}
//用不同的返回值决定成果
if (j == '*')
{
PrintBorad(arr, ROW, LINE);
printf("玩家胜利\n");
}
if (j == '#')
{
PrintBorad(arr, ROW, LINE);
printf("机器胜利\n");
}
if (j == '%')
{
PrintBorad(arr, ROW, LINE);
printf("平局\n");
}
printf("不想玩了就退出去\n");
}