一、文件的创建
这里我们创建三个文件俩个源文件,一个头文件
源文件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,则退出菜单 ,并跳出break default: // 当用户选择不是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 -9 printf("\n"); //换行,所以第一行为0-9 for (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之间,所以我们进行加1 y = rand() % col + 1; //产生一个随机值 if (board[x][y] == '0') //如果这个地方没有雷, board[x][y] ='1'; // 我们在这里布上雷,即让坐标里的数字为1 count--; // 布雷一次,我们对雷的数量-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< row*col-10) // 如果玩家的格子为9x9-10即71时,说明玩家一颗雷都没中 { scanf("%d%d", &x, &y); //接收玩家的坐标 if (x >= 1 && x <= 9 && y >= 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‘