gitee仓库代码提交https://gitee.com/hacha/practice.git
三子棋小游戏思路
通过人机对战的形式,用坐标来确定落子的位置,三子相连判断输赢
模块可分为:1.初始化数组中的元素,全部初始化为空格,能让棋盘打印的规整
2.打印棋盘,在控制台显示出棋盘
3.玩家下棋 4.电脑下棋(循环)
5.判断输赢,退出循环
代码模块化,更好的厘清思路,test.c 实现测试游戏进行,game.c 三子棋游戏的实现 game.h 函数声明
#include
void menu()
{
printf("*************************************\n");
printf("********* 1.play 0.exit ***********\n");
printf("*************************************\n");
}
int main()
{
int input = 0;
// 1次不够再来1次 循环
// 要先进来一次,判断玩家玩不玩,所以采用do while的形式
do
{
//菜单
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
// 进入游戏
case 1:
printf("三子棋\n");
break;
// 退出游戏
case 0:
printf("游戏结束\n");
break;
// 输入错误
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
要初始化棋盘就要先有棋盘,在test中创建棋盘
用33的二维数组作为棋盘,但是如果以后要更改,33太固定了,所以通过#define 定义行列
// 二维数组传参,直接拿一个二维数组接收
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 DisplayBoard(char board[ROW][COL], int row, int col)
{
//将1行元素和1行分割线看做一组,通过i控制组数
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("|");
}
}
// 打印完1行 换行
printf("\n");
// --- 线在最后1行也不能显示
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
// 同理
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家下棋\n");
printf("请选择坐标:>");
int x = 0, y = 0;
while (1)
{
scanf("%d %d", &x, &y);
// 先判断坐标的合法性
if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
{
// 这里的坐标并不代表下标,所以x-1,y-1
if (board[x - 1][y - 1] == ' ')
{
// 玩家落子设置为*
board[x - 1][y - 1] = '*';
break;
}
// 坐标被占用的情况
else
{
printf("输入坐标被占用,请重新输入\n");
}
}
else
{
printf("输入坐标不合法,请重新输入");
}
}
}
电脑生成随机数,对行列取模生成范围内的随机数
要使用到库函数rand生成随机数
在调用rand之前要先调用srand(在整个项目当中只需要设置1次即可,所以设置在test函数当中)
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
while (1)
{
// 这里的x,y是生成的随机数取模,所以x,y的取值为0,1,2 就是下标
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
//电脑落子为#
board[x][y] = '#';
break;
}
}
}
// 用字符类型接收
char IsWin(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][2] != ' ')
{
// 此时数组当中存放的就是赢的一方,直接return
return board[i][0];
}
}
int j = 0;
for (j = 0; j < col; j++)
{
// 某一列相等
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
// 对角线相等
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[0][0];
}
// 当以上条件都未进入就说明棋局:
// 要么继续 --'C ' Continue
// 要么就是棋盘满了平局--'Q' quit
// 如果继续返回C 如果平局 返回Q
//拿ret接收IsFull的字符
int ret = IsFull(board, ROW, COL);
return ret;
}
//棋局是否满了
char IsFull(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 'C';
}
}
}
// 到这里就是棋盘满了的情况
return 'Q';
}
do
{
//菜单
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
// 进入游戏
case 1:
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
// 循环下棋
//接收IsWin的返回值
char num = 0;
while (1)
{
// 玩家下棋
PlayerMove(board, ROW, COL);
num = IsWin(board, ROW, COL);
// 只要不是'C' 就说明判断出胜负或者是平局
if (num != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
ComputerMove(board, ROW, COL);
num = IsWin(board, ROW, COL);
if (num != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
}
if (num == '*')
{
printf("玩家赢\n");
}
else if (num == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
// 判断完棋局输赢再打印1次棋盘
DisplayBoard(board, ROW, COL);
break;
// 退出游戏
case 0:
printf("游戏结束\n");
break;
// 输入错误
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);