扫雷游戏
功能实现:
1、可以选择难度级别(初级、中级、高级);
2、实现了连续无雷区的显示。
设计思路:
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++; int flag = 0; //左上:循环 x_a = x; y_a = y; for (; aroundMine(Mine, x_a, y_a) == 0 && x > 0; x_a--){ flag = 1; y_a = y; for (; aroundMine(Mine, x_a, y_a) == 0 && y_a > 0; y_a--){ View[x_a][y_a] = '0'; count++; showAround(View, Mine, x_a, y_a, count); } } if (flag == 0){//若条件成立,说明aroundMine(Mine, x, y)!=0 goto judge; } //左下 x_a = x + 1;//此时aroundMine(Mine, x, y)已判断过 y_a = y; for (; aroundMine(Mine, x_a, y_a) == 0 && x <= row; x_a++){ y_a = y; for (; aroundMine(Mine, x_a, y_a) == 0 && y_a > 0; y_a--){ View[x_a][y_a] = '0'; count++; showAround(View, Mine, x_a, y_a, count); } } //右上 x_a = x; y_a = y + 1; for (; aroundMine(Mine, x_a, y_a) == 0 && x > 0; x_a--){ y_a = y + 1; for (; aroundMine(Mine, x_a, y_a) == 0 && y_a <= col; y_a++){ View[x_a][y_a] = '0'; count++; showAround(View, Mine, x_a, y_a, count); } } //右下 x_a = x + 1; y_a = y + 1; for (; aroundMine(Mine, x_a, y_a) == 0 && x < row; x_a++){ y_a = y + 1; for (; aroundMine(Mine, x_a, y_a) == 0 && y_a <= col; y_a++){ View[x_a][y_a] = '0'; count++; showAround(View, Mine, x_a, y_a, count); } } judge: 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("你踩到雷了!\n"); break; case 0: printf("扫雷成功!\n"); 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; do{ system("cls"); showView(View, row, col); res = start(View, Mine, row, col, minesNum); if (res != -1){ break; } } while (1); endTip(res); 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; do{ system("cls"); showView(View, row, col); res = start(View, Mine, row, col, minesNum); if (res != -1){ break; } } while (1); endTip(res); 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; do{ system("cls"); showView(View, row, col); res = start(View, Mine, row, col, minesNum); if (res != -1){ break; } } while (1); endTip(res); showView(Mine, row, col); }
运行结果: