1.扫雷小游戏分析和设计
1.1 扫雷小游戏的玩法
- 游戏可通过控制台实现游玩或退出
- 游戏的棋盘为9*9(可调整)
- 随机布置十个雷(可调整)
- 排查位置不是雷,就显示周围有几个雷
- 排查位置是雷,结束游戏,返回菜单
- 把所有不是雷的地方找出,游戏胜利
1. 2 扫雷小游戏的分析和设计
1.2.1 数据结构的分析
扫雷过程中,我们需要将雷的位置、排查的位置等信息存储下来,需要一定的数据结构来存储信息。
我们要在9*9的棋盘上排雷,所以需要一个数组来存放信息。
雷就用1来表示,非雷就用0
当我们排查某个坐标时,会统计它周围八个位置的雷的数量,但是当我们排查棋盘边缘的位置时,访问周围的八个位置必然会越界,所以我们可以将数组预留出一圈非雷的位置,以防止越界的发生。
当我们排查某一坐标时,若周围共一个雷,那这个位置就应该显示1,那这又和雷无法区别,所以我们需要两个数组,一个数组用来存放雷的信息(mine数组),一个数组展示给玩家(show数组),我们选择将其中元素全初始化为‘*’,为了保证两数组类型一致,我们将mine数组初始化为‘0’。
1.2.2 文件结构的分析
为了方便管理以及后续的拓展,我们将整个小游戏分为三个文件来实现,分别用到一个头文件和两个源文件。
game.h//用来定义数据和声明函数等
game.c//游戏中函数的实现
test.c//游戏中的测试逻辑
2.扫雷小游戏代码实现
game.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
//行数
#define ROW 9
#define ROWS ROW + 2
//列数
#define COL 9
#define COLS COL + 2
//雷数
#define EASY_COUNT 9
//初始化棋盘
void InitBoard(char board[ROWS][COLS], char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS]);
//布置雷
void SetMine(char board[ROWS][COLS]);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]);
game.c
#include "game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], char set)
{
for (int i = 0; i < ROWS; i++)
{
for (int n = 0; n < COLS; n++)
{
board[i][n] = set;
}
}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS])
{
printf("------扫雷游戏------\n");
for (int m = 0; m <= COL; m++)
printf("%d ", m);
printf("\n");
for (int i = 1; i < ROWS - 1; i++)
{
printf("%d ", i);
for (int n = 1; n < COLS - 1; n++)
{
printf("%c ", board[i][n]);
}
printf("\n");
}
}
//布置雷
void SetMine(char board[ROWS][COLS])
{
int count = EASY_COUNT;
while (count)
{
//产生随机坐标
int x = rand() % ROW + 1;
int y = rand() % COL + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
//统计周围雷数量
int CountMine(char mine[ROWS][COLS], int x, int y)
{
return (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');
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS])
{
int win = 0;
while (win < COL * ROW - EASY_COUNT)
{
DisplayBoard(show);
int x = 0;
int y = 0;
printf("请输入要排查的坐标:");
scanf("%d%d", &x, &y);
if (x > 0 && x <= ROW && y > 0 && x <= COL)
{
if (mine[x][y] == '0')
{
system("cls");
show[x][y] = CountMine(mine, x, y) + '0';
win++;
}
else
{
system("cls");
printf("你踩到雷了,游戏结束~~\n");
DisplayBoard(mine);
system("pause");
system("cls");
break;
}
}
else
{
system("cls");
printf("坐标不合法,请重新输入\n");
}
if (win == COL * ROW - EASY_COUNT)
{
printf("恭喜你!!所有地雷均已排除!\n");
DisplayBoard(mine);
system("pause");
system("cls");
}
}
}
test.c
#include "game.h"
//打印菜单
void menu()
{
printf("**********************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("**********************\n");
}
//实现游戏
void game()
{
char show[ROWS][COLS] = { 0 };
char mine[ROWS][COLS] = { 0 };
//初始化棋盘
InitBoard(show, '*');
InitBoard(mine, '0');
//布置雷
SetMine(mine);
//排查雷
FindMine(mine, show);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
system("cls");
if (input == 1)
game();
else if (input == 0)
break;
else
printf("输入错误,请重新输入");
}
while (input);
return 0;
}