目录
说起扫雷,相信大家应该都不陌生吧。windows系统里的小游戏,扫雷有着不可撼动的地位。
今天我们就用c语言来复刻扫雷小游戏!

玩家需要排查出格子中的雷,点开一个方块后,显示数字,数字是几就表示它周围的八个方块有几个雷。

比如说这个红色的方框里面就存在一个雷。

雷盘相当于一个二维的数组
一、游戏交互界面
- 创建游戏菜单
- 创建游戏逻辑主体
二、扫雷游戏实现
- 创建扫雷棋盘
- 初始化扫雷棋盘
- 布置雷
- 打印扫雷棋盘
- 用户排查雷
- 判断输赢
1.设计扫雷游戏的时候,二维数组的行数和列数需要比真正想要得到的棋盘多两行和多两列
为什么呢?
因为我们排查雷的时候,需要遍历坐标走位八个格子是否有雷,当输入坐标为雷盘边界坐标时,遍历周围的雷就会出现越界的问题!

2.创建两个雷盘,一个用于显示,一个用于存放地雷
只创建一个棋盘,那么这一个棋盘上就要放置3种信息。分别为雷、非雷、排查出周围雷的信息。虽然这种方法也没太大的问题,但是一个棋盘上放置3种信息会给之后打印棋盘时造成麻烦,不易打印。
3.使用宏常量
方便雷盘大小的修改,不会写死程序,提高代码的灵活性。
- void menu()
- {
- printf("**************************\n");
- printf("********1.开始游戏********\n");
- printf("********0.退出游戏********\n");
- printf("**************************\n");
- }
- int main()
- {
- srand((unsigned int)time(NULL));
- int intput = 0;
- again:
- menu();
- scanf("%d", &intput);
- do
- {
- switch (intput)
- {
- case 1:
- printf("游戏开始\n");
- game();
- goto again;
- case 0:
- printf("退出游戏\n");
- break;
- default:
- printf("输入错误请重新输入\n");
- break;
- }
- } while(intput);
-
- return 0;
- }
- void game()
- {
- //设置两个数组,mine数组用来存放设置雷的信息,show数组用来存放排查雷的信息
- char mine[ROWS][COLS] = {0};
- char show[ROWS][COLS] = {0};
- init_board(show,ROWS,COLS,'*');
- init_board(mine, ROWS, COLS, '0');
- //display_board(mine, ROW, COL);
- display_board(show, ROW, COL);
- set_mine(mine,ROW,COL);
- //display_board(mine, ROW, COL);
- find_mine(mine,show,ROW,COL);
- }
- void init_board(char board[][COLS],int rows,int cols,char set)//初始化雷盘,set是需要初始化成什么字符
- {
- int i = 0;
- int j = 0;
-
- for (i = 0; i < rows; i++)
- {
- for (j = 0; j < cols; j++)
- {
- board[i][j] = set;
- }
- }
- }
- void display_board(char board[][COLS], int row, int col)
- {
- printf("---------扫雷游戏-------------\n");
- printf(" ");
- for (int n = 1; n <= col; n++)
- {
- printf("%d ",n);
- }
- printf("\n");
- 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("|");
- printf("\n");
- }
- printf("-----------------------------\n");
-
- }
- void set_mine(char board[][COLS], int row, int col)
- {
-
- int count = MINENUMS;
- while (count)
- {
- int x = rand() % row + 1;
- int y = rand() % col + 1;//设置1~9随机数布置雷
- if (board[x][y] != '1')
- {
- board[x][y] = '1';
- count--;
- }
- }
- }
-
- //获取坐标周围的雷数目(八个格子)
- int get_minecount(char mine[][COLS], int x, int y)
- {
- int n = 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';//减去八个字符零是因为八个字符相加,要转换成数字得到和
- return n;
- }
- void ergodic(char mine[][COLS],char show[][COLS],int x,int y,int *w)//遍历打开不是雷的区域
- {
- int mine_num = get_minecount(mine, x, y);
- if (mine_num == 0)
- {
- show[x][y] = ' ';//如果这个坐标周围都没有雷的话,显示为空格
- (*w)++;
- system("cls");
- display_board(show, ROW, COL);
- /*display_board(mine, ROW, COL);*/
-
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x - 1][y - 1] == '*')
- {
- ergodic(mine,show,x-1,y-1,w);
- }
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y >= 1 && y <= COL) && show[x - 1][y] == '*')
- {
- ergodic(mine, show, x - 1, y,w );
- }
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y +1>= 1 && y+1 <= COL) && show[x - 1][y+1] == '*')
- {
- ergodic(mine, show, x - 1, y+1,w);
- }
- if((x>=1&&x<=ROW)&&(y - 1 >= 1 && y - 1 <= COL) && show[x ][y - 1] == '*')
- {
- ergodic(mine, show, x , y - 1,w);
- }
- if ((x >= 1 && x <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x][y + 1] == '*')
- {
- ergodic(mine, show, x, y + 1,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x + 1][y - 1] == '*')
- {
- ergodic(mine, show, x + 1, y - 1,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y >= 1 && y <= COL) && show[x + 1][y] == '*')
- {
- ergodic(mine, show, x + 1, y,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x + 1][y + 1] == '*')
- {
- ergodic(mine, show, x + 1, y + 1,w);
- }
- }
- else
- {
- show[x][y] = mine_num + '0';
- ///* display_board(mine, ROW, COL);*/
-
- (*w)++;
- }
-
- }
- void find_mine(char mine[][COLS],char show[][COLS],int row,int col)//寻找雷
- {
- int x = 0;
- int y = 0;
- int win = 0;
- int* w = &win;
- while (win < (row * col - MINENUMS))//判断是否已经排查完毕,win相当于一个计数器
- {
- printf("请输入需要排雷的坐标: ");
- scanf("%d %d", &x, &y);
- if (x >= 1 && x <= row && y >= 1 && y <= col)
- {
- if (show[x][y] == '*')
- {
- if (mine[x][y] == '1')
- {
- printf("你被炸死了!\n");
- display_board(show,row,col);
- break;
- }
- else
- {
- /* int count = get_minecount(mine,x,y);
- show[x][y] = count + '0';*/
-
- ergodic(mine,show,x,y,w);
- system("cls");
- display_board(show, ROW, COL);
- /*display_board(mine, ROW, COL);*/
- /*win++;*/
-
- }
- }
- else
- {
- printf("坐标已经被排查过啦!\n");
- }
- }
- else
- {
- printf("输入的坐标有误!\n");
- }
- }
- if (win == row * col - MINENUMS)
- {
- printf("恭喜你,排雷成功!\n\n\n\n");
- display_board(show, ROW, COL);
- }
- }
这里的win相当于计数器,排一个格子,win就加一,作为判断输赢的条件
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
- #include
- #include
- #include
- #include
- #define ROW 9
- #define COL 9//雷盘大小
- #define ROWS ROW+2
- #define COLS COL+2
- #define MINENUMS 10//布置雷数
- void game();
-
- void init_board(char board[][COLS], int rows, int cols, char set);
-
- void display_board(char board[][COLS], int row, int col);
-
- void set_mine(char board[][COLS], int row, int col);
-
- void find_mine(char mine[][COLS], char show[][COLS], int row, int col);
-
- #include"game.h"
-
- void game()
- {
- //设置两个数组,mine数组用来存放设置雷的信息,show数组用来存放排查雷的信息
- char mine[ROWS][COLS] = {0};
- char show[ROWS][COLS] = {0};
- init_board(show,ROWS,COLS,'*');
- init_board(mine, ROWS, COLS, '0');
- //display_board(mine, ROW, COL);
- display_board(show, ROW, COL);
- set_mine(mine,ROW,COL);
- //display_board(mine, ROW, COL);
- find_mine(mine,show,ROW,COL);
- }
-
-
- void init_board(char board[][COLS],int rows,int cols,char set)//初始化雷盘,set是需要初始化成什么字符
- {
- int i = 0;
- int j = 0;
-
- for (i = 0; i < rows; i++)
- {
- for (j = 0; j < cols; j++)
- {
- board[i][j] = set;
- }
- }
- }
-
- //打印雷盘,制作的是9x9的雷盘
- //把雷盘看成一个二维数组打印,为了防止数组越界,我们数组的行和列分别要比想要棋盘的行和列多2
- void display_board(char board[][COLS], int row, int col)
- {
- printf("---------扫雷游戏-------------\n");
- printf(" ");
- for (int n = 1; n <= col; n++)
- {
- printf("%d ",n);
- }
- printf("\n");
- 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("|");
- printf("\n");
- }
- printf("-----------------------------\n");
-
- }
- void set_mine(char board[][COLS], int row, int col)
- {
-
- int count = MINENUMS;
- while (count)
- {
- int x = rand() % row + 1;
- int y = rand() % col + 1;//设置1~9随机数布置雷
- if (board[x][y] != '1')
- {
- board[x][y] = '1';
- count--;
- }
- }
- }
-
- //获取坐标周围的雷数目(八个格子)
- int get_minecount(char mine[][COLS], int x, int y)
- {
- int n = 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';//减去八个字符零是因为八个字符相加,要转换成数字得到和
- return n;
- }
- void ergodic(char mine[][COLS],char show[][COLS],int x,int y,int *w)//遍历打开不是雷的区域
- {
- int mine_num = get_minecount(mine, x, y);
- if (mine_num == 0)
- {
- show[x][y] = ' ';//如果这个坐标周围都没有雷的话,显示为空格
- (*w)++;
- system("cls");
- display_board(show, ROW, COL);
- /*display_board(mine, ROW, COL);*/
-
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x - 1][y - 1] == '*')
- {
- ergodic(mine,show,x-1,y-1,w);
- }
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y >= 1 && y <= COL) && show[x - 1][y] == '*')
- {
- ergodic(mine, show, x - 1, y,w );
- }
- if ((x - 1 >= 1 && x - 1 <= ROW) && (y +1>= 1 && y+1 <= COL) && show[x - 1][y+1] == '*')
- {
- ergodic(mine, show, x - 1, y+1,w);
- }
- if((x>=1&&x<=ROW)&&(y - 1 >= 1 && y - 1 <= COL) && show[x ][y - 1] == '*')
- {
- ergodic(mine, show, x , y - 1,w);
- }
- if ((x >= 1 && x <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x][y + 1] == '*')
- {
- ergodic(mine, show, x, y + 1,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y - 1 >= 1 && y - 1 <= COL) && show[x + 1][y - 1] == '*')
- {
- ergodic(mine, show, x + 1, y - 1,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y >= 1 && y <= COL) && show[x + 1][y] == '*')
- {
- ergodic(mine, show, x + 1, y,w);
- }
- if ((x + 1 >= 1 && x + 1 <= ROW) && (y + 1 >= 1 && y + 1 <= COL) && show[x + 1][y + 1] == '*')
- {
- ergodic(mine, show, x + 1, y + 1,w);
- }
- }
- else
- {
- show[x][y] = mine_num + '0';
- ///* display_board(mine, ROW, COL);*/
-
- (*w)++;
- }
-
- }
-
- void find_mine(char mine[][COLS],char show[][COLS],int row,int col)//寻找雷
- {
- int x = 0;
- int y = 0;
- int win = 0;
- int* w = &win;
- while (win < (row * col - MINENUMS))//判断是否已经排查完毕,win相当于一个计数器
- {
- printf("请输入需要排雷的坐标: ");
- scanf("%d %d", &x, &y);
- if (x >= 1 && x <= row && y >= 1 && y <= col)
- {
- if (show[x][y] == '*')
- {
- if (mine[x][y] == '1')
- {
- printf("你被炸死了!\n");
- display_board(show,row,col);
- break;
- }
- else
- {
- /* int count = get_minecount(mine,x,y);
- show[x][y] = count + '0';*/
-
- ergodic(mine,show,x,y,w);
- system("cls");
- display_board(show, ROW, COL);
- /*display_board(mine, ROW, COL);*/
- /*win++;*/
-
- }
- }
- else
- {
- printf("坐标已经被排查过啦!\n");
- }
- }
- else
- {
- printf("输入的坐标有误!\n");
- }
- }
- if (win == row * col - MINENUMS)
- {
- printf("恭喜你,排雷成功!\n\n\n\n");
- display_board(show, ROW, COL);
- }
- }
-
-
-
-
-
-
- #include"game.h"
- void menu()
- {
- printf("**************************\n");
- printf("********1.开始游戏********\n");
- printf("********0.退出游戏********\n");
- printf("**************************\n");
- }
- int main()
- {
- srand((unsigned int)time(NULL));
- int intput = 0;
- again:
- menu();
- scanf("%d", &intput);
- do
- {
- switch (intput)
- {
- case 1:
- printf("游戏开始\n");
- game();
- goto again;
- case 0:
- printf("退出游戏\n");
- break;
- default:
- printf("输入错误请重新输入\n");
- break;
- }
- } while(intput);
-
- return 0;
- }
-
-
制作不易,给博主一键3连吧!蟹蟹!!!
制作不易,给博主一键3连吧!蟹蟹!!!
制作不易,给博主一键3连吧!蟹蟹!!!