相信大家都玩过三子棋吧,在一个九宫格内,谁先实现三个棋子连线,谁就获得胜利!
今天,我们就一起用C语言来实现简易版的三子棋。
首先,我们的思路大致如下:
1.程序开始时打印菜单,让玩家选择开始游戏还是退出游戏
2.玩家选择游戏后进入游戏
3.判断输赢后,重新回到菜单
为了更好的管理代码,我们建立三个文件,分别是:
game.c 用于游戏函数的实现
game.h 用于游戏函数的声明
test.c 用于测试相关的游戏函数
程序主体框架如下:
该框架放在test.c文件中,用于调用游戏函数
enum Choose
{
EXIT,
PLAY
};
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case PLAY:
game();//选择了玩游戏后,调用game函数来进行游戏
break;
case EXIT:
printf("退出游戏\n");
break;
default:
printf("选择有误,请重新选择\n");
break;
}
} while (input);//当input为0时,推出循坏,结束程序
return 0;
}
菜单函数的实现:
该函数实现放在game.c文件中,方便调用,方便管理
而该函数的声明,我们放在game.h中即可,我们只需要在test.c中引用game.h头文件就可以使用该函数了
void menu()
{
printf("***************************\n");
printf("******* 1. play *******\n");
printf("******* 0. exit *******\n");
printf("***************************\n");
}
游戏函数的实现:
我们为了日后维护的方便,同时为了能够将三子棋升级为五子棋甚至更大的棋盘
我们在定义棋盘的时候,不要把大小写死,可以通过define来定义大小
define定义放在game.h中
#define ROW 3
#define COL 3
接下来就是重中之重的game函数实现
game函数里面,包括了棋盘(二维数组)创建的函数,棋盘初始化的函数,打印棋盘的函数,玩家下棋的函数,电脑下棋的函数,判断棋盘是否已满的函数以及判断玩家或者电脑是否赢了的函数
由于函数众多,我们就不一一在game函数内部定义,统一再game函数外定义,通过game函数调用来完成游戏过程
void game()
{
//该函数用于实现三子棋
//创建棋盘数组
char board[ROW][COL];
//初始化棋盘数组
Initboard(board,ROW,COL);
//打印棋盘
Printboard(board, ROW, COL);
while (1)
{
int ret = 0;
char tmp = 0;
//玩家输入坐标来下棋
Playermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判断是否赢了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家赢了\n");
break;
}
else if (tmp == '#')
{
printf("电脑赢了\n");
break;
}
//判断棋盘是否已满
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
//电脑下棋
Computermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判断是否赢了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家赢了\n");
break;
}
else if (tmp == '#')
{
printf("电脑赢了\n");
break;
}
//判断棋盘是否已满
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
}
}
棋盘初始化的函数:
void Initboard(char board[ROW][COL],int row,int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
*(*(board + i) + j) = ' ';
}
}
}
打印棋盘的函数:
打印棋盘我们可以通过循环的方法,但是要注意判断打印的条件
void Printboard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", *(*(board + i) + j));
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
for (j = 0; j < col; j++)
{
if (i < row - 1)
printf("--- ");
}
printf("\n");
}
}
玩家下棋的函数:
玩家通过输入坐标来下棋,同时要注意判断玩家输入的坐标是否再棋盘大小范围之内,还要判断玩家输入的坐标对应的位置有没有放棋子。
void Playermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请玩家输入:>\n");
scanf("%d %d", &x, &y);
//scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x-1][y-1] == ' ')
{
board[x-1][y-1] = '*';
break;
}
else
printf("该位置已被占用,请重新输入\n");
}
else
{
printf("输入有误,请重新输入\n");
}
}
}
电脑下棋的函数:
电脑下棋,在这里我们就用最简单的生成随机数来实现,就不设计更优(电脑能够主动赢,或者会堵玩家棋)的算法了(其实是我能力有限,想不到QAQ)
void Computermove(char (*board)[COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
int x = (rand() % row);
int y = (rand() % col);
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
判断棋盘是否已满的函数:
玩家和电脑每走一步,就应该调用该函数来判断棋盘是否已满,若已满,则需返回一个已满的条件,便于让循环终止
int Isfull(char(*board)[COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
if (ROW == i)
{
printf("棋盘已满,退出游戏\n");
return 1;
}
}
判断输赢的函数:
玩家和电脑每走一步,就应该调用该函数,用于判断输赢,若已经分出胜负,则需要返回一个能够判断输赢的条件,便于让循环终止
char Iswin(char(*board)[COL], int row, int col)
{
//行
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
}
以上就是各个函数的定义了
我们只需要把思路整理一下,把每一个函数的定义放在game函数之前,并且把以上的函数都放在game.c文件即可,至于上述函数的声明,我们放在game.h中,我们只需要再test.c和game.c中各自引用game.h就可以啦
最后的汇总:
test.c
#include"game.h";
//三子棋的测试
enum Choose
{
EXIT,
PLAY
};
int main()
{
int input = 0;
do
{
menu();
srand((unsigned int)time(NULL));
scanf("%d", &input);
switch (input)
{
case EXIT:
printf("退出游戏\n");
break;
case PLAY:
game();
break;
default:
printf("输入有误,请重新选择\n");
break;
}
} while (input);
return 0;
}
game.c
//游戏相关函数的实现
#include"game.h"
//菜单
void menu()
{
printf("************************************\n");
printf("************ 1.play *************\n");
printf("************ 0.exit *************\n");
printf("************************************\n");
}
void Initboard(char board[ROW][COL],int row,int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
*(*(board + i) + j) = ' ';
}
}
}
void Printboard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", *(*(board + i) + j));
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
for (j = 0; j < col; j++)
{
if (i < row - 1)
printf("--- ");
}
printf("\n");
}
}
void Playermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请玩家输入:>\n");
scanf("%d %d", &x, &y);
//scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x-1][y-1] == ' ')
{
board[x-1][y-1] = '*';
break;
}
else
printf("该位置已被占用,请重新输入\n");
}
else
{
printf("输入有误,请重新输入\n");
}
}
}
//char board[ROW][COL]
void Computermove(char (*board)[COL], int row, int col)
{
printf("电脑走:>\n");
while (1)
{
int x = (rand() % row);
int y = (rand() % col);
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int Isfull(char(*board)[COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
if (ROW == i)
{
printf("棋盘已满,退出游戏\n");
return 1;
}
}
char Iswin(char(*board)[COL], int row, int col)
{
//行
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
}
void game()
{
//该函数用于实现三子棋
//创建棋盘数组
char board[ROW][COL];
//初始化棋盘数组
Initboard(board,ROW,COL);
//打印棋盘
Printboard(board, ROW, COL);
while (1)
{
int ret = 0;
char tmp = 0;
//玩家输入坐标来下棋
Playermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判断是否赢了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家赢了\n");
break;
}
else if (tmp == '#')
{
printf("电脑赢了\n");
break;
}
//判断棋盘是否已满
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
//电脑下棋
Computermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判断是否赢了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家赢了\n");
break;
}
else if (tmp == '#')
{
printf("电脑赢了\n");
break;
}
//判断棋盘是否已满
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
}
}
game.h
//游戏函数的声明
//棋盘大小的定义
#include
#include
#include
#include
#define ROW 3
#define COL 3
void menu();
void game();
好啦,三子棋游戏的实现到这里就结束啦
结语:
创作不易,希望大家可以点赞、评论、转发、关注一条龙哦!
你们的支持是我创作最大的动力!!
由于本人能力有限,若有错误,希望指正!!
如果有更好的方法或者想法,也欢迎再评论区留言哦~