游戏程序的整体布局
1,test.c---游戏运行的主体
2,game.c---游戏函数实现的主体
3,game.h---游戏函数即一些头文件的声明
#include"game.h"
int main()
{
int put = 0;
do
{
menu();
printf("请输入对应功能的数字:");
scanf("%d", &put);
switch (put)
{
case 1:
game();
break;
case 0:
printf("已退出游戏");
break;
default:
printf("非法输入,请重新输入");
}
} while (put);
return 0;
}
这里没有引用<stdio.h>的头文件,该文件被封装到了game.h的文件中,其中的menu()菜单函数与游戏函数game()被封装到game.c文件中
游戏主体的实现
要想做出扫雷,首先要有游戏菜单,棋盘,布雷,及玩家排查的逻辑,和判断输赢的逻辑,其次要了解本质的实现原理,首先要有一个显示给玩家的棋盘(不显示雷),其次创建另一个棋盘不给玩家看(布置雷),在玩家游玩的过程实际是在内置的棋盘中进行排查,而在另一个棋盘显示。
?
void game()
{
srand((unsigned)time(NULL));
//创建棋子数组
char showboard[SROW][SCOL];
char setboard[SROW][SCOL];
//创建棋盘
init_sboard(showboard,SROW,SCOL);
init_board(setboard, SROW, SCOL);
//布置雷
init_leiboard(setboard, ROW, COL);
//排查与输赢的判断
}
?
游戏菜单
//菜单
void menu()
{
printf("-------------- 扫雷 -----------\n");
printf("---------- 1.开始游戏 ---------\n");
printf("---------- 0.退出游戏 ---------\n");
printf("-------------------------------\n");
printf("游戏规则:在9*9的棋盘内布置10个雷,雷用数字1表示。\n");
printf("踩到雷游戏结束,没踩到雷则计算出该位置周围8个位置中雷的个数\n");
printf("-------------------------------\n");
}
初始化棋盘
?tips:为了提高代码的健壮性,我们使用了全局变量 ROW 和 COL ,SROW,SCOL来进行操作,通过改变这两个全局变量的值就可以操作棋盘的格局,方便了日后的进一步优化改进,提高游戏可操作性。在game.h文件中使用
#define ROW 9
#define COL 9
#define SROW ROW+2
#define SCOL COL+2
在显示的棋盘中我们只显示9*9的棋盘大小,而在内置的棋盘中为了方便排查边角处的雷所以要多加两行两列
初始化显示棋盘
//显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol);
?在此创建一个showboard二维数组,用‘*’来初始化。
//初始化显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol)
{
for (int i = 0; i < srow; i++)
{
for (int j = 0; j < scol; j++)
{
showboard[i][j] = '*';
}
}
}
初始化内置棋盘
//内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol);
?在此创建一个setboard二维数组,用‘0’来初始化,之后用字符1来布置雷。
//初始化内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol)
{
for (int i = 0; i < srow; i++)
{
for (int j = 0; j < scol; j++)
{
setboard[i][j] = '0';
}
}
}
布置雷
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col);
?在这里宏定义雷的个数为10
#define LEI 10
通过库函数随机布置雷的位置?
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col)
{
int lei = LEI;
int i, j;
while (lei)
{
i = rand() % row + 1;
j = rand() % col + 1;
if (setboard[i][j] == '0')
{
setboard[i][j] = '1';
lei--;
}
}
}
循环排查直到排查完或踩到雷
void game()
{
srand((unsigned)time(NULL));
//创建棋子数组
char showboard[SROW][SCOL];
char setboard[SROW][SCOL];
//创建棋盘
init_sboard(showboard,SROW,SCOL);
init_board(setboard, SROW, SCOL);
//布置雷
init_leiboard(setboard, ROW, COL);
//排查与输赢的判断
while (1)
{
//打印棋盘
print_sboard(showboard, ROW, COL);
//排查与判断输赢
find_lei(showboard,setboard,ROW,COL);
//打印最终结果
printf("以下是全部雷区\n");
print_board(setboard, ROW, COL);
break;
}
}
?
打印棋盘
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col);
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col)
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 0; i <= col; i++)
{
printf("--");
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", showboard[i][j]);
}
printf("|\n");
}
}
在此为了方便玩家排雷,将数组的下角标与真实行列坐标对应,以下是演示图
?排查与判断输赢 ?
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col);
?在此我们宏定义排查次数WIN
#define WIN ((ROW*COL)-LEI)
?
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col)
{
int i, j;
int win = WIN;
while (win)
{
printf("请输入想要排查的行:");
scanf("%d", &i);
printf("请输入想要排查的列:");
scanf("%d", &j);
if (i >= 1 && i <= row && j >= 1 && j <= col)
{
if (showboard[i][j] == '*')
{
if (setboard[i][j] == '1')
{
printf("恭喜你踩到雷了小笨蛋!\n");
return ;
}
else
{
showboard[i][j] = countlei(setboard, i, j);
system("cls");
print_sboard(showboard, ROW, COL);
win--;
}
}
else
printf("该位置已经排查过了,请重新输入\n");
}
else
printf("非法输入,请重新输入\n");
}
if (win == 0)
{
printf("真可惜你排查完所有的雷,没炸到你!\n");
return ;
}
}
?
这里如果没有踩到雷则在该位置计算出周围8个方位雷的个数
计算雷个数
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j);
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j)
{
return (setboard[i - 1][j - 1] + setboard[i - 1][j] // 将布置雷棋盘该位置周围八个对应的字符相加减去 7*‘0’ 得到的是周围雷的个数 赋给排查雷的棋盘
+ setboard[i - 1][j + 1] + setboard[i][j - 1]
+ setboard[i][j + 1] + setboard[i + 1][j - 1]
+ setboard[i + 1][j] + setboard[i + 1][j + 1])-(7*'0');
}
字符储存的是ascll,字符‘0’对应的ascll是48,因为在内置棋盘中只有字符‘0’和字符‘1’,将周围的8个字符相加后减去7个字符‘0’的大小,如果有一个雷则返回字符‘1’的ascll码值49,如果有两个则返回49+1即字符‘2’的ascll值,以此来计算并显示雷的多少。
打印最终的结果 ?
//打印最终的结果
void print_board(char setboard[SROW][SCOL], int row, int col);
在排查完或踩到雷后显示出所有雷的位置
//打印最终结果
void print_board(char setboard[SROW][SCOL], int row, int col)
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 0; i <= col; i++)
{
printf("--");
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", setboard[i][j]);
}
printf("|\n");
}
}
test.c
#include"game.h"
int main()
{
int put = 0;
do
{
menu();
printf("请输入对应功能的数字:");
scanf("%d", &put);
switch (put)
{
case 1:
game();
break;
case 0:
printf("已退出游戏");
break;
default:
printf("非法输入,请重新输入");
}
} while (put);
return 0;
}
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define SROW ROW+2
#define SCOL COL+2
#define LEI 10
#define WIN ((ROW*COL)-LEI)
//菜单
void menu();
//游戏主函数
void game();
//显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol);
//内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol);
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col);
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col);
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col);
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j);
//打印最终的结果
void print_board(char setboard[SROW][SCOL], int row, int col);
game.c
#include"game.h"
//菜单
void menu()
{
printf("-------------- 扫雷 -----------\n");
printf("---------- 1.开始游戏 ---------\n");
printf("---------- 0.退出游戏 ---------\n");
printf("-------------------------------\n");
printf("游戏规则:在9*9的棋盘内布置10个雷,雷用数字1表示。\n");
printf("踩到雷游戏结束,没踩到雷则计算出该位置周围8个位置中雷的个数\n");
printf("-------------------------------\n");
}
//初始化显示棋盘
void init_sboard(char showboard[SROW][SCOL], int srow, int scol)
{
for (int i = 0; i < srow; i++)
{
for (int j = 0; j < scol; j++)
{
showboard[i][j] = '*';
}
}
}
//初始化内置棋盘
void init_board(char setboard[SROW][SCOL], int srow, int scol)
{
for (int i = 0; i < srow; i++)
{
for (int j = 0; j < scol; j++)
{
setboard[i][j] = '0';
}
}
}
//布置雷
void init_leiboard(char setboard[SROW][SCOL], int row, int col)
{
int lei = LEI;
int i, j;
while (lei)
{
i = rand() % row + 1;
j = rand() % col + 1;
if (setboard[i][j] == '0')
{
setboard[i][j] = '1';
lei--;
}
}
}
//打印棋盘
void print_sboard(char showboard[SROW][SCOL], int row, int col)
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 0; i <= col; i++)
{
printf("--");
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", showboard[i][j]);
}
printf("|\n");
}
}
//排查与判断输赢
void find_lei(char showboard[SROW][SCOL], char setboard[SROW][SCOL], int row, int col)
{
int i, j;
int win = WIN;
while (win)
{
printf("请输入想要排查的行:");
scanf("%d", &i);
printf("请输入想要排查的列:");
scanf("%d", &j);
if (i >= 1 && i <= row && j >= 1 && j <= col)
{
if (showboard[i][j] == '*')
{
if (setboard[i][j] == '1')
{
printf("恭喜你踩到雷了小笨蛋!\n");
return ;
}
else
{
showboard[i][j] = countlei(setboard, i, j);
system("cls");
print_sboard(showboard, ROW, COL);
win--;
}
}
else
printf("该位置已经排查过了,请重新输入\n");
}
else
printf("非法输入,请重新输入\n");
}
if (win == 0)
{
printf("真可惜你排查完所有的雷,没炸死你狗日的!\n");
return ;
}
}
//计算雷的个数
char countlei(char setboard[SROW][SCOL], int i, int j)
{
return (setboard[i - 1][j - 1] + setboard[i - 1][j] // 将布置雷棋盘该位置周围八个对应的字符相加减去 7*‘0’ 得到的是周围雷的个数 赋给排查雷的棋盘
+ setboard[i - 1][j + 1] + setboard[i][j - 1]
+ setboard[i][j + 1] + setboard[i + 1][j - 1]
+ setboard[i + 1][j] + setboard[i + 1][j + 1])-(7*'0');
}
//打印最终结果
void print_board(char setboard[SROW][SCOL], int row, int col)
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 0; i <= col; i++)
{
printf("--");
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d|", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", setboard[i][j]);
}
printf("|\n");
}
}
void game()
{
srand((unsigned)time(NULL));
//创建棋子数组
char showboard[SROW][SCOL];
char setboard[SROW][SCOL];
//创建棋盘
init_sboard(showboard,SROW,SCOL);
init_board(setboard, SROW, SCOL);
//布置雷
init_leiboard(setboard, ROW, COL);
//排查与输赢的判断
while (1)
{
//打印棋盘
print_sboard(showboard, ROW, COL);
//排查与判断输赢
find_lei(showboard,setboard,ROW,COL);
//打印最终结果
printf("以下是全部雷区\n");
print_board(setboard, ROW, COL);
break;
}
}
|