> 文档中心 > C语言实现扫雷

C语言实现扫雷

目录

一、文件的创建

二、用户界面的建立

1.菜单建立

 2.用户选择的建立

三、游戏环节的建立和输赢条件的判断

1.游戏规则

2.游戏棋盘的搭建

2.1棋盘的定义

2.2棋盘的打印

3.开始布雷

 4.玩家进行找雷

4.1.1未找到雷,对周围雷个数加和函数

四、微小优化

五、测试

5.1排完雷结果测试

5.2踩到雷结果测试

5.3未踩到雷结果测试

六、待优化

七、代码部分

game.h

test.c

game.c


一、文件的创建

这里我们创建三个文件俩个源文件,一个头文件

源文件test.c(用来测试) game.c(用来实现游戏函数),头文件game.h(用来声明函数) 

 

二、用户界面的建立

1.菜单建立

这里我们编辑一个简单的函数,实现用户选择界面

void menu(){printf("**********************************\n");printf("***********1.play*****************\n");printf("***********0.exit*****************\n");printf("**********************************\n");}

定义好了之后去主函数里简单的测试一下

 2.用户选择的建立

菜单界面有了,接下来该用户来进行选择了

int input; //定义一个整型变量用来存放用户输入的值while (1)   //while(1)意思为死循环{menu();  // 进入菜单界面printf("请选择:");   //让用户选择scanf("%d", &input); //用户进行选择switch (input) // 判断用户的选择满足下列哪个条件{case 1:  printf("扫雷游戏:\n");game();break;     // 若用户选择1,打印出扫雷游戏字样,并进入game()游戏函数,当游戏结束后,break自动跳出while(1)循环case 0: printf("退出菜单");break;  //用户输入0,则退出菜单 ,并跳出breakdefault:  // 当用户选择不是0和1,告诉用户输入有误,并让他重新输入printf("输入错误请重新输入:");}

 用户选择界面建立好了,将他放在主函数中

 

int main(){int input;while (1){menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("扫雷游戏:\n");game();break;case 0:printf("退出菜单");break;default:printf("输入错误请重新输入:");}

 主函数搭建完成,在我们设置的规则中,用户按1后要进入游戏,所以大家看到有一个game()函数,接下来就是编写game()函数,即游戏环节的代码

三、游戏环节的建立和输赢条件的判断

1.游戏规则

当输入棋盘中的一个坐标后,若此坐标有雷,游戏直接宣告失败,若此棋盘没有雷则该棋盘上会显示周围8个位置(上下左右,左上,左下,右上,右下)所有雷个数的总和

2.游戏棋盘的搭建

我们采用的是9x9的棋盘格,用输入坐标的形式来扫雷,但是直接9x9容易让人看错坐标,所以加以改善,我们将横纵坐标都打印出来.

 

像这样,以便于用户输入准确的坐标

2.1棋盘的定义

由于是9x9的棋盘,我们要建立一个11x11的二维数组,防止最边上的坐标在计算周围雷个数的时候发生越界,也就是说我们建立一个11x11的二维数组,但实际只用到9个

#define ROW 9#define COL 9#define COLS COL+2#define ROWS ROW+2

于是我们在game.h头文件里声明,因为这里的横纵数列我们后面有很多次要用到,

定义完之后,我们在game.c和test.c函数里面引用一下

 

现在开始创建俩个11x11的二维数组,第一个数组用来放雷,第二个数组用来找雷

 

char board[ROWS][COLS] = { 0 };char mine[ROWS][COLS] = { 0 };

这里再game()里定义

定义好之后先给俩个二维数组赋值

按照什么赋值? 

我们规定:0代表没有雷,1代表有雷,当用户选择完之后我们应显示一张棋盘且不能让用户看到我们的雷布置在哪,所以我们用*来给雷“穿上外套”。像下图这样用户选择完后,看不到哪里是雷

接下来我们定义一个函数,负责给俩个数组遍历并赋值,第一个函数全部赋值为0,此时表示还没有布置雷,第二个函数全部遍历*,让用户后期负责在*里面找雷

传参

Itnboard(board, ROWS, COLS, '0');Itnboard(mine, ROWS, COLS, '*'); 
Itnboard(char board[ROWS][COLS], int rows, int cols, char set){int i;int j;for (i = 0; i < rows; i++)for (j = 0; j < cols; j++)board[i][j] = set;}

 这是赋值函数,我们先给11x11所有格子上都赋上值

2.2棋盘的打印

定义game.h一个函数来打印棋盘,在test.c里面引用,在game.c里面实现函数

test.c:

Displayboard(mine, ROW, COL);

game.h:

Displayboard(char board[ROWS][COLS], int row, int col);

game.c

 

Displayboard(char board[ROWS][COLS], int row, int col){int i;    int j; //定义俩个变量用来遍历数组printf("---------------- 扫雷游戏----------------------\n");for (i = 0; i <=row; i++)printf("%d ", i);   //  先打印0 -9printf("\n");    //换行,所以第一行为0-9for (i = 1; i <=row ; i++)     // 开始遍历数组{printf("%d ", i);//在每行开头打上相应的行坐标for (j = 1; j <=col ; j++){printf("%c ", board[i][j]);}printf("\n");     // 打印完一行后换行}printf("---------------- 扫雷游戏----------------------\n");}

 效果:

3.开始布雷

 这里布置10个雷即可,我们让电脑来随机布雷,先定义布雷的函数,再进行声明,在引用

game.h:

ComputerSet(char board[ROWS][COLS], int row, int col);

 test.c

ComputerSet(board,ROW,COL);  //这里我们在9x9的格子里布雷,所以传参的时候穿 ROW和COL,他们的数值都是9

game.c:

ComputerSet(char board[ROWS][COLS], int row, int col){int x;int y;    // 定义俩个变量来接收布雷的位置int count = 10;  // 布雷的个数while(count)     //当布雷的数量减到0时,退出循环,即结束布雷{x = rand() % row + 1;    // 产生一个随机值,这里为了确保随机值在1-9之间,我们对让随机值对row进行取余,row=9,余数在0-8之间,所以我们进行加1y = rand() % col + 1;     //产生一个随机值if (board[x][y] == '0')   //如果这个地方没有雷,board[x][y] ='1'; // 我们在这里布上雷,即让坐标里的数字为1count--; // 布雷一次,我们对雷的数量-1}Displayboard(board, row, col); // 打印一下棋盘,我们看看布雷效果}

 

 4.玩家进行找雷

像前面一样,定义game.h一个函数来定义函数,在test.c里面引用,在game.c里面实现函数

game.h

Playmove(board,mine, ROW, COL);

test.c

Playmove(board,mine, ROW, COL);

game.c

Playmove(char board[ROWS][COLS],char mine[ROWS][COLS], int row, int col){int x;int y;    // 定义俩个数值,用来让玩家输入坐标int count = 0; //记录一下玩家未找到雷的格子printf("请输入坐标:");while (count= 1 && x = 1 && y <= 9)  // 判断玩家输入坐标是否合法{if (board[x][y] == '1')    {printf("你被炸死了:");break;  // 如果踩到雷,告知玩家被炸死了,并退出循环}else{    int ch = fun(board, x, y);mine[x][y] = ch + '0';  // 如果没踩到雷,我们对这个格子周围雷的个数加和,这里定义了一个加和函数为int型int型加'0',可将其转换为字符型数字Displayboard(mine,row,col);  打印一下棋盘,让玩家获取当前信息count++;     玩家所扫棋盘数加一,这个值到79会跳出循环}}else{printf("输入错误,请重新输入"); 如果玩家输入的值不合法,让玩家重新输入}if(count==row*col-10) printf("玩家胜利");  // 当跳出while循环时,看看count是否等于79,如果等于79则宣布玩家胜利}

4.1.1未找到雷,对周围雷个数加和函数

int fun(char board[ROWS][COLS], int x, int y)   // 注意这里传参不能char board[ROWS][COLS] 虽然只在9x9中操作,但是他是11x11的表格必须完整传过来{return board[x - 1][y - 1] +board[x - 1][y] +board[x - 1][y + 1] +board[x][y - 1] +board[x][y + 1] +board[x + 1][y - 1] + board[x + 1][y] +board[x + 1][y + 1] - 8 * '0';} 

由于board[][]中存放的是字符类型,但我们定义的是一个int类型,为了能返回正确的数值,我们要对字符型数字减‘0’,这样才能输出int型数字,由于有8个字符型数字,要减去8个字符型0,所以我们这里用8*’0‘

四、微小优化

在电脑布雷的时候我们定义了count,让他等于10,

 玩家输入坐标并判断输赢时候,我们也用到了数字10

 我们为了方便,在game.h里可#define COT 10

到时候可以直接用COT来代替10

五、测试

5.1排完雷结果测试

由于有10个雷,71个空格我们一一排查需耗费大量时间,所以我们将雷设置为80,此时只有一个位置没有雷,这时候我们选中这个位置

此时7,7这个地方没有雷,当我们选中时,告诉我们排雷成功

5.2踩到雷结果测试

将雷数量重新设置回10

此时踩到了雷,宣布被炸死

5.3未踩到雷结果测试

 

 4,4坐标显示没有雷,但其周围8个地方又有2个雷,此时4,4位置打印数字2

六、待优化

待优化点:点开一个不是雷的地方开铺开一大片显示没雷的地方

七、代码部分

game.h

#pragma once#include#include#include#define ROW 9#define COL 9#define COT 10#define COLS COL+2#define ROWS ROW+2Itnboard(char board[ROWS][COLS], int rows, int cols, char set);Displayboard(char board[ROWS][COLS], int row, int col);ComputerSet(char board[ROWS][COLS], int row, int col);Playmove(char board[ROWS][COLS],char mine[ROWS][COLS], int row, int col);//玩家排雷

test.c

 

#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"void menu(){printf("**********************************\n");printf("***********1.play*****************\n");printf("***********0.exit*****************\n");printf("**********************************\n");}void game(){char board[ROWS][COLS] = { 0 };char mine[ROWS][COLS] = { 0 };Itnboard(board, ROWS, COLS, '0');Itnboard(mine, ROWS, COLS, '*'); //初始化棋盘Displayboard(mine, ROW, COL);//打印棋盘ComputerSet(board,ROW,COL);Playmove(board,mine, ROW, COL);}int main(){srand((unsigned int)time(NULL));int input;while (1){menu();printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("扫雷游戏:\n");game();break;case 0:printf("退出菜单");break;default:printf("输入错误请重新输入:");}}}

game.c

#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"Itnboard(char board[ROWS][COLS], int rows, int cols, char set){int i;int j;for (i = 0; i < rows; i++)for (j = 0; j < cols; j++)board[i][j] = set;}int fun(char board[ROWS][COLS], int x, int y){return board[x - 1][y - 1] +board[x - 1][y] +board[x - 1][y + 1] +board[x][y - 1] +board[x][y + 1] +board[x + 1][y - 1] +board[x + 1][y] +board[x + 1][y + 1] - 8 * '0';}Displayboard(char board[ROWS][COLS], int row, int col){int i;int j;printf("---------------- 扫雷游戏----------------------\n");for (i = 0; i <=row; i++)printf("%d ", i);printf("\n");for (i = 1; i <=row ; i++){printf("%d ", i);for (j = 1; j <=col ; j++){printf("%c ", board[i][j]);}printf("\n");}printf("---------------- 扫雷游戏----------------------\n");}Playmove(char board[ROWS][COLS],char mine[ROWS][COLS], int row, int col){int x;int y;int count=0;while (count= 1 && x = 1 && y <= 9){if (board[x][y] == '1'){printf("你被炸死了:");break;}else{    int ch = fun(board, x, y);mine[x][y] = ch + '0';Displayboard(mine,row,col);count++;}}else{printf("输入错误,请重新输入");}}if (count == row * col - COT)printf("恭喜你,排雷成功");}ComputerSet(char board[ROWS][COLS], int row, int col){int x;int y;int count = COT;while(count){x = rand() % row + 1;y = rand() % col + 1;if (board[x][y] == '0'){board[x][y] = '1';count--;}}Displayboard(board, row, col);}