本篇文章带你明明白白理解三子棋,五子棋。
目录
下面我们将三子棋拆分成几个步骤:
菜单
首先我们要创建一个菜单。
具体代码如下:
void menu()
{
printf("--------------------------------------\n");
printf("--------------------------------------\n");
printf("1.play 0.exit \n");
printf("--------------------------------------\n");
printf("--------------------------------------\n");
}
棋盘
三子棋的棋盘我们采用二维数组方式实现。
首先我们对棋盘进行初始化,棋盘初始内容全为空格。
void Initboard(char r[ROW][COL])//初始化棋盘
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
r[i][j] = ' ';
}
}
}
接着我们所要做的操作是要把棋盘打印出来。
void Displayboard(char r[ROW][COL])
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf(" %c ", r[i][j]);//打印每行元素
if (j < COL - 1)
{
printf("|");
}
}
printf("\n");
if (i < ROW - 1)
{
for (int k = 0; k < COL ; k++)
{
printf("----");
}
}
printf("\n");
}
}
这样棋盘我们就创建完成了。
对弈
下面我们要实现玩家与电脑的对弈。
通过修改二维数组的内容,我们可以实现对弈。
玩家走
void PlayerMove(char r[ROW][COL])//玩家走
{
printf("玩家走\n");
printf("请输入坐标:");
int a = 0, b = 0;
while (1)
{
scanf_s("%d %d", &a, &b);
if (a >= 1 && a <= ROW && b >= 1 && b <= COL)
{
if (r[a-1][b-1] == ' ')
{
r[a-1][b-1] = '*';
break;//输入成功后退出
}
else
{
printf("非法坐标请重新输入:");//预防重复修改
}
}
else
{
printf("非法坐标请重新输入:");
}
}
}
电脑走
void ComputerMove(char r[ROW][COL])//电脑走
{
srand((size_t)time(NULL));
printf("电脑走:\n");
int a = 0, b = 0;
while (1)
{
a = rand() % ROW, b = rand() % COL;//采用随机值
if (r[a][b] == ' ')
{
r[a][b] = 'x';
break;
}
}
}
这样对弈过程就实现了。
下面就到了最关键的一步。
判断输赢
输赢有三种:行胜利,列胜利,对角线胜利。
首先我们要判断棋盘是否满。
int isfull(char r[ROW][COL])//判断棋盘是否满
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (r[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
接着判断输赢:
char _iswin(char r[ROW][COL])
{
int flag = 0;//通过flag的值来判断是否有符合条件的
for (int i = 0; i < ROW; i++)
{
flag = 1;
for (int j = 1; j < COL; j++)
{
if (r[i][j - 1] != r[i][j])
{
flag = 0;
}
}
if (flag == 1&&r[i][0]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[i][0];
}
}//行判断赢
for (int i = 0; i < ROW; i++)
{
flag = 1;
for (int j = 1; j < COL; j++)
{
if (r[j-1][i] != r[j][i])
{
flag = 0;
}
}
if (flag == 1&&r[0][i]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][i];
}
}//列判断赢
flag = 1;
for (int i = 1; i < ROW; i++)//对角线判断
{
if (r[i - 1][i - 1] != r[i][i])
{
flag = 0;
}
}
if (flag == 1&&r[0][0]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][0];
}
flag = 1;
for (int i = 0; i < ROW-1; i++)//对角线判断
{
if (r[i][COL - i - 1] != r[i + 1][COL - i - 1 - 1])
{
flag = 0;
}
}
if (flag == 1&&r[0][COL-1]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][COL - 1];
}
if (isfull(r))//棋盘已满,胜负未分
{
return 'Q';//平局
}
return 'C';//不满则继续
}
行列对角线判断输赢我们利用传递性实现,若a=b,b=c,那么a=b=c,这里同理,
a[0]=a[1],a[1]=a[2]-----------------以此类推。
要注意的是,棋盘初始内容全是空格,这就造成了大量内容的相等,对判断输赢有干扰,因此我们要加上条件:元素不为空格。
这里我们通过返回值来判断输赢,‘Q’表示平局,‘C’表示棋盘未满,要继续下棋。
完整代码如下:
三子棋.h:
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
void menu();//菜单
void Initboard(char r[ROW][COL]);//初始化棋盘
void Displayboard(char r[ROW][COL]);//打印棋盘
void PlayerMove(char r[ROW][COL]);//玩家走
void ComputerMove(char r[ROW][COL]);//电脑走
void game();
void iswin(char r[ROW][COL]);
三子棋.c
#include"三子棋.h"
void menu()
{
printf("--------------------------------------\n");
printf("--------------------------------------\n");
printf("1.play 0.exit \n");
printf("--------------------------------------\n");
printf("--------------------------------------\n");
}
void Initboard(char r[ROW][COL])//初始化棋盘
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
r[i][j] = ' ';
}
}
}
void Displayboard(char r[ROW][COL])
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf(" %c ", r[i][j]);//打印每行元素
if (j < COL - 1)
{
printf("|");
}
}
printf("\n");
if (i < ROW - 1)
{
for (int k = 0; k < COL ; k++)
{
printf("----");
}
}
printf("\n");
}
}
void PlayerMove(char r[ROW][COL])//玩家走
{
printf("玩家走\n");
printf("请输入坐标:");
int a = 0, b = 0;
while (1)
{
scanf_s("%d %d", &a, &b);
if (a >= 1 && a <= ROW && b >= 1 && b <= COL)
{
if (r[a-1][b-1] == ' ')
{
r[a-1][b-1] = '*';
break;//输入成功后退出
}
else
{
printf("非法坐标请重新输入:");//预防重复修改
}
}
else
{
printf("非法坐标请重新输入:");
}
}
}
void ComputerMove(char r[ROW][COL])//电脑走
{
srand((size_t)time(NULL));
printf("电脑走:\n");
int a = 0, b = 0;
while (1)
{
a = rand() % ROW, b = rand() % COL;//采用随机值
if (r[a][b] == ' ')
{
r[a][b] = 'x';
break;
}
}
}
int isfull(char r[ROW][COL])//判断棋盘是否满
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
if (r[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char _iswin(char r[ROW][COL])
{
int flag = 0;
for (int i = 0; i < ROW; i++)
{
flag = 1;
for (int j = 1; j < COL; j++)
{
if (r[i][j - 1] != r[i][j])
{
flag = 0;
}
}
if (flag == 1&&r[i][0]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[i][0];
}
}//行判断赢
for (int i = 0; i < ROW; i++)
{
flag = 1;
for (int j = 1; j < COL; j++)
{
if (r[j-1][i] != r[j][i])
{
flag = 0;
}
}
if (flag == 1&&r[0][i]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][i];
}
}//列判断赢
flag = 1;
for (int i = 1; i < ROW; i++)//对角线判断
{
if (r[i - 1][i - 1] != r[i][i])
{
flag = 0;
}
}
if (flag == 1&&r[0][0]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][0];
}
flag = 1;
for (int i = 0; i < ROW-1; i++)//对角线判断
{
if (r[i][COL - i - 1] != r[i + 1][COL - i - 1 - 1])
{
flag = 0;
}
}
if (flag == 1&&r[0][COL-1]!=' ')//要注意这里!元素不为空格,不然就是bug
{
return r[0][COL - 1];
}
if (isfull(r))
{
return 'Q';//平局
}
return 'C';//不满则继续
}
void game()
{
char ret = 0;
char a[ROW][COL]={0};
Initboard(a);
Displayboard(a);
while (1)
{
PlayerMove(a);
Displayboard(a);
ret = _iswin(a);
if (ret != 'C')
{
break;
}
ComputerMove(a);
Displayboard(a);
ret = _iswin(a);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
if (ret == 'x')
{
printf("电脑赢\n");
}
if (ret == 'Q')
{
printf("平局\n");
}
}
test.c
#include"三子棋.h"
int main()
{
int input = 0;
do
{
menu();
printf("请输入:");
scanf_s("%d", &input);
printf("\n");
switch (input)
{case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("请重新输入:\n");
break;
}
} while (input);
return 0;
}
五子棋
现在我们已经实现了三子棋,如何实现五子棋呢?
其实只要将头文件中的ROW和COL改成5就可以实现啦!
总结
希望本篇文章对于你有一些帮助,如果觉得不错,三连唔。