扫雷游戏
功能实现:
1、可以选择难度级别(初级、中级、高级);
2、实现了连续无雷区的显示;
3、添加计时功能。
设计思路:
1、有难度的选择:初级、中级、高级,不同的难度级别会有不同数量的雷和不一样大小的网格;
2、通过输入坐标来确定你选择的踩雷位置,当你踩到此区显示0(即它的周围无雷)时,它会在显示周围各个位置(8个)的数字,若它周围的位置有显示0的情况,则同样又会显示它周围各个位置(8个)的数字,依次向外扩散,若出现不为0(即周围有雷)的情况,则不再继续显示该位置周围的位置。若是踩到该位置有雷,游戏结束;
3、在统计周边雷的个数时,为了省略对周边的位置是否超出数组大小,在定义数组时,定义为[+2][+2]形式。
所遇问题并解决:
1、返回值为char型的函数,虽返回char型,但是char在内存中以数字形式(即为它的ASCII码)存储,所以在赋值给char型变量时,需要通过+'0'的形式使其存储的ASCII码显示为字符(转化);强制类型转换:对内存空间未改变,仅是“看做”;
2、显示一大片无雷区的实现:用循环逻辑实现,分为四个方向,均向边界处循环判断;
3、选择难度级别的实现:均定义难度级别最高的数组大小,但用各自难度级别数组的大小来决定输出与判断,这样解决了三个难度级别所对应三个数组的问题。
#ifndef _CLEARMINES_H_
#define _CLEARMINES_H_
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#pragma warning(disable:4996)
#define ROW 16
#define COL 30
#define MineSum 99
void playPrimary();
void playIntermediate();
void playAdvanced();
#endif
#include"clearMines.h"
void view()
{
printf("*********************************\n");
printf("********* 欢迎来到扫雷!*********\n");
printf("******** 1:paly! 0:exit! *******\n");
printf("*********************************\n");
printf("please select:");
}
void selectModelView()
{
printf("**********************************\n");
printf("********** 选择游戏难度 **********\n");
printf("* a:初级(10个雷,9*9平铺网格)***\n");
printf("* b:中级(40个雷,16*16平铺网格)*\n");
printf("* c:高级(99个雷,16*30平铺网格)*\n");
printf("**********************************\n");
printf("please select:");
}
int main()
{
int sel;
char selmod;
do{
view();
scanf("%d", &sel);
switch (sel)
{
case 0:
exit(0);
case 1:
system("cls");
do{
fflush(stdin);
selectModelView();
scanf("%c", &selmod);
switch (selmod)
{
case 'a':
playPrimary(ROW - 7, COL - 21, MineSum - 89);
break;
case 'b':
playIntermediate(ROW, COL - 14, MineSum - 59);
break;
case 'c':
playAdvanced(ROW, COL, MineSum);
break;
default:
printf("input error.try again!\n");
break;
}
} while (selmod != 'a' && selmod != 'b' && selmod != 'c');
break;
default:
printf("input error.try again!\n");
break;
}
} while (1);
system("pause");
return 0;
}
#include"clearMines.h"
static void showView(char MineOrView[][COL + 2], int row, int col)
{
int k = 1;
printf(" ");
for (k = 1; k <= col; k++){
printf("%3d", k);
}
printf("\n___");
for (k = 0; k < col; k++){
printf("___");
}
printf("\n");
int i = 1;
for (; i <= row; i++){
int j = 1;
printf("%2d", i);
for (; j <= col; j++){
printf("|%2c", MineOrView[i][j]);
}
printf("|\n");
}
}
static void layMines(char Mine[][COL + 2], int start, int endr, int endc, int minesNum)//设置雷区
{
srand((unsigned)time(NULL));
int x, y;
int n = 0;
do{
x = (rand() % endr - start + 1) + start;
y = (rand() % endc- start + 1) + start;
if (Mine[x][y] == '0'){
Mine[x][y] = '1';//雷区设置为字符'1':方便计算周围的雷总数
n++;
}
} while (n < minesNum);
}
static int aroundMine(char Mine[][COL + 2], int x, int y)
{
return (Mine[x - 1][y - 1] + Mine[x - 1][y] + Mine[x - 1][y + 1] + \
Mine[x][y - 1] + Mine[x][y + 1] + \
Mine[x + 1][y - 1] + Mine[x + 1][y] + Mine[x + 1][y + 1]) - 8 * '0';//周围雷的个数
}
static void showAround(char View[][COL + 2], char Mine[][COL + 2], int x_a, int y_a, int count)
{
int x, y;
for (x = x_a - 1; x <= x_a + 1; x++){
for (y = y_a - 1; y <= y_a + 1; y++){
if (x == x_a && y == y_a){
continue;
}
View[x][y] = aroundMine(Mine, x, y) + '0';
count++;
}
}
}
static char judge(char View[][COL + 2], char Mine[][COL + 2], int x, int y, int row, int col, int minesNum)
{
if (Mine[x][y] == '1'){
return 'f';//file
}
static int count = 0;
int x_a, y_a;
View[x][y] = aroundMine(Mine, x, y) + '0';
count++;
if (View[x][y] == '0'){
int flag = 0;
//左上:循环
x_a = x;
y_a = y;
for (; x_a > 0; x_a--){
flag = 0;
y_a = y;
for (; View[x_a][y_a] != '#' && y_a > 0; y_a--){
if (aroundMine(Mine, x_a, y_a) == 0){
flag = 1;//若一行中无0则退出循环
View[x_a][y_a] = '0';
count++;
showAround(View, Mine, x_a, y_a, count);
}
}
if (flag == 0){
break;
}
}
//左下
x_a = x + 1;
y_a = y;
for (; x_a <= row; x_a++){
flag = 0;
y_a = y;
for (; View[x_a][y_a] != '#' && y_a > 0; y_a--){
if (aroundMine(Mine, x_a, y_a) == 0){
flag = 1;
View[x_a][y_a] = '0';
count++;
showAround(View, Mine, x_a, y_a, count);
}
}
if (flag == 0){
break;
}
}
//右上
x_a = x;
y_a = y + 1;
for (; x_a > 0; x_a--){
flag = 0;
y_a = y + 1;
for (; View[x_a][y_a] != '#' && y_a <= col; y_a++){
if (aroundMine(Mine, x_a, y_a) == 0){
flag = 1;
View[x_a][y_a] = '0';
count++;
showAround(View, Mine, x_a, y_a, count);
}
}
if (flag == 0){
break;
}
}
//右下
x_a = x + 1;
y_a = y + 1;
for (; x_a < row; x_a++){
flag = 0;
y_a = y + 1;
for (; View[x_a][y_a] != '#' && y_a <= col; y_a++){
if (aroundMine(Mine, x_a, y_a) == 0){
flag = 1;
View[x_a][y_a] = '0';
count++;
showAround(View, Mine, x_a, y_a, count);
}
}
if (flag == 0){
break;
}
}
}
if (count == row*col - minesNum){
return 's';//success
}
return 'n';
}
static int start(char View[][COL + 2], char Mine[][COL + 2], int row, int col, int minesNum)
{
int x, y;
char j;
do{
printf("please input the position <x y> of your select!\n");
scanf("%d%d", &x, &y);
if (x < 1 || x > row || y < 1 || y > col){
printf("This position out of bounds!\n");
}
else if (View[x][y] == '#'){
j = judge(View, Mine, x, y, row, col, minesNum);
switch (j){
case 'f':
return 1;
case 's':
return 0;
case 'n':
break;
}
break;
}
else{
printf("This location has been determined!\n");
}
} while (1);
return -1;
}
static void endTip(int res)
{
system("cls");
switch (res){
case 1:
printf("你踩到雷了!\t");
break;
case 0:
printf("扫雷成功!\t");
break;
}
}
void playPrimary(int row, int col, int minesNum)//row:9;col:9;minesNum:10
{
char View[ROW + 2][COL + 2];
char Mine[ROW + 2][COL + 2];
memset(View, '#', (ROW + 2)*(COL + 2));
memset(Mine, '0', (ROW + 2)*(COL + 2));//将布雷的数组初始化为'0'
layMines(Mine, 1, row, col, minesNum);//布雷
int res;
clock_t t1 = clock();//获取开始时间
do{
system("cls");
showView(View, row, col);
res = start(View, Mine, row, col, minesNum);
if (res != -1){
break;
}
} while (1);
clock_t t2 = clock();//获取结束时间
endTip(res);
printf("所用时间:%.1f秒(s)\n", (double)(t2 - t1) / CLK_TCK);
showView(Mine, row, col);
}
void playIntermediate(int row, int col, int minesNum)
{
char View[ROW + 2][COL + 2];
char Mine[ROW + 2][COL + 2];
memset(View, '#', (ROW + 2)*(COL + 2));
memset(Mine, '0', (ROW + 2)*(COL + 2));//将布雷的数组初始化为'0'
layMines(Mine, 1, row, col, minesNum);//布雷
int res;
clock_t t1 = clock();//获取开始时间
do{
system("cls");
showView(View, row, col);
res = start(View, Mine, row, col, minesNum);
if (res != -1){
break;
}
} while (1);
clock_t t2 = clock();//获取结束时间
endTip(res);
printf("所用时间:%.1f秒(s)\n", (double)(t2 - t1) / CLK_TCK);
showView(Mine, row, col);
}
void playAdvanced(int row, int col, int minesNum)
{
char View[ROW + 2][COL + 2];
char Mine[ROW + 2][COL + 2];
memset(View, '#', (ROW + 2)*(COL + 2));
memset(Mine, '0', (ROW + 2)*(COL + 2));//将布雷的数组初始化为'0'
layMines(Mine, 1, row, col, minesNum);//布雷
int res;
clock_t t1 = clock();//获取开始时间
do{
system("cls");
showView(View, row, col);
res = start(View, Mine, row, col, minesNum);
if (res != -1){
break;
}
} while (1);
clock_t t2 = clock();//获取结束时间
endTip(res);
printf("所用时间:%.1f秒(s)\n", (double)(t2 - t1) / CLK_TCK);
showView(Mine, row, col);
}
运行结果: