练手必备 | C 语言快速实现五子棋

关注「实验楼」,每天分享一个项目教程   

教你用最简单易懂的代码编写一个控制台下的五子棋!课程正在限免中,想学习的同学赶紧拿来练手!

正文共:2618 字 

预计阅读时间:7 分钟

五子棋大家一定都玩过,想不想试着用 C 语言来实现一个简易版的五子棋呢?下面就让我们现在开始,用最简单易懂的代码来编写一个控制台下的五子棋,并逐步完善它,每个人都能轻松学会哦!

知识点

  • 游戏的逻辑

  • 判断结果的算法

  • 界面的设计

实验环境

  • vim编辑器

  • Xfce终端

  • gcc编译器

适合人群

本课程比较简单,没有复杂的语法和逻辑,适合具有C基础的用户,一起探索和发现C语言可以做一些有趣的事情。

源码下载:

点击「 阅读原文 」进入课程,即可找到全部源码的下载地址。

效果截图:

( 大家看了截图,有没有一种想拍死我的冲动Σ( ° △ °|||)︴ )别急,看起来似乎很丑,实际上……确实很丑。不过没关系,这次的项目课,主要是给大家介绍一个小项目的开发流程,同时帮大家复习 C 语言基础知识,让大家轻松实现一个功能比较齐全的小游戏,后续我还会继续开设这一系列的项目课,带大家完善游戏功能和界面。废话有点多了,下面就让我们开始吧!

二、实验步骤

2.1 设计棋盘

注:实验楼环境无法输入中文,可以用O和X来代替棋子

我们首先需要一个棋盘(15 * 15),记录棋盘中每一个位置的“情况”。那么我们可以定义一个 chessboard[16][16] 的数组,为什么不是 [15][15] 呢?因为这样我们就可以让数组的坐标正好对应棋盘的行和列,方便后面代码的编写。

#include 

#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;
}

主函数大概就是这样了,是不是很简单明了呢?附一张用gedit编辑main函数的图:

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 

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),仅有一个满足条件的点。

  • 然后一共找到五个在同一直线上的点,所以玩家二取得胜利,

如果倾斜方向不满足取胜的条件,就再判断竖直方向,水平方向,如果均不成立,这意味着当前玩家无法取得胜利,对局将会继续。

三、修复 BUG


到这里,我们的五子棋游戏就基本上完成了。不过,我们的项目课并没有结束,这个游戏还有两个明显的BUG:

  • 已经落子的地方,依然可以落子,并“吃掉”原棋子。

  • 比赛结束后,仍提示下一个人落子,此时添加一个胜利的判定和提示即可。


如何修复这两个BUG及获取项目的全部源码请点击阅读文档~课程正在限免中欢迎大家用电脑登陆实验楼亲手把这个项目实现~


学习更多


楼+「 Python实战 」、「 Linux运维与Devops实战 」优惠报名中——来自腾讯、Intel、IBM等互联网大厂的一线大牛,带你12周内打通Python、Linux的任督二脉!

点击下面的链接了解详情:

一个暑假打通Python任督二脉!12周特训再次开启~

11周打通 Linux 任督二脉,实验楼技术天团带你飞!

他在一线互联网大厂研发PHP数年,用6周时间带你打通“全宇宙最好的语言”

你可能感兴趣的:(练手必备 | C 语言快速实现五子棋)