扫雷游戏
关键步骤:
两个二维数组的大小为11*11,但实际上操作的只有中心的9*9的棋盘,创建另外两行的原因是方便统计一个坐标周围3*3的雷的个数
1.创建两个二维数组一个存放布置好的雷(1号),另外一个存放空的棋盘(2号)
2.选手选出来的坐标传到1号棋盘上对坐标进行分析如果是雷就返回被炸死了,不是雷就算一下这个坐标周边一圈
有多少雷,并在2号棋盘上显示出来
结束标志:没被炸死,且棋盘上还剩下雷的个数的位置没被探索
二、代码
game.h
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define MINES 10 //初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch); //展示 void DisPlay(char board[ROWS][COLS], int row, int col); //布置雷 void LayMine(char board[ROWS][COLS], int row, int col); //开始游戏 void Play(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { board[i][j] = ch; } } } //展示 void DisPlay(char board[ROWS][COLS], int row, int col) { 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 ", board[i][j]); } printf("\n"); } } //布置雷 void LayMine(char board[ROWS][COLS], int row, int col) { int x, y; int count = MINES;//雷的数量 //要把雷布置在棋盘1-9的位置上 while (count) { x = rand() % 9 + 1; y = rand() % 9 + 1;//生成1-9的随机坐标 if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } //(x-1,y-1) (x-1,y) (x-1,y+1) //(x,y-1) (x,y) (x,y+1) //(x+1,y-1) (x+1,y) (x+1,y+1) //这个函数是用来统计输入的坐标旁边一共有多少个雷的 int CountMine(char mine[ROWS][COLS], 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] - 7*'0'; } //该函数通过递归来实现一片空白区域的连续展开 void Expand(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y) { //条件:如果show[x][y]处为'*'就进行展开求值 if(show[x][y]=='*') { show[x][y] = CountMine(mine, x, y); } //&&x>1&&x<9&&y>1&&y<9 //用于调试 if (show[x][y] == '0' && x >= 1 && x <= 9 && y>=1 && y <= 9)//这一句很重要,要不然一次性就把棋盘外面的一起展开了 { if (show[x - 1][y - 1] == '*')//同样判断要展开的位置是否是'*'也很重要,要不然就会栈溢出陷入死递归 { Expand(show, mine, x - 1, y - 1); } if(show[x - 1][y] == '*') { Expand(show, mine, x - 1, y); } if (show[x - 1][y+1] == '*') { Expand(show, mine, x - 1, y + 1); } if (show[x][y-1] == '*') { Expand(show, mine, x, y - 1); } if (show[x][y+1] == '*') { Expand(show, mine, x, y + 1); } if (show[x+1][y-1] == '*') { Expand(show, mine, x + 1, y-1); } if (show[x + 1][y] == '*') { Expand(show, mine, x + 1, y ); } if (show[x + 1][y +1] == '*') { Expand(show, mine, x + 1, y + 1); } } } //正式游戏 void Play(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x, y; while (1) { int count = 0; printf("请输入坐标:>"); scanf("%d%d", &x, &y); if (x >= 1 && x <=9 && y >= 1 && y <= 9)//确保合理输入范围 { if (mine[x][y] == '1') { printf("Game Over\n"); DisPlay(mine, ROW, COL); //用于显示失败后的雷区 break; } //else if (mine[x][y] != '1') //{ // show[x][y] = CountMine(mine,x,y); // /*printf("%d\n", CountMine(show, x, y));*///用于测试 // DisPlay(show, ROW, COL); //} else if (mine[x][y] != '1') { show[x][y] = CountMine(mine, x, y); if (show[x][y] == '0') { Expand(show, mine, x, y); } DisPlay(show, ROW, COL); } } else { printf("Error Location\n"); } //判断是否成功,当show中剩余的‘*’等于雷的个数时且还没被炸死时就赢了 for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { if (show[i][j] == '*') { count++; } } } if (count == MINES) { printf("Win\n"); DisPlay(mine, ROW, COL); //用于显示胜利后的雷区 break; } } }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" menu() //选择菜单 { printf(" \n"); printf(" 1.Play 0.Exit \n"); printf(" \n"); } void game() { char mine[ROWS][COLS] = { 0 };//用于存放地雷 char show[ROWS][COLS] = { 0 };//用于展示 InitBoard(mine, ROWS, COLS, '0');//将第一个放雷的棋盘全部初始化成'0' InitBoard(show, ROWS, COLS, '*');//将第二个展示的棋盘全部初始化成'*' //DisPlay(mine, ROW, COL);//只展示中心9*9的棋盘 DisPlay(show, ROW, COL); LayMine(mine, ROW, COL);//在mine棋盘里布置雷 //DisPlay(mine, ROW, COL);//用于测试 //开始玩扫雷 Play(mine, show,ROW,COL); } int main() { srand((unsigned int)time(NULL));//用于生成随机雷 int input;//玩家要输入的选择 do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: game();//游戏主体 break; case 0: printf("Exit Game\n"); break; default: printf("Error Choice\n"); break; } } while (input); return 0; }
三、测试结果展示