计项01组02号C 语言快速实现五子棋1.0
Posted SYF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计项01组02号C 语言快速实现五子棋1.0相关的知识,希望对你有一定的参考价值。
1.1 实验内容
五子棋大家一定都玩过,想不想试着用 C 语言来实现一个简易版的五子棋呢?下面就让我们现在开始,用最简单易懂的代码来编写一个控制台下的五子棋,并逐步完善它,每个人都能轻松学会哦!
1.2 知识点
- 游戏的逻辑
- 判断结果的算法
- 界面的设计
2.1 设计棋盘
注:实验楼环境无法输入中文,可以用O和X来代替棋子
我们首先需要一个棋盘(15 * 15),记录棋盘中每一个位置的“情况”。 那么我们可以定义一个 chessboard[16][16] 的数组,为什么不是 [15][15] 呢?因为这样我们就可以让数组的坐标正好对应棋盘的行和列,方便后面代码的编写。
查看代码
#include <stdio.h>
#define N 15
//定义一个数组并为每一个元素赋初值0
int chessboard[N + 1][N + 1] = 0 ;
2.2、main函数的编写
开始编写主函数之前,我们先简单的考虑一下,一个游戏通常的流程是怎么样的 (⊙o⊙?)首 先肯定是进入游戏的一个主界面,然后点击开始按钮进入游戏,接着显示游戏画面,判断输赢,游戏结束。那么一个五子棋游戏的流程呢?
查看代码
//用来记录轮到玩家1还是玩家2,奇数表示轮到玩家1,偶数轮到玩家2
int whoseTurn = 0;
int main(void)
//自定义函数,用来初始化游戏,也就是显示欢迎界面并且进入游戏显示棋盘
initGame();
//这个循环就是用来让两个玩家轮流落子的
while (1)
//每次循环自增1,这样就可以做到2人轮流
whoseTurn++;
//自定义函数,用来执行落子操作
playChess();
return 0;
2.3、initGame函数
在这个函数中,我们要实现的功能是
- 显示一个简单的欢迎界面
- 要求输入Y之后显示出棋盘
下面,我们就开始吧!
查看代码
void initGame(void)
char c;
printf("欢迎^_^请输入y进入游戏:");
c = getchar();
if (\'y\' != c && \'Y\' != c)
exit(0);
//清屏,windows下为system("cls")
system("clear");
//这里我们又调用了一个自定义函数,函数的功能是打印出棋盘
printChessboard();
我们在 initGame 函数中使用了 exit 以及 system 这两个函数,所以要在程序的最上面包含 stdlib.h 这个头文件
查看代码
#include <stdlib.h>
2.4、printChessboard 函数
功能:
- 打印出行号和列号,并打印出棋盘
- 数组元素的值为0,打印出星号(*),表示该位置没有人落子
- 数组元素的值为1,打印实心圆(X,玩家1的棋子)
- 数组元素的值为2,打印空心圆(O,玩家2的棋子)
查看代码
void printChessboard(void)
int i, j;
for (i = 0; i <= N; i++)
for (j = 0; j <= N; j++)
if (0 == i) //这样可以打印出列号
printf("%3d", j);
else if (j == 0) //打印出行号
printf("%3d", i);
else if (1 == chessboard[i][j])
//windows下●占2列,前面只需加一个空格
printf(" X");
else if (2 == chessboard[i][j])
printf(" O");
else
printf(" *");
printf("\\n");
2.5、 playChess 函数
函数功能:
- 要求玩家输入准备落子的位置
- 如果当前是玩家1落子,就将1赋值给数组中对应位置的元素
- 如果当前是玩家2落子,就将2赋值给数组中对应位置的元素
- 每次落子完毕,判断当前玩家是否获胜
查看代码
void playChess(void)
int i, j, winner;
//判断轮到玩家1还是玩家2,然后把值赋给数组中对应的元素
if (1 == whoseTurn % 2)
printf("轮到玩家1,请输入棋子的位置,格式为行号+空格+列号:");
scanf("%d %d", &i, &j);
chessboard[i][j] = 1;
else
printf("轮到玩家2,请输入棋子的位置,格式为行号+空格+列号:");
scanf("%d %d", &i, &j);
chessboard[i][j] = 2;
//重新打印一次棋盘
system("clear");
printChessboard(); //再次调用了这个函数
/*
*下面这段调用了自定义函数(judge函数)
*用来判断当前玩家下完这步棋后,他有没有获胜
*具体怎么判断的,马上就给大家解释哦
*/
if (judge(i, j, whoseTurn))
if (1 == whoseTurn % 2)
printf("玩家1胜!\\n");
else
printf("玩家2胜!\\n");
2.6、judge函数
函数参数:
- x:当前落子的行号
- y:当前落子的列号
返回值:
- 1或0。1表示当前玩家落子之后出现五子连一线,也就是当前玩家获胜
查看代码
int judge(int x, int y)
int i, j;
int t = 2 - whoseTurn % 2;
const int step[4][2]=-1,0,0,-1,1,1,1,0;
for(int i=0;i<4;++i)
const int d[2]=-1,1;
int count=1;
for(int j=0;j<2;++j)
for(int k=1;k<=4;++k)
int row=x+k*d[j]*step[i][0];
int col=y+k*d[j]*step[i][1];
if( row>=1 && row<=N && col>=1 && col<=N &&
chessboard[x][y]==chessboard[row][col])
count+=1;
else
break;
if(count>=5)
return 1;
return 0;
judge 这个函数中,有 3 个嵌套的 for 循环,这 3 个循环的目的在于判断是否有五子连城一条线。
五子连线,无非是在一行上,一列或者斜方向上有连续的五个子。在这里,我们将采取一种试探的方法,即沿着水平,竖直,倾斜等方向分别寻找是否有五子连线。下面举一个例子:
在上面的对局中,我们以(9,10)来讲解判断五子是否成线的算法。
首先判断(9,10)的倾斜方向是否出现五子连线,判断方式如下:
- 以(9,10)为起点,向左上方向依此寻找,满足条件的坐标分别是(8,9),(7,8),(6,7)。因为(5,6)不满足条件,所以进入下一步
- 然后在向右下方寻找,找到(10,11),仅有一个满足条件的点。
- 然后一共找到五个在同一直线上的点,所以玩家二取得胜利,
如果倾斜方向不满足取胜的条件,就再判断竖直方向,水平方向,如果均不成立,这意味着当前玩家无法取得胜利,对局将会继续。
到这里,我们的五子棋游戏就基本上完成了。不过,我们的项目课并没有结束,我们还要对项目做一个后期的维护工作。
3.1 我的棋子被“吃”了
不知道大家发现没有,我们的五子棋小游戏在落子时,即便是落子的位置已经被占用,依旧可以“吃掉”原棋子。 这是因为我们在写 playChess 函数的时候,没有对落子位置进行检测。我们可以这样修改我们的代码:
查看代码
void playChess(void)
int i, j, winner;
if (1 == whoseTurn % 2)
printf("轮到玩家1,请输入棋子的位置,格式为行号+空格+列号:");
scanf("%d %d", &i, &j);
//修复BUG
while(chessboard[i][j] != 0)
printf("您要下的位置已经被占用了哦,请重新输入:");
scanf("%d %d", &i, &j);
//修复BUG
chessboard[i][j] = 1;
else
printf("轮到玩家2,请输入棋子的位置,格式为行号+空格+列号:");
scanf("%d %d", &i, &j);
//修复BUG
while(chessboard[i][j] != 0)
printf("您要下的位置已经被占用了哦,请重新输入:");
scanf("%d %d", &i, &j);
//修复BUG
chessboard[i][j] = 2;
system("clear");
printChessboard();
if (judge(i, j))
if (1 == whoseTurn % 2)
printf("玩家1胜!\\n");
else
printf("玩家2胜!\\n");
在函数中加入一个循环,当落子位置已经被占用时,给出提示,并且要求重新输入。
3.2 我怎么永远赢不了
当出现五子连线的时候,提示玩家1或玩家2获胜之后,又提示“轮到玩家*,请输入棋子位置……” 是不是很郁闷呢? 其实我们只要加一句代码就行!
查看代码
if (judge(i, j))
if (1 == whoseTurn % 2)
printf("玩家1胜!\\n");
exit(0); //修复BUG
else
printf("玩家2胜!\\n");
exit(0); //修复BUG
在获胜后除了提示玩家某某获胜意外,退出游戏exit(0)
源代码
查看代码
#include <stdio.h>
#include <stdlib.h>
#define N 15
int chessboard[N+1][N+1]=0;
int whoseTurn=0;
void initGame(void);
void printChessboard(void);
void playChess(void);
int judge(int ,int );
int main(void)
initGame();
while(1)
whoseTurn++;
playChess();
return 0;
void initGame(void)
char c;
printf("Please intput \\\'y\\\' to enter the game:");
c = getchar();
if(\'y\'!=c&&\'Y\'!=c)
exit(0);
system("clear");
printChessboard();
void printChessboard(void)
int i,j;
for(i=0;i<=N;i++)
for(j=0;j<=N;j++)
if(0==i)
printf("%3d",j);
else if(j==0)
printf("%3d",i);
else if(1==chessboard[i][j])
printf(" 0");
else if(2==chessboard[i][j])
printf(" X");
else
printf(" *");
printf("\\n");
void playChess(void)
int i,j,winner;
if(1==whoseTurn%2)
printf("Turn to player 1,please input the position:");
scanf("%d %d",&i,&j);
while(chessboard[i][j]!=0)
printf("This position has been occupied,please input the position again:");
scanf("%d %d",&i,&j);
chessboard[i][j]=1;
else
printf("Turn to player 2,please input the position:");
scanf("%d %d",&i,&j);
while(chessboard[i][j]!=0)
printf("This position has been occupied,please input the position again:");
scanf("%d %d",&i,&j);
chessboard[i][j]=1;
system("clear");
printChessboard();
if(judge(i,j))
if(1==whoseTurn%2)
printf("Winner is player 1!\\n");
exit(0);
else
printf("Winner is player 2!\\n");
exit(0);
int judge(int x,int y)
int i,j;
int t= 2 - whoseTurn%2;
const int step[4][2]=-1,0,0,-1,1,1,1,0;
for(int i=0;i<4;i++)
const int d[2]=-1.1;
int count=1;
for(int j=0;j<2;++j)
for(int k=1;k<=4;k++)
int row=x+k*d[j]*step[i][0];
int col=y+k*d[j]*step[i][1];
if(row>=1&&row<=N&&
col>=1&&col<=N&&
chessboard[x][y]==chessboard[row][col])
count+=1;
else
break;
if(count>=5)
return 1;
return 0;
以上是关于计项01组02号C 语言快速实现五子棋1.0的主要内容,如果未能解决你的问题,请参考以下文章