目录
一、打印菜单
二、游戏实现
三、头文件(sl.h)
四、函数实现(slhs.c)
1、棋盘设置
2、打印棋盘
3、布置雷区
4、排雷
a.计算周围雷的个数
b.递归排雷
c.判断胜利
d.执行
五、补充 *** 作
1、标记雷区
2、取消标记
3、跳过第一次排雷被炸
4、定位光标与改换颜色
六、完整代码
一、打印菜单话不所说,跟着来 *** 作……
//菜单
void menu(){
printf("********************************\n");
printf("**** 1、play 0、exist ****\n");
printf("********************************\n");
}
//菜单选择
void test(){
int input;
srand((unsigned)time(NULL));//随机埋雷需用
do{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input){
case 1:game();
break;
case 0:printf("欢迎下次再玩\n");
break;
default:printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
二、游戏实现
分为两个棋盘,一个用来显示,一个用来存储扫雷信息
void game(){
//雷的信息存储
//1.布置好的雷的信息
char mine[ROWS][COLS] = { 0 };
//2.排查出的雷的信息
char show[ROWS][COLS] = { 0 };
//初始化
InitBoard(mine, ROWS, COLS,'0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
// DisplayBoard(mine, ROW, COL);//显示埋雷位置
//扫雷
//DisplayBoard(mine, ROW, COL);
FineMine(mine, show, ROW, COL);
}
三、头文件(sl.h)
为了方便,显得不那么乱,我们把所有的头文件、所定义函数、棋盘大小放在头文件中
#define ROW 9
#define COL 9 //棋盘大小9x9
#define ROWS ROW+2
#define COLS COL+2 //幕后棋盘实际要四周扩一格
#define EASY_COUNT 10 //埋雷个数
#include
#include
#include
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
四、函数实现(slhs.c) 1、棋盘设置
//棋盘设置
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set){
int i, j;
for (i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
board[i][j] = set;
}
}
}
2、打印棋盘
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
int i, j;
//打印列号
for (i = 0; i <= col; i++){
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++){
printf("%d ", i);
for (j = 1; j <= col; j++){
printf("%c ", board[i][j]);
}
printf("\n");
}
}
3、布置雷区
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col){
int count = EASY_COUNT;
while (count){
int x = rand() % row + 1;//1-9
int y = rand() % col + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}
4、排雷
a.计算周围雷的个数
int get_mine_count(char mine[ROWS][COLS], int x, int y){
return mine[x - 1][y] + mine[x - 1][y - 1] +
mine[x][y - 1] + mine[x + 1][y - 1] +
mine[x + 1][y] + mine[x + 1][y + 1] +
mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
}
b.递归排雷
void Rd(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){
//判断坐标是否合法
if (x==0 || y ==0 || x==ROWS-1 || y == COLS-1) return;
//判断是否已被排出
if (show[x][y] != '*') return;
int count = get_mine_count(mine, x, y);
if (count > 0){
show[x][y] = count + '0';
return;
}
else if (count == 0){
show[x][y] = '0';
Rd(mine, show, x, y - 1);
Rd(mine, show, x, y + 1);
Rd(mine, show, x + 1, y - 1);
Rd(mine, show, x + 1, y + 1);
Rd(mine, show, x + 1, y);
Rd(mine, show, x - 1, y - 1);
Rd(mine, show, x - 1, y);
Rd(mine, show, x - 1, y + 1);
}
}
c.判断胜利
int Victory(char show[ROWS][COLS],int row, int col){
int i,j;
int win = 0;
for(i=1;i<=row;i++){
for(j=1;j<=col;j++){
if(show[i][j] == '*'){
win++;
}
}
}
return win;
}
d.执行
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){
int x, y;
size_t flag_count = 0;
int win = 0;
while (1){
printf("请输入坐标并用空格隔开:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col){
//坐标合法
//踩雷
if (mine[x][y] == '1'){
printf("很遗憾,游戏失败!\n");
puts("\n雷阵如下:\n");
DisplayBoard(mine, row, col);
break;
}
//不是雷
else{
Rd(mine, show, x, y);
DisplayBoard(show, row, col);
}
}
else{
printf("坐标非法,请重新输入!\n");
}
win = Victory(show,row,col);
if(win == EASY_COUNT) break;
}
if (win == EASY_COUNT){
printf("恭喜,通关成功\n\n");
printf("雷阵如下:\n");
DisplayBoard(mine, row, col);
}
}
五、补充 *** 作
1、标记雷区本程序未添加这几项功能,感兴趣的盆友可自行发挥,添加……
当然,若博主后期比较闲的话也可能来优化
int Flagmine(char show[ROWS][COLS], int row, int col, size_t flag){
int x = 0, y = 0;
if (flag == EASY_COUNT){
printf("标记的雷与实际存在的雷数量相等,无法标记\n");
return 0;
}
printf("请输入你要标记的坐标:> ");
scanf("%d %d", &x, &y);
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col){
//判断是否已被确认为雷
if (show[x][y] == '*'){
show[x][y] = '!';//以!作为标记
flag++;
}
else{
printf("该坐标不可能是雷,请重新输入!\n");
}
}
else{
printf("该坐标不合法,请重新输入!\n");
}
return flag;
}
2、取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count){
int x = 0, y = 0;
printf("请输入需要取消的坐标:> ");
scanf("%d %d", &x, &y);
//判断坐标是否合法
if (x >= 1 && x <= row && y >= 1 && y <= col){
//判断是否被标记过
if (show[x][y] == '!'){
show[x][y] = '*';
flag_count--;
}
else
printf("该位置未被标记过,无需取消标记\n");
}
else
printf("该坐标不合法,请重新输入!\n");
return flag_count;
}
3、跳过第一次排雷被炸
void Change(char mine[ROWS][COLS],int row, int col,int x,int y){
x=rand()%row;
y=rand()%col;
mine[x][y]='1';
printf("第一次就踩雷了哟,请重新选择!\n");
}
4、定位光标与改换颜色
此两项 *** 作请阅读孤的“迷宫小游戏”C语言实现初级小迷宫_一段路的博客-CSDN博客_c语言制作小迷宫
六、完整代码
//sl.h
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include
#include
#include
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//sl.c
void menu(){
printf("********************************\n");
printf("**** 1、play 0、exist ****\n");
printf("********************************\n");
}
void game(){
//雷的信息存储
//1.布置好的雷的信息
char mine[ROWS][COLS] = { 0 };
//2.排查出的雷的信息
char show[ROWS][COLS] = { 0 };
//初始化
InitBoard(mine, ROWS, COLS,'0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//扫雷
//DisplayBoard(mine, ROW, COL);
FineMine(mine, show, ROW, COL);
}
//执行
void test(){
int input;
srand((unsigned)time(NULL));
do{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input){
case 1:game();
break;
case 0:printf("欢迎下次再玩\n");
break;
default:printf("选择错误,请重新选择\n");
break;
}
} while (input);
}
//主函数
int main(){
test();
return 0;
}
//slhs.c
//棋盘设置
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set){
int i, j;
for (i = 0; i < rows; i++){
for (j = 0; j < cols; j++){
board[i][j] = set;
}
}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
int i, j;
//打印列号
for (i = 0; i <= col; i++){
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++){
printf("%d ", i);
for (j = 1; j <= col; j++){
printf("%c ", board[i][j]);
}
printf("\n");
}
}
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col){
int count = EASY_COUNT;
while (count){
int x = rand() % row + 1;//1-9
int y = rand() % col + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}
//排雷
int get_mine_count(char mine[ROWS][COLS], int x, int y){
return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] +
mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
}
//递归
void Rd(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y){
//判断坐标是否合法
if (x==0 || y ==0 || x==ROWS-1 || y == COLS-1) return;
//判断是否已被排出
if (show[x][y] != '*') return;
int count = get_mine_count(mine, x, y);
if (count > 0){
show[x][y] = count + '0';
return;
}
else if (count == 0){
show[x][y] = '0';
Rd(mine, show, x, y - 1);
Rd(mine, show, x, y + 1);
Rd(mine, show, x + 1, y - 1);
Rd(mine, show, x + 1, y + 1);
Rd(mine, show, x + 1, y);
Rd(mine, show, x - 1, y - 1);
Rd(mine, show, x - 1, y);
Rd(mine, show, x - 1, y + 1);
}
}
//标记雷
int Flagmine(char show[ROWS][COLS], int row, int col, size_t flag){
int x = 0, y = 0;
if (flag == EASY_COUNT){
printf("标记的雷与实际存在的雷数量相等,无法标记\n");
return 0;
}
printf("请输入你要标记的坐标:> ");
scanf("%d %d", &x, &y);
//判断坐标的合法性
if (x >= 1 && x <= row && y >= 1 && y <= col){
//判断是否已被确认为雷
if (show[x][y] == '*'){
show[x][y] = '!';//以!作为标记
flag++;
}
else{
printf("该坐标不可能是雷,请重新输入!\n");
}
}
else{
printf("该坐标不合法,请重新输入!\n");
}
return flag;
}
//取消标记
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count){
int x = 0, y = 0;
printf("请输入需要取消的坐标:> ");
scanf("%d %d", &x, &y);
//判断坐标是否合法
if (x >= 1 && x <= row && y >= 1 && y <= col){
//判断是否被标记过
if (show[x][y] == '!'){
show[x][y] = '*';
flag_count--;
}
else
printf("该位置未被标记过,无需取消标记\n");
}
else
printf("该坐标不合法,请重新输入!\n");
return flag_count;
}
//判断胜利
int Victory(char show[ROWS][COLS],int row, int col){
int i,j;
int win = 0;
for(i=1;i<=row;i++){
for(j=1;j<=col;j++){
if(show[i][j] == '*'){
win++;
}
}
}
return win;
}
void FineMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){
int x, y;
size_t flag_count = 0;
int win = 0;
while (1){
printf("请输入坐标并用空格隔开:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col){
//坐标合法
//踩雷
if (mine[x][y] == '1'){
printf("很遗憾,游戏失败!\n");
puts("\n雷阵如下:\n");
DisplayBoard(mine, row, col);
break;
}
//不是雷
else{
Rd(mine, show, x, y);
DisplayBoard(show, row, col);
}
}
else{
printf("坐标非法,请重新输入!\n");
}
win = Victory(show,row,col);
if(win == EASY_COUNT) break;
}
if (win == EASY_COUNT){
printf("恭喜,通关成功\n\n");
printf("雷阵如下:\n");
DisplayBoard(mine, row, col);
}
}
不足之处,请多多指教,欢迎留言……
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)