一、扫雷游戏分析和设计
1.1 扫雷游戏的功能说明
使⽤控制台实现经典的扫雷游戏
游戏可以通过菜单实现继续玩或者退出游戏
扫雷的棋盘是9*9的格⼦
默认随机布置10个雷
可以排查雷
如果位置不是雷,就显⽰周围有⼏个雷
如果位置是雷,就炸死游戏结束
把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束
二、思路分析
1.数据结构的分析
一般来说扫雷的简单模式是9*9的界面,我们需要判断周围8个格子有几颗雷,
但是四周的格子无法判断,因为他们周围没有8个格子,
所以我们在设计界面时就用11*11的界面,这样就保证了所有格子
都可以判断周围的8个格子,而在显示的时候,仅显示9*9的界面即可。
通过两个数组来实现,
一个数组用来存储棋盘本身的数据,这个数组称为mine
一个用来对外展示,这个数组称为show
mine数组
如果这个位置布置雷,我们就存放字符'1',没有布置雷就存放字符'0'
show数组
全部初始化为字符'*'
对应的代码
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
char mine[ROWS][COLS];
char show[ROWS][COLS];
2.文件结构设计
1.text.c 游戏的主函数
2.game.c 函数的实现
3.game.h 数据类型和函数声明
3.游戏代码的实现
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define COUNT 10 //雷的数量
void menu();
void game();
//初始化数组
void init(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void print(char arr[ROWS][COLS], int row, int col);
//设置炸弹
void display_TNT(char arr[ROWS][COLS], int row, int col);
//检查炸弹
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
text.c
#include "game.h"//先引用game.h
主函数内
int main()
{
int option = 0;
srand((unsigned)time(NULL));
do
{
menu();
scanf("%d", &option);
switch (option)
{
case 1:
game();
break;
case 0:
printf("game over\n");
break;
default:
printf("input error\n");
break;
}
} while (option);
return 0;
}
用库函数<time.h>和<stdlib.h>
srand((unsigned int)time(NULL))来获取随机数
建立菜单
void menu()
{
printf("************\n");
printf("***1.play***\n");
printf("***0.exit***\n");
printf("************\n");
printf("请选择>");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化数组
init(mine, ROWS, COLS, '0');
init(show, ROWS, COLS, '*');
printf("-----game start-----\n");
//开始游戏
print(show, ROW, COL);
//设置炸弹
display_TNT(mine, ROW, COL);
//查看TNT
//print(mine, ROW, COL);
//play
find_mine(mine, show, ROW, COL);
}
game.c
#include "game.h"//先引用game.h
初始化棋盘
void init(char arr[ROWS][COLS], int rows, int cols, char set)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
打印棋盘
void print(char arr[ROWS][COLS], int row, int col)
{
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
for (int j = 1; j <= col; j++)
{
printf("%-2c", arr[i][j]);
}
printf("\n");
}
}
设置炸弹
void display_TNT(char arr[ROWS][COLS], int row, int col)
{
int count = COUNT;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
检查炸弹
static int number_mine(char mine[ROWS][COLS], int x, int y)
{
int i = 0;
int j = 0;
int number = 0;
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
number += (mine[i][j] - '0');
}
}
return number;
}
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < row * col - COUNT)
{
printf("要排查的坐标>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] == '*')
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
print(mine, ROW, COL);
break;
}
else
{
int count = 0;
count = number_mine(mine, x, y);
show[x][y] = count + '0';
print(show, row, col);
win++;
}
}
else
{
printf("该坐标已经排查过了\n");
}
}
else
{
printf("输入错误,重新输入\n");
}
}
if (win == row * col - COUNT)
{
printf("恭喜你拿下\n");
print(mine, row, col);
}
}
4.运行游戏