为了实现三子棋游戏,首先要知道三子棋游戏需要做到那些关键步骤,明白每一步步骤,然后按照步骤,将代码分步写出来。复杂的代码是由一个个最简单的代码块复合起来的。
咋们现在来看看三子棋游戏需要怎演的步骤才能将其实现。
- 进行一个游戏开始的选择,即是否进行游戏,如果不进行游戏,那就退出。在这一步的实现的时候,还要考虑到在一次游戏结束后,如果还要再进行游戏,不需要进行重新运行代码,而是进行一个循环,进行一个选择,然后继续运行程序的运行。
- 第二部是进行一个游戏棋盘的打印。游戏的开始,是需要向玩家展示游戏的期盼布局的。在这一步的时候,除了进行棋盘的打印外,我们还可以在棋盘上加上行标和列标,方便下棋时行和列的选择。
- 第三步就是数据的输入,然后判断输入的数据的有效性。
- 第四部便是游戏主题代码的实现,对输入的数据进行处理,然后再一次打印在屏幕上。
- 第五步是进行一个游戏胜负的判定,判断输赢,然后打印在屏幕上,并为是否再次进行游戏进行判定,达到与步骤一形成一个循环。
这是游戏的基本步骤,现在要考虑的是,如何进行游戏具体步骤的实现。
步骤一:进行一个游戏开始的选择,即是否进行游戏,如果不进行游戏,那就退出。在这一步的实现的时候,还要考虑到在一次游戏结束后,如果还要再进行游戏,不需要进行重新运行代码,而是进行一个循环,进行一个选择,然后继续运行程序的运行。
int main()
{
srand((unsigned int)time(NULL));
int key = 0;
char GameArr[ROW][COL];
while (1)
{
printf("***************************\n");
printf("*** 1.PvE ***\n");
printf("*** 2.PvP ***\n");
printf("*** 0.exit ***\n");
printf("**************************\n");
printf("请选择:>");
scanf("%d", &key);
while(key > 2 || key < 0)
{
printf("输入有误,请重新选择:>");
scanf("%d", &key);
}
PrintGame();
if (key == 0)
{
break;
}
else if (key == 1)
{
PvE_Game(GameArr);
}
else if (key == 2)
{
PvP_Game(GameArr);
}
}
system("pause");
return 0;
}
// 头文件
#define ROW 5
#define COL 5
#include<time.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void PrintGame();
void PvE_Game(char GameArr[ROW][COL]);
void PeoPrint(int row, int col);
void PvP_Game(char GameArr[ROW][COL]);
这便是我的main函数,PvP只是我自己添加的,可以根据自己的需要进行添加。我在main函数中完成了游戏的循环进行,并且进行了游戏选择时数据输入有效性的判断。在游戏开始的时候,我定义了两个全局常量,ROW和COL,这两个全局常量,表示的是在一个二维数组中(棋盘)中的行和列,通过定义全局常量将棋盘大小固定,在程序过程中不能被改变,而在需要改变棋盘的大小的时候,可以仅通过这两个全局常量的改变,完成对棋盘大小的修改,使代码灵活性增加了。
并且我还在这部分进行了一个随机数的获取 srand((unsigned int)time(NULL)) ,这是为了后面在实现与电脑下棋时,电脑获得随机的下棋位置。
步骤二:第二部是进行一个游戏棋盘的打印。游戏的开始,是需要向玩家展示游戏的期盼布局的。在这一步的时候,除了进行棋盘的打印外,我们还可以在棋盘上加上行标和列标,方便下棋时行和列的选择。
void PrintGame()
{
int col = 0;
int row = 0;
int k = 0;
int x = 1;
int y = 1;
while (x <= COL)//列标打打印
{
printf(" %d ", x);
if (x == COL)
{
printf("\n");
}
x++;
}
while (1)
{
printf("%d ", y);//每行开始时行标的打印
y++;
for (col = 1; col <= COL; ++col)//每一行中的每一个元素的打印
{
if (col == COL)
{
printf(" \n");
break;
}
printf(" |");
}
k++;
if (k == ROW)//进行一个行是否打印完的判定,如果所有行都打印完了,但就跳出打印循环
{
break;
}
printf(" ");
for (row = 1; row <= COL; ++row)//每行的分割线的打印
{
if (row == COL)
{
printf("---\n");
break;
}
printf("---|");
}
}
}
步骤三:游戏主题代码的实现,对输入的数据进行处理,然后再一次打印在屏幕上。
void PvE_Game(char GameArr[ROW][COL])
{
int row = 0;
int col = 0;
int chick = 0;
char game[ROW][COL] = { NULL };
while (1)
{
printf("请输入下棋位置:>");
while (1)
{
printf("行:");
scanf("%d", &row);
printf("列: ");
scanf("%d", &col);
if (game[row - 1][col - 1] == '*' || game[row - 1][col - 1] == '#')//数据有效性的判断
{
printf("输入的位置重复,请重新输入:>\n");
continue;
}
else if ((row > ROW) || (col > COL))
{
printf("数据输入有误,请重新输入:>");
continue;
}
else
{
break;
}
}
game[row-1][col-1] = '*';//将玩家输入的有效下棋坐标置为玩家下棋标记
system("cls");//进行一次屏幕清空,消去先前打印在屏幕上的东西
PrintComputer(game);//电脑获得自己的随机下棋位置,并进行棋盘的打印
chick = ChickWin(game);//检查胜负,并获得返回值,
if (chick == 1)
{
break;
}
}
}
static void PrintComputer(char Game[ROW][COL])
{
int row = 1;
int col = 1;
int k = 0;
int x = 1;
int y = 1;
while (1)
{
row =rand()%(ROW-1);//随机数的获取
col =rand()%(COL-1);//随机数的获取
if (Game[row][col] != '*'&&Game[row][col] != '#')//判断这个随机位置的元素是否已经存在,如果存在那就重新获得一个随机位置
{
Game[row][col] = '#';
break;
}
else
{
continue;
}
}
while (x <= COL)
{
printf(" %d ", x);
if (x == COL)
{
printf("\n");
}
x++;
}
for (row = 1; row <= ROW; ++row)
{
printf("%d ", y);
y++;
for (col = 1; col <= COL; ++col)
{
if (Game[row - 1][col - 1] == '#')
{
if (col == COL)
{
printf(" # \n");
break;
}
else
{
printf(" # |");
continue;
}
}
if (Game[row - 1][col - 1] == '*')
{
if (col == COL)
{
printf(" * \n");
break;
}
else
{
printf(" * |");
continue;
}
}
if (col == COL)
{
printf(" \n");
break;
}
printf(" |");
}
k++;
if (k == ROW)
{
break;
}
printf(" ");
for (col = 1; col <= COL; ++col)
{
if (col == COL)
{
printf("---\n");
break;
}
printf("---|");
}
}
}
步骤四:进行输赢检测
static int ChickWin(char Game[ROW][COL])
{
int row = 1;
int col = 1;
for (row = 1; row <= ROW - 2; ++row)
{
for (col = 1; col <= COL - 2; ++col)
{
if (Game[row - 1][col - 1] == '*'&&Game[row - 1][col] == '*'&&Game[row - 1][col + 1] == '*')//x1
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row][col - 1] == '*'&&Game[row][col] == '*'&&Game[row][col + 1] == '*')//x2
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row + 1][col - 1] == '*'&&Game[row + 1][col] == '*'&&Game[row + 1][col + 1] == '*')//x3
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row - 1][col - 1] == '*'&&Game[row][col - 1] == '*'&&Game[row + 1][col - 1] == '*')//y1
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row - 1][col] == '*'&&Game[row][col] == '*'&&Game[row + 1][col] == '*')//y2
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row - 1][col + 1] == '*'&&Game[row][col + 1] == '*'&&Game[row + 1][col + 1] == '*')//y3
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row - 1][col - 1] == '*'&&Game[row][col] == '*'&&Game[row + 1][col + 1] == '*')//xy1
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row + 1][col - 1] == '*'&&Game[row][col] == '*'&&Game[row - 1][col + 1] == '*')//xy2
{
printf("玩家胜利!\n");
return 1;
}
if (Game[row - 1][col - 1] == '#'&&Game[row - 1][col] == '#'&&Game[row - 1][col + 1] == '#')//x1
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row][col - 1] == '#'&&Game[row][col] == '#'&&Game[row][col + 1] == '#')//x2
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row + 1][col - 1] == '#'&&Game[row + 1][col] == '#'&&Game[row + 1][col + 1] == '#')//x3
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row - 1][col - 1] == '#'&&Game[row][col - 1] == '#'&&Game[row + 1][col - 1] == '#')//y1
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row - 1][col] == '#'&&Game[row][col] == '#'&&Game[row + 1][col] == '#')//y2
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row - 1][col + 1] == '#'&&Game[row][col + 1] == '#'&&Game[row + 1][col + 1] == '#')//y3
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row - 1][col - 1] == '#'&&Game[row][col] == '#'&&Game[row + 1][col + 1] == '#')//xy1
{
printf("电脑胜利!\n");
return 1;
}
if (Game[row + 1][col - 1] == '#'&&Game[row][col] == '#'&&Game[row - 1][col + 1] == '#')//xy2
{
printf("电脑胜利!\n");
return 1;
}
}
}
}
这一部分代码看着非常复杂,而且多,其实并不难理解,就是对从第一行第一列的元素开始进行检查,如果有三个相同的标记字符在一条线上,那就输出胜负。注意,这里一定不要进行数组的越界访问!!!在一开始循环的时候,一定要限制循环的结束条件,不让ChickWin函数越界访问。
这便是三子棋游戏,当然也可以对这个代码进行添加,比如实现PvP等,或者对电脑进行优化,是电脑实现AI,都是可以的。