本文共 4543 字,大约阅读时间需要 15 分钟。
在初期版本扫雷的基础上上添加了展开,标记,防首次炸死功能;
效果展示:
扫雷首先需要两个大小相等的棋盘,一个如图1用来向外界展示,一个如图2用来埋雷。
棋盘有行和列,于是乎用二维数组来进行数据统计
char board[ROW][LINE]; memset(board, '*', sizeof(board));//显示的没点开之前为* char mineboard[ROW][LINE]; memset(mineboard, '0', sizeof(board));//雷的统计初始化为0 Mineset(mineboard);//设置雷区
将显示棋盘进行初始化为 * 后,用显示函数将其显示出来;
static void Showboard(char board[][LINE], int row, int line) //棋盘显示{ printf(" "); for (int i = 0; i <row-2; i++) { printf(" %2d |", i+1); } printf("\n------------------------------------------------------\n"); for (int i = 1; i < row - 1; i++) { printf(" %2d|", i); for (int j = 1; j < line - 1; j++) { printf(" %2c |", board[i][j]); } printf("\n------------------------------------------------------\n"); }}
显示效果图如下
很显然,雷区棋盘需与显示棋盘同等大小,同时在其中分布一定数目的雷,定义一个宏MINE,将其赋值给count,每成功设立一颗雷,count就减一,设定的宏的大小就是雷的数目;
static void Mineset(char mineboard[][LINE])//随机分布雷{ int x = 0; int y = 0; int count = MINE; while (count) { x = (rand() % (ROW - 2)) + 1; y = (rand() % (LINE - 2)) + 1; if (mineboard[x][y] == '0') { mineboard[x][y] = '1'; count--; } }}
上面提到两个棋盘,但是是独立分开的,那么是怎么联系在一起的呢?这个统计功能就是将两个棋盘联系在一起,当输入扫雷坐标后,通过雷区棋盘判定是否有雷,再将这个信息赋值给显示棋盘;
static char Detect(char mineboard[][LINE], int x, int y)//进行扫雷时,如果不是雷,则显示周围雷数{ if (mineboard[x][y] == '0') { return mineboard[x][y - 1] + mineboard[x][y + 1] \ + mineboard[x - 1][y - 1] + mineboard[x - 1][y] \ + mineboard[x - 1][y + 1] + mineboard[x + 1][y - 1]\ + mineboard[x + 1][y] + mineboard[x + 1][y + 1]-7*'0'; } if (mineboard[x][y] =='1') { return OVER; }}
设定一个函数,当我们进行第一次输入坐标的时候,如果判定是雷,就将这颗雷挪走,再随机设置一颗雷;
static void Firstmine(char mineboard[][LINE], int x, int y)//避免第一次被炸死{ if (mineboard[x][y] == '1') { mineboard[x][y] = '0'; } while (1) { x = (rand() % (ROW - 2)) + 1; y = (rand() % (LINE - 2)) + 1; if (mineboard[x][y] == '0') { mineboard[x][y] = '1'; break; } }}
如下图,黑色是坐标点,该函数统计的是分别以黄色为中心点统计其周围雷的数目;
static void Openmine(char board[][LINE], char mineboard[][LINE], int x, int y)//平铺展开函数{ board[x][y - 1] = Detect(mineboard,x,y-1); board[x][y + 1] = Detect(mineboard, x, y + 1); board[x - 1][y - 1] = Detect(mineboard, x-1, y - 1); board[x - 1][y] = Detect(mineboard, x-1, y ); board[x - 1][y + 1] = Detect(mineboard, x-1, y + 1); board[x + 1][y - 1] = Detect(mineboard, x+1, y - 1); board[x + 1][y] = Detect(mineboard, x+1, y ); board[x + 1][y + 1] = Detect(mineboard, x + 1, y + 1);}
标记功能是每进行一次输入就提示一次是否需要进行标记,标记的地方会显示为‘#’,如图所示
static void Lable(char board[][LINE])//标记坐标{ int x = 0; int y = 0; int quit = 0; int select = 0; while (!quit) { printf("请输入是否需要进行标记#1.yes#2.no\n"); scanf("%d", &select); switch (select) { case 1: printf("请输入你的标记坐标\n"); scanf("%d %d", &x, &y); board[x][y] = '#'; system("cls"); Showboard(board, ROW, LINE); break; case 2: quit = 1; break; default: printf("输入有误,请从新输入\n"); } }}
通过统计显示棋盘剩余的空白处和标记数与设定的雷区数目进行比较,如果想等则玩家胜利;
static int Blank(char board[][LINE], int row, int line)//判断棋盘剩余的空白处{ int count = 0; for (int i = 1; i < row - 1; i++) { for (int j = 1; j < line - 1; j++) { if (board[i][j] == '*' || board[i][j] == '#') { count++; } } } return count;}
将上述函数进行整体连接;
void Game(){ srand((unsigned)time(NULL)); char board[ROW][LINE]; memset(board, '*', sizeof(board));//显示的没点开之前为* char mineboard[ROW][LINE]; memset(mineboard, '0', sizeof(board));//雷的统计初始化为0 Mineset(mineboard);//设置雷区 int n = 1;//防炸死次数; while (1) // { system("cls"); Showboard(board, ROW, LINE);//展示棋盘 while (1)//判断是否需要进行标记; { Lable(board); break; } int quit = 0; int x = 0; int y = 0; while (!quit)//循环输入坐标扫雷 { printf("请输入你的坐标\n"); scanf("%d %d", &x, &y); if (x<0 || x>ROW - 2 || y<0 || y>LINE - 2) { printf("输入越界,请从新输入\n"); continue; } if (board[x][y] != '*' && board[x][y] != '#') { printf("此处已经排除,请从新输入\n"); continue; } quit = 1; } while (n)//排除第一次被炸死 { Firstmine(mineboard, x, y); n--; break; } int result = Detect(mineboard, x, y);//判断是否被炸死 if (result == OVER)//炸死了 { system("cls"); board[x][y] = OVER; Showboard(board, ROW, LINE); printf("很遗憾,你被炸死了\n"); printf("雷区分布如下\n"); Showboard(mineboard, ROW, LINE); break; } else//没炸死 { if (result == '0')//如果该扫雷处周围8个都是安全的,就将周围8个的周围8个的雷数显示出来; { Openmine(board, mineboard, x, y); } board[x][y] = result; } int Win = Blank(board, ROW, LINE); if (Win == MINE) { printf("恭喜你,你赢了\n"); break; } }}
转载地址:http://lose.baihongyu.com/