小时候电脑课上偷偷玩扫雷,现在长大了自己来实现一个扫雷。
一扫雷游戏的基本思路
①首先界面上会弹出相应的提示:提示玩游戏或者退出游戏。扫雷游戏应该要做到可以反复玩。
②首先需要布置雷,雷的位置应该是要随机生成的,雷的个数是自定义的。
③之后玩家输入对应的坐标,进行排雷操作。
排雷的过程中,需要提示玩家坐标的周围有多少个雷。
④游戏结束有两种方式:
a 被雷炸死,直接结束
b 成功排查出所有的雷,游戏成功
二 扫雷游戏的实现
我们建立game.c game.h test.c的三个项目。game.c专门用来实现游戏 game.h对函数声明,头文件包含等。test.c用来实现整个游戏的一个基本思路
缺点:这个游戏不能实现展开一片和标记的效果。仅仅是一个简易版的扫雷。
① test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
void test()
{
menu();
int input = 0;
char set[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
printf("PLEASE INPUT THE NUMBER HERE:");
srand((unsigned int)time(NULL));
do {
scanf("%d", &input);
switch (input)
{
case 1:
init_board(set, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');//初始化
print_show_chess(show, ROW, COL);//打印棋盘
set_mine(set, ROW, COL);//设置雷
search_mine(set, show, ROW, COL);
break;
case 0:
printf("THE GAME IS END\n");
break;
default:
printf("THE NUMBER IS FALSE,PLEASE INPUT AGAIN!\n");
}
} while (1);
}
int main()
{
test();
return 0;
}#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
void test()
{
menu();
int input = 0;
char set[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
printf("PLEASE INPUT THE NUMBER HERE:");
srand((unsigned int)time(NULL));
do {
scanf("%d", &input);
switch (input)
{
case 1:
init_board(set, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*');//初始化
print_show_chess(show, ROW, COL);//打印棋盘
set_mine(set, ROW, COL);//设置雷
search_mine(set, show, ROW, COL);
break;
case 0:
printf("THE GAME IS END\n");
break;
default:
printf("THE NUMBER IS FALSE,PLEASE INPUT AGAIN!\n");
}
} while (1);
}
int main()
{
test();
return 0;
}
②mine.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"mine.h"
void menu()
{
printf("******************\n");
printf("******************\n");
printf("******1.play******\n");
printf("******0.exit******\n");
printf("******************\n");
printf("******************\n");
}
//初始化棋盘
void init_board(char arr[ROWS][COLS], int rows, int cols,char sign)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
arr[i][j] = sign;
}
printf("\n");
}
}//由于展示给玩家的棋盘和内置的棋盘都是需要初始化的,并且初始化的功能实现只有展示的字符不一致,因此把他们封装成函数
void print_show_chess(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("---------扫雷--------\n");
for (i = 0; i <=col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <=row; i++)//已经初始化11*11,因此从0还是从1开始都可以得到相应的棋盘 从1开始方便打印标签
{
printf("%d ", i);
for (j = 1; j <=col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("---------扫雷--------\n");
}//数组下标是从0开始,怎样调整更有利于玩家?->初始化的阶段不一定需要打印出来全部都初始化了有两个好处
//1 利于查找雷的时候数量的统计 2 下标经过调整之后更有利于玩家
void set_mine(char set[ROWS][COLS], int row, int col)
{
int count = EASY_MINE;//宏不能直接修改,创建临时变量记住值
int x = 0;
int y = 0;
while(count)
{
x = rand() % row + 1;
y = rand() % col + 1;//随机生成1——9的数字
if (set[x][y]=='0')//如果随机生成的位置没有雷才能放
{
set[x][y] = '1';//为什么要创建二维数组!二维数组可以保存下对应的信息
count--;//循环次数>=10
}
}
}
void search_mine(char set[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int ret = 0;
int count = 0;
for (count = ROW * COL - EASY_MINE; count >= 0; count--)
{
printf("请输入坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)//在有效坐标范围内
{
if (set[x][y] == '0')
{
ret = count_mine(set, x, y);//统计这个坐标附近八个位置的雷 在屏幕上打印
show[x][y] = ret + '0';//将int的ret转换成char
printf("周围有%d个雷\n", ret);//找到就--,直到找出所有的雷
print_show_chess(show, ROW, COL);
}
else
{
printf("LOSE!\n");
print_show_chess(show, ROW, COL);
break;
}
}
else
{
printf("坐标非法,重新输入\n");
}
}
if (count == ROW * COL - EASY_MINE)
{
printf("排雷成功\n");
print_show_chess(show, ROW, COL);
}
}
//int count_mine(char set[ROW][COL],int x, int y)
//{
// int ret = set[x - 1][y - 1] + set[x][y - 1] + set[x + 1][y - 1] +
// set[x][y - 1] + set[x][y + 1] +
// set[x + 1][y - 1] + set[x + 1][y] + set[x + 1][y + 1] - 8 * '0';
// return ret;
//}
int count_mine(char set[ROW][COL], int x, int y)
{
int i = 0;
int j = 0;
int count = 0;
for (i = x-1; i <= x+1; i++)
{
for (j = y-1; j <= y+1; j++)
{
if (set[i][j] == '1')
count++;
}
}
return count;
}//遍历找雷
③mine.h
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#define ROW 9
#define COL 9
#define ROWS 11
#define COLS 11
#define EASY_MINE 10//宏定义雷的数量,方便后期难度调整
void menu();//打印菜单
void init_board(char arr[ROWS][COLS], int rows, int cols, char sign);//初始化棋盘
void print_show_chess(char arr[ROWS][COLS], int rows, int cols);//打印棋盘
void set_mine(char set[ROWS][COLS], int row, int col);//布置雷
void search_mine(char set[ROWS][COLS], char show[ROWS][COLS], int row, int col);//找雷
int count_mine(char set[ROW][COL], int x, int y);//计数
这里有几个需要注意的问题:
①为什么要定义ROW,ROWS与COL,COLS?->处理边角难于统计的问题
②为什么要定义两个棋盘->
一个是展示给玩家看的,主要实现排雷的操作(玩家可以直接观察)
一个是设置雷的棋盘,主要实现布置雷的操作(内置,只有游戏结束才能观察)
③定义两个二维数组数组->记住各自的信息。如果单纯使用两层嵌套就会比较繁琐。
三 效果展示