当然这个扫雷游戏没法像电脑上的那个那么完善,只能在编译器的环境下玩。尽管如此,但是大部分扫雷的功能是有的。
其实需要思考的有以下几点
我们通过设置两个二维数组,一个放雷,一个显示,如果我们要一个99的雷区,就要设置两个11
11的数组,我们通过在雷盘上的操作,将其显示到展示的棋盘上
在红色的范围内放置地雷,打印时也只需要打印红色范围,因为如果在整个范围放置地雷,统计时会遇到越界问题
1.通过增加雷的个数以及改变雷的个数来增加难度
2.关于空白处的展开,会用到函数的递归
3.为了防止一落子便被炸死,增加可玩性,我们在第一次不让玩家被炸死,设置一个静态变量计数器,并将此处的雷转移
4.雷数的统计,我们将雷设置为1,空白为0,这样就好统计了
代码
#define _GAME_H_
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define mine_count 10
char sweep(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int rows, int cols, int x, int y);
void Init_board(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols);
void printf_board(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols);
void set_mine(char mine_board[ROWS][COLS], int row, int col);
void find_mine(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols);
char get_mine(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int rows, int cols, int x, int y);
#endif
void menu(){
char mine_board[ROWS][COLS];//定义两个数组 char show_board[ROWS][COLS]; int input = 0; printf("********扫雷*********\n"); printf("***1 play 0 exit****\n"); printf("*********************\n"); printf("请选择:"); do{ scanf("%d", &input); switch (input){ case 0: break; case 1: game(mine_board,show_board,ROWS,COLS,ROWS,COLS); break; default: printf("请重新输入:"); break; } } while (input);
}
2.游戏函数
void game(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols)
{
int input = 1; while (input){ Init_board(mine_board, show_board, ROW, COL, ROWS, COLS);//初始化雷盘和显示盘 /*printf_board(mine_board, show_board, ROW, COL, ROWS, COLS);*/ set_mine(mine_board, ROW, COL);//放置地雷 printf_board(mine_board, show_board, ROW, COL, ROWS, COLS);//打印雷盘 find_mine(mine_board, show_board, ROW, COL, ROWS, COLS);//玩家找雷 /*printf_board(mine_board, show_board, ROW, COL, ROWS, COLS);*/ printf("\n是否继续 : \n继续 》1 \n结束 》 0 \n请选择"); scanf("%d", &input); } return 0;
}
3.初始化雷盘和显示盘
void Init_board(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols){
int i = 0; int j = 0; for (i = 0; i < rows;i++) for (j = 0; j < cols; j++) mine_board[i][j] = '0'; //将雷盘初始化为字符0 for (i = 0; i < rows; i++) for (j = 0; j < cols; j++) show_board[i][j] = '*'; //将显示盘初始化为*
}
4.打印雷盘和显示盘
void printf_board(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols){
int i = 0; int j = 0; for (i = 0; i <= row; i++) { //打印展示数组 printf("%d ", i); } printf("\n"); for (j = 1; j <= row; j++) { printf("%d", j); for (i = 1; i <= col; i++) printf(" %c", show_board[j][i]); printf("\n"); }
for (i = 0; i <= row; i++) { //打印放雷数组 printf("%d ", i); } printf("\n"); for (j = 1; j <= row; j++) { printf("%d", j); for (i = 1; i <=col; i++) printf(" %c", mine_board[j][i]); printf("\n"); }
}
5.随机放置地雷
void set_mine(char mine_board[ROWS][COLS], int row, int col){
int x = 0; int y = 0; int count = mine_count; // 计数器为雷的个数 while (count) { x = rand() % row + 1; // 产生随机数 y = rand() % row + 1; if (mine_board[x][y] == '0') { mine_board[x][y] = '1'; count--; //将所有的雷放完为止 } }
}
6.玩家找地雷
void find_mine(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col, int rows, int cols){
int x = 0; int y = 0; int i = 0; int j = 0; static int count = 0; //声明一静态常量计数器,用来检测玩家是否为第一次落子
while (1) { printf("玩家输入:"); scanf("%d %d", &x, &y); count++; if (x >= 0 && x <= ROW&&y >= 0 && y <= ROW) //输入要在雷区范围内 { if (mine_board[x][y] == '1') { if (count == 1) { mine_board[x][y] = '0'; //将地雷换到别的地方去 int x1 = 0; int x2 = 0; x1 = rand() % row + 1; x2 = rand() % row + 1; if (mine_board[x1][x2] != '1'){ mine_board[x1][x2] = '1'; printf("此处有雷");//防止玩家第一次落子便被炸死 } } else{ printf("你被炸死了\n"); return 0; } } else if (mine_board[x][y] == '0')//如果此处无雷 { get_mine(mine_board, show_board, ROWS, COLS, x, y); //统计周围雷的个数 sweep(mine_board, show_board, x, y); //如果周围也没雷则展开
printf_board(mine_board, show_board, ROW, COL, ROWS, COLS); } else printf("请重新输入:"); if (count == row*col - mine_count) { printf("游戏结束"); return 0; } } } }
7.判断周围雷的个数
char get_mine(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int rows, int cols, int x, int y);{
if (x > 0 && x <= ROWS - 2 && y > 0 && y <= ROWS - 2){
show_board[x][y] = (mine_board[x - 1][y] + mine_board[x - 1][y - 1] + mine_board[x - 1][y + 1] + mine_board[x][y + 1] + mine_board[x + 1][y + 1] + mine_board[x + 1][y] + mine_board[x + 1][y - 1] + mine_board[x][y - 1]) - 8 * '0' + 48; //将周围所有的雷每个都减去字符0,加起来的个数为其数字个数,加上48将其转换为字符数字输出
return show_board[x][y];
}
return 0;
}
8.展开空白雷区
char sweep(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int rows, int cols, int x, int y){
if ((x >= 0) && (x <= ROWS) && (y >= 0) && (y <= ROWS)) { if (get_mine(mine_board, show_board, ROWS, COLS, x, y) == '0')//判断周围雷的个数是否为0 { show_board[x][y] = ' '; if (show_board[x - 1][y - 1] == '*')//对周围八个方向分别进行递归 { sweep(mine_board, show_board, x - 1, y - 1); } if (show_board[x - 1][y] == '*') { sweep(mine_board, show_board, x - 1, y); } if (show_board[x - 1][y + 1] == '*') { sweep(mine_board, show_board, x - 1, y + 1); } if (show_board[x][y - 1] == '*') { sweep(mine_board, show_board,x, y - 1); } if (show_board[x][y + 1] == '*') { sweep(mine_board, show_board, x, y +1); } if (show_board[x + 1][y - 1] == '*') { sweep(mine_board, show_board, x+1, y - 1); } if (show_board[x + 1][y] == '*') { sweep(mine_board, show_board, x+1, y); } if (show_board[x + 1][y + 1] == '*') { sweep(mine_board, show_board, x+1, y + 1); } } else show_board[x][y] = get_mine(mine_board, show_board, ROWS, COLS, x, y);;//如果周围有雷则显示雷的个数 }
}
完成结果