#第一次用C语言独立编写一个小游戏
编程前的准备
使用的软件: Visual Studio2022;需要创建的源文件与头文件:
game.h包含需要的头文件及其函数声明;game.c 包括游戏需要的操作; test.c 是测试文件包含主函数
一、打印游戏菜单
一个简单的格式输出操作
二、创建一个 3*3的棋盘格并对其进行初始化
因为棋盘刚开始为空 所以我们要对 一个二维数组(三行三列)进行初始化
//初始化棋盘
void InitBoard(char board[Row][Col], int row, int col);
void InitBoard(char board[Row][Col], int row, int col)
{
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Col; j++)
{
board[i][j] = ' ';
}
}
}
三、打印棋盘
棋盘如图所示 可知该棋盘由三部分组成 1.‘ ’ (空格) 2. 二维数组其中的元素 3.分隔符(用来隔开不同位置 每一次循环输入‘ 数组元素 ' + ' | ' 再输入换行符用来输入 ’---‘ 每一个“短横” 对应一个位置
只需要改变 Row 和 Col 便可以自定义棋盘大小 如:#define Row 5 #define Col 5 打印5*5的棋盘
void ShowBoard(char board[Row][Col], int row, int col)
{
//1.打印字符空格 2.分隔符
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Col; j++)
{
printf(" %c ", board[i][j]);
if (j<Col-1)
{
printf("|"); //最后一列不需要'|'分隔符
}
}
printf("\n");
if (i < Row - 1) //最后一行要为空 不需要 '---'
{
for (int j = 0; j < Col; j++)
{
printf("---");
if (j<Col-1)
{
printf("|");//最后一列不需要'|'分隔符
}
}
}
printf("\n");
}
}
四、玩家进行下棋操作
以上我们已经创建了一个空棋盘,接下来玩家要进行下棋操作
创建一个名为 PlayerMove的函数用以玩家进行操作即对该二维数组进行操作并保存合法的结果
操作代码放在一个死循环当中, 当玩家操作合法才能跳出循环
有两种常见的非法操作:1.因为我们是3*3的棋盘,故输入的x,y均不超过3 2.不能重复下一个位置
void PlayerMove(char board[Row][Col], int x, int y)
{
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");
}
}
}
五、电脑进行操作
电脑操作需要随机数的函数需要的头文件有#include <stdlib.h> #include <time.h>
需要限制随机数的范围在0~2,x%3 y%3 即可
合法操作的检验:因为已经控制随机数的范围在0~2,因此只需要检验当前位置是否有其他棋子占用, 若操作合法,则跳出循环,电脑操作完成。
void ComputerMove (char board[Row][Col], int row, int col)
{
int x, y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
else{}
}
}
六、输赢条件的判断
每次玩家或电脑进行下棋操作后要对输赢进行判断如若有一方获胜则跳出循环
我们制定以下规则来判别操作后的四种情形。
//判断游戏输赢
//玩家赢--‘#’;电脑赢-- ‘*’; 平局-- ‘E' ; 继续---’C‘;
char IsWin(char board[Row][Col], int row, int col);
while (1)
{
//玩家操作;
PlayerMove(board, Row, Col);
//判断输赢;
ShowBoard(board, Row, Col);
ret = IsWin(board, Row, Col);
if (ret != 'C')
{
break;
}
//电脑操作;
ComputerMove(board, Row, Col);
ShowBoard(board, Row, Col);
ret = IsWin(board, Row, Col);
if (ret != 'C')
{
break;
}
}
6.1获胜的三种情况
一列或一行相同 或者 对角线元素都相同 由此进行判别:通过返回的字符类型即可判断电脑或玩家获胜
char IsWin(char board[Row][Col], int row, int col)
{
//判断行相等
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ' )
{
return board[i][1];
}
}
//判断列相等
for (int j = 0; j< col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[j][1] != ' ')
{
return board[1][j];
}
}//判断对角线相等
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];
}
6.2 平局或者游戏继续的情况
ps:只有当游戏继续的情况下 才不会跳出循环 其余三种情况游戏都会终止。
//剩下平局或继续情况
int flag = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
flag = 1;
}
}
}
if (flag == 1)
{
return 'C';
}
else
{
return 'E';
}
}
七、输出游戏结果
用变量ret储存函数IsWin的返回值 用来判断该局游戏的获胜情况。
switch (ret)
{
case '#':
printf("玩家取得胜利\n");
break;
case '*':
printf("电脑取得胜利\n");
case 'E':
printf("平局\n");
default:
break;
}