三子棋规则:玩家和电脑下棋交替下棋,直到有一方获胜为止,如果棋盘满了但没人赢那这局就是平局.
获胜判定:只要有一方的棋子是三个连起来的,那么连起来的那一方就获胜,如果棋盘满了也没人胜出那么这句就是平局.
游戏需求:游戏菜单,初始化棋盘,打印棋盘,玩家下棋,电脑随机下棋,判定输赢或平局.
可以创建三个文件来将游戏分为:
tesc.c:测试文件
game.c:游戏功能实现的文件
game.h:包括游戏功能里函数的声明及库函数的头文件
游戏开始前都是需要一个菜单来给玩家选择是否开始游戏或者退出游戏的,接下来我们来实现菜单的打印和游戏实现的框架
我们在主函数里定义do while循环来打印菜单(如果玩家选择1就是开始游戏,玩家选择0就是退出游戏,选择其他数字就提醒他选择错误)如下就是菜单打印的代码:
void menu()
{
printf("*****************************************\n");
printf("************** 三子棋游戏 ***************\n");
printf("****** 1.开始游戏 2.退出游戏 *********\n");
printf("*****************************************\n");
}
我们利用do while循环来打印菜单之后来实现框架,用Switch多重选择语句来给玩家选择是开始游戏还是退出游戏
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏!\n");
break;
default:
printf(" 输入错误,重新输入\n");
break;
}
} while (input);
return 0;
}
char board[ROW][COL] = { 0 };
#define ROW 3
#define COL 3
注:在自己创建的头文件在别的文件使用时要包含创建的头文件:
#include "game.h"
接下来是game函数的实现代码:
#include "game.h"
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘
Init_Board(board, ROW, COL);
//打印棋盘
Display_Board(board, ROW, COL);
while (1)
{
//玩家下棋
Player_Down(board, ROW, COL);
Display_Board(board, ROW, COL);
//判断输赢
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
Computer_chess(board, ROW, COL);
Display_Board(board, ROW, COL);
//判断输赢
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
Display_Board(board, ROW, COL);
}
void Init_Board(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 Display_Board(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");
//打印分割线
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
void Player_Down(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf(" 玩家下棋\n");
while (1)
{
printf("输入坐标,输入时用空格分开:>");
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");
}
}
}
我们定义两个数x和y来接收玩家要选择的坐标,在C语言里数组的下标是从0开始的,但如果给外行人玩的话他是不会知道数组下标是从0开始的,所以玩家输入后我们判断x和y是否大于1小于行和列如果是那么就进去,不是那么就提醒玩家输入的坐标不正确。
上面的判断条件为真后进入里面判断x和y减1的位置是不是空格,是空格我们就放入一个*号进去表示玩家的棋,如果不是空格那么就提醒玩家这个坐标已有棋子。
void Computer_chess(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
rand函数:是一个生成随机数的函数,但是如果我们只使用rand函数的话每次的随机数都是一样的,如果想要每次生成的数都是随机的那么我们就得再加一个srand函数。
srand函数:是初始化随机数的生成器,是供给rand生成随机数的生成器,
srand()括号里调用一个时间戳time,然后time的参数定义为空指(NULL),返回类型强制转换为无符号的int类型。
srand((unsigned int)time(NULL));
注:srand只用在主函数里调用一次就可以了,因为srand和rand还有time是库函数,所以要包含一下头文件:
srand和rand的头文件为#include
time的头文件为#include
char Is_Win(char board[ROW][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++)
{
int j = 0;
if (board[0][i] == board[1][i]
&& board[1][i] == board[2][i]
&& board[0][i] != ' ')
{
return board[j][i];
}
}
//对角线
if (board[0][2] == board[1][1]
&& board[1][1] == board[2][0]
&& board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][0] == board[1][1]
&& board[1][1] == board[2][2]
&& board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (Is_Full(board, row, col) == 1)
{
return 'Q';
}
return 'C';
}
输赢判断: 用循环来查看行,列,两对角线是否有3个一样的棋子是相连的
,是就返回三个棋子的其中一个其中,然后在test.c里定义一个变量来接收返回值,最后看返回的是*号还是#号,*号就代表玩家赢,#号就代表电脑赢
平局判断:平局判断的话,我们定义一个函数,用这个函数来判断棋盘里是否还有空格,有空格就返回0,没空格就返回1,然后在判断输赢的函数里判断
如果返回的是1那我们就返回’c’,如果返回0那么就是平局我们就返回’Q’来表示平局
int Is_Full(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
最后在test.c文件的game函数里接收返回来的字符,返回*玩家赢,返回#电脑赢,返回’C’棋盘还有位置游戏继续,返回‘Q’表示平局.
#include
#include
#include
#include
#define ROW 3
#define COL 3
//初始化棋盘
void Init_Board(char board[ROW][COL], int row, int col);
//打印棋盘
void Display_Board(char board[ROW][COL], int row, int col);
//玩家下棋
void Player_Down(char board[ROW][COL], int row, int col);
//电脑下棋
void Computer_chess(char board[ROW][COL], int row, int col);
/*
判断输赢:
*为玩家赢
#为电脑赢
Q为平局
C继续游戏
*/
char Is_Win(char board[ROW][COL], int row, int col);
另外我们可以在玩家选择是否开始游戏后加一个 system("cls");
来清理菜单,或者在判断输赢的前加system("cls");
.
三子棋游戏运行效果
test.c文件:
#include "game.h"
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘
Init_Board(board, ROW, COL);
//打印棋盘
Display_Board(board, ROW, COL);
while (1)
{
//玩家下棋
Player_Down(board, ROW, COL);
Display_Board(board, ROW, COL);
//判断输赢
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
Computer_chess(board, ROW, COL);
Display_Board(board, ROW, COL);
//判断输赢
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
break;
}
system("cls");
if (ret == '*')
{
printf("\n 玩家胜\n");
printf("\n\n");
}
else if (ret == '#')
{
printf("\n 电脑胜\n");
printf("\n\n");
}
else if (ret == 'C')
{
printf(" 平局\n");
printf("\n\n");
}
Display_Board(board, ROW, COL);
}
void menu()
{
printf("*************************\n");
printf("***** 三子棋游戏 ******\n");
printf("****** 1.play *********\n");
printf("****** 2.exit *********\n");
printf("*************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
system("cls");
switch (input)
{
case 1:
game();
break;
case 0:
printf("\n");
printf(" 退出游戏!\n");
break;
default:
printf("\n");
printf(" 输入错误,重新输入\n");
printf("\n");
break;
}
} while (input);
return 0;
}
game.h文件:
#include
#include
#include
#include
#define ROW 3
#define COL 3
//初始化棋盘
void Init_Board(char board[ROW][COL], int row, int col);
//打印棋盘
void Display_Board(char board[ROW][COL], int row, int col);
//玩家下棋
void Player_Down(char board[ROW][COL], int row, int col);
//电脑下棋
void Computer_chess(char board[ROW][COL], int row, int col);
/*
判断输赢:
*为玩家赢
#为电脑赢
Q为平局
C继续游戏
*/
char Is_Win(char board[ROW][COL], int row, int col);
game.c文件:
#include "game.h"
void Init_Board(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 Display_Board(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");
//打印分割线
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
void Player_Down(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf(" 玩家下棋\n");
while (1)
{
printf("输入坐标,输入时用空格分开:>");
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");
printf("此处已有棋子,重新输入\n");
printf("\n");
}
}
else
{
printf("\n");
printf("输入坐标不正确,请重新输入\n");
printf("\n");
}
}
}
void Computer_chess(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf(" 电脑下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int Is_Full(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
char Is_Win(char board[ROW][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++)
{
int j = 0;
if (board[0][i] == board[1][i]
&& board[1][i] == board[2][i]
&& board[0][i] != ' ')
{
return board[j][i];
}
}
//对角线
if (board[0][2] == board[1][1]
&& board[1][1] == board[2][0]
&& board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][0] == board[1][1]
&& board[1][1] == board[2][2]
&& board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (Is_Full(board, row, col) == 1)
{
return 'Q';
}
return 'C';
}