ps
本次文章代码采用的多文件函数的声明和定义的形式,即函数的声明、类型的声明放在头文件中(.h)中,函数的实现放在(.c)文件中
扫雷游戏的分析和设计
1.扫雷游戏功能说明
*玩家可以通过菜单实现继续玩或者退出游戏
扫雷的棋盘是99的格子**随机布置10个雷
排查雷
**如果排查的位置不是雷,显示周围雷的个数
**如果位置是雷,游戏结束
**把所有非雷的位置找出来,排雷成功,游戏结束
该游戏的界面
2.扫雷的过程中,布置雷和存储雷的信息都需要存放在棋盘上,假设布置雷的符号为 1,没有布置雷的位置存放 0,当我们排查最外层的雷时,按理说会访问该位置周围一圈的位置,但是会造成数组越界,怎么办呢?这是我们把布置雷的棋盘扩大一圈,这样就解决了数组越界的问题,所以把棋盘创建成1111的数组。
3.上面我们说到把雷的位置设为 1,不是雷的位置设为 0,但如果我们排查的位置周围有1个雷,这样在棋盘上不也显示1,就会分不清楚1是雷还是表示周围雷,怎么办呢?我们创建两个棋盘,一个专门存放布置雷的信息,一个专门用来排查雷和显示雷周围的信息。这样避免在一个棋盘上的实现功能相互冲突的问题。
文件结构设计
test.c // 该文件是写游戏的逻辑
game.h //该文件是写游戏中函数的声明,头文件等
game.c //该文件是写游戏需要的函数具体的实现
test.c
首先主函数里面先打印菜单,供玩家选择,选择 1 开始游戏,0 退出游戏,选择其他 重新输入。要实现这样的功能应选择do-while语句,不管三七二十一先打印菜单,再选择。
int main()
{
int input = 0;//在这里创建input的原因是do-while中条件设为input选择1和其他数
时就又跳到上面重新选择,选择 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;
}
接下来写menu()和game()的函数
game.c
创建两个11*11的棋盘,一个初始化全是0,用来存放雷和布置雷,一个全是 * 供玩家排查雷。
其中棋盘为啥用ROWS和COLS呢?,这是为了方便以后可以修改棋盘的大小,已经在头文件game.h中声明了
实现初始化棋盘
要想看看实现效果如何,接下来打印棋盘
第一个for循环是用来打印标号,方便玩家快速定位,第二个for循环打印每一行的开头标号,然后再打印数组。
接下来布置雷
这里布置的雷是随机布置10个雷,所以用到库函数rand()//生成随机数,不过要先调用srand(),ps:已经在主函数处调用。%row 随机生成0~ 8的随机数,再加1随机生成1~ 9的数。
然后再实现排雷函数
这里得到周围雷的个数还可以用循环来遍历,具体用法如下:
这里为啥要减 ’ 0 '呢?,这里我们在二维数组中布置的全是字符0和字符1,是char类型,而要统计周围雷的个数是int类型,所以要转换,字符0的ASCII是48,而字符1的ASCII码值是49,两者相减就得到了数字1.
结尾
这样一个基本的扫雷游戏就完成了,如果大家有不理解的或者有更精进的方法可以在评论区和我讨论哈。
源代码
//game.h
#pragma once
# include <stdio.h>
# define ROW 9
# define COL 9
# define ROWS ROW + 2
# define COLS COL + 2
# define bomb 10
# include <time.h>
# include <stdlib.h>
void init_board(char mine[ROWS][COLS], int rows, int cols, char set);
void print_board(char mine[ROWS][COLS], int rows, int cols);
void set_mine(char mine[ROWS][COLS], int row, int col);
void find_show(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//game.c
#define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void init_board(char mine[ROWS][COLS], int rows, int cols, char set)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
mine[i][j] = set;
}
printf("\n");
}
}
void print_board(char mine[ROWS][COLS], int row, int col)
{
printf("--------扫雷游戏-------\n");
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%c ", mine[i][j]);
}
printf("\n");
}
}
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = bomb;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int get_bomb(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 + 1] +
mine[x][y + 1] +
mine[x - 1][y + 1] +
mine[x + 1][y]- 8 * '0');
}
void find_show(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - bomb)
{
printf("请输入要排查雷的坐标:->");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("被炸死了,你个废物\n");
print_board(mine, ROW, COL);
break;
}
else
{
int count = 0;
count = get_bomb(mine, x, y);
show[x][y] = count + '0';
print_board(show, ROW, COL);
win++;
}
}
else
{
printf("坐标不对,你个废物,重新输入\n");
}
}
if (win == row * col - bomb)
{
printf("排雷成功\n");
print_board(mine, ROW, COL);
}
}
//test.c
#define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void menu()
{
printf("****************\n");
printf("*****1.play*****\n");
printf("*****0.exit*****\n");
printf("****************\n");
}
void game()
{
//创建棋盘
char mine[ROWS][COLS];//布置雷
char show[ROWS][COLS];//排查雷
//初始化棋盘
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');
//打印棋盘
//print_board(mine, ROW, COL);
print_board(show, ROW, COL);
//布置雷
set_mine(mine, ROW, COL);
//排查雷
find_show(mine, show, ROW, COL);
}
int main()
{
//打印界面
int input = 0;
srand((unsigned int)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);
return 0;
}