提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
在开始今天的内容之前,首先我们要清楚什么是”扫雷“游戏?
扫雷游戏的规则是,当点击某个位置时:
如果这个位置有雷,玩家就会被炸,展示雷盘中所有雷的位置,游戏结束;
如果这个位置没有雷,则玩家点击的这个位置就会出现一个数字,这个数字代表的是这个位置周围一圈(8个位置)的雷的总数。
春雨后太阳,缓缓的露出笑容.............................................................
一、游戏的实现思路
首先扫雷游戏的实现需要有两个二维数组,一个用来存放布置雷的信息,一个用来存放排查雷的信息,存放雷的数组将其命名为"Bombs",其中排查雷是提供给玩家来进行排查操作的,该数组显示的是玩家排查的坐标周围8个位置雷的总个数,所以我们将该数组命名为"ShowBombs"。
我们编写一个9*9的简单模式,但设计数组时,我们需要都将两个数组设计为 11 行 和 11 列的二维数组。而不是9行9列,理由是:当玩家选定一个坐标时,当这个坐标位于雷盘的边缘位置时,并且该坐标没有雷,需要计算该坐标周围存在雷的个数。故会出现访问雷盘之外元素的情况,而设置成 11 X 11 的二维数组,可以避免因为判断边界周围雷的个数而产生数组越界的问题。需要注意的是当打印雷盘和布置雷和排查雷的时候,只需要打印 9 X 9 的雷盘和对 9 X 9 的雷盘范围进行相应的布置和排查即可。我们分别将两个数组初始化,Bombs存放’0‘而在Bombs中布置雷时将’0‘替换为’1‘(原因是:字符数字-字符0 = 十进制数字,十进制数字+字符0 = 字符数字。布置雷的位置标记为字符1。这样在计算选定坐标周围雷的个数时,可以将这个坐标为中心的九宫格范围的其他八个位置存放的字符相加减去8个字符0即可。)
同样的,该游戏的实现也需要用到”模块化编写“(详情见上期三子棋的实现)。
主要步骤分为:
1.设计游戏菜单
2.创建两个二维数组(分别用来存放雷,所选坐标周围雷的个数)
3.对数组进行初始化
4.打印雷盘(显示雷信息的数组)
5.布置雷(存放类的数组)
6.排查雷(在存放雷的数组中进行排查,并在存放雷信息的数组中进行打印)
7.对游戏结果进行判断
二、功能模块的编写
2.1菜单的实现
同三子棋一样,进行游戏时需为玩家提供可选择的菜单。代码部分:
void menu()
{
printf("****************************\n");
printf("*********1.开始扫雷*********\n");
printf("*********0.退出游戏*********\n");
printf("****************************\n");
}
效果图:
2.2初始化二维数组
因为这里我们需要进行两次 二维数组初始化,所以我们在进行函数的编写时,不妨把每个数组初始化的内容也当作参数进行设计,使程序编写更加便利。
代码:
void InitBoard(char board[ROWS][COLS], int rows, int cols,char ret)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ret;
}
}
}
2.3显示雷盘
这里只需要显示ShowBombs即可代码部分:
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}//打印横行便于确定每个元素的位置
printf("\n");
for (i = 1; i <=row; i++)
{
printf("%d ", i);//打印竖行便于确定每个元素的位置
for (j = 0; j < col; j++)
{
//printf("%d\n", j);
printf("%c ", board[i][j]);
}
printf("\n");
}
}
效果图:
2.4布置雷
利用srand函数随机布置雷,即将’0‘替换为’1‘代码:
void SetBombs(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = EasyCount;
while (count)
{
x = rand() % row+1;
y = rand() % col+1;
if (board[x][y] == '0')//确保在正确的位置上布置雷。
{
board[x][y] = '1';
count--;
}
}
}
2.4排查雷
这部分对玩家输入的位置进行排查,代码部分:
int GetBombs(char board[ROWS][COLS], int x, int y)
{
return (board[x - 1][y] +
board[x - 1][y - 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1] +
board[x][y + 1] +
board[x - 1][y + 1] - 8 * '0');
}
void CheckBombs(char board[ROWS][COLS], char showboard[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = row * col - EasyCount;
while (win )
{
printf("请输入要检查的坐标\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (showboard[x][y] == '*')//确保排查的位置未被排查过
{
if (board[x][y] == '1')
{
printf("游戏结束\n");
DisplayBoard(board, ROW, COL);
break;
}
else
{
int ret = GetBombs(board, x, y);
showboard[x][y] = ret + '0';
DisplayBoard(showboard, ROW, COL);
win--;
}
}
else
{
printf("已排查过该位置\n");
}
}
else
{
printf("坐标输入错误\n");
}
}
if (win == 0)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(board, ROW, COL);
}
}
三、完整代码
3.1game.h部分
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <sidlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EasyCount 10
//初始化
void InitBoard(char board[ROW][COL],int row, int col,char ret);
//打印
void DisplayBoard(char board[ROW][COL],int row, int col);
//布置雷
void SetBombs(char board[ROW][COL], int row, int col);
//排查雷
void CheckBombs(char board[ROW][COL], char showboard[ROW][COL], int row, int col);
3.2game.c部分
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols,char ret)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = ret;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <=row; i++)
{
printf("%d ", i);
for (j = 0; j < col; j++)
{
//printf("%d\n", j);
printf("%c ", board[i][j]);
}
printf("\n");
}
}
void SetBombs(char board[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = EasyCount;
while (count)
{
x = rand() % row+1;
y = rand() % col+1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
int GetBombs(char board[ROWS][COLS], int x, int y)
{
return (board[x - 1][y] +
board[x - 1][y - 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1] +
board[x][y + 1] +
board[x - 1][y + 1] - 8 * '0');
}
void CheckBombs(char board[ROWS][COLS], char showboard[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = row * col - EasyCount;
while (win)
{
printf("请输入要检查的坐标\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (showboard[x][y] == '*')
{
if (board[x][y] == '1')
{
printf("游戏结束\n");
DisplayBoard(board, ROW, COL);
break;
}
else
{
int ret = GetBombs(board, x, y);
showboard[x][y] = ret + '0';
DisplayBoard(showboard, ROW, COL);
win--;
}
}
else
{
printf("已排查过该位置\n");
}
}
else
{
printf("坐标输入错误\n");
}
}
if (win == 0)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(board, ROW, COL);
}
}
3.3test.c部分
#include "game.h"
void menu()
{
printf("****************************\n");
printf("*********1.开始扫雷*********\n");
printf("*********0.退出游戏*********\n");
printf("****************************\n");
}
void game()
{
char Bombs[ROWS][COLS] = { 0 };
char ShowBombs[ROWS][COLS] = { 0 };
InitBoard(Bombs, ROWS, COLS, '0');
//DisplayBoard(Bombs, ROW, COL);
InitBoard(ShowBombs, ROWS, COLS, '*');
DisplayBoard(ShowBombs, ROW, COL);
SetBombs(Bombs, ROW, COL);
CheckBombs(Bombs, ShowBombs, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择>:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
3.4成果图
总结
这篇文章,讲述了简单版扫雷游戏的实现,欢迎大家指正!
........我回忆画面有你情节.................
—————《夏天》