1.扫雷游戏的介绍
(1)扫雷
用最简单的扫雷举例当第一次点击之后,点击的方块附近会出现一些数字
这些数字代表了,以这个数字为中心的3x3的正方形内的雷的个数,当只剩下雷的方块,此时即可胜利
如果中途点击到了雷,则游戏失败。
2.游戏的构思
(1)扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要⼀定的数据结构来存储这些信息。
因为我们需要在9*9的棋盘上布置雷的信息和排查雷,我们⾸先想到的就是创建⼀个9*9的数组来存放信息。
在棋盘上布雷,如果是雷就存放1,如果不是就存放0。
因此,这一步骤的设计到二维数组。
当点击一次之后,应该显示的是这个位置附近的1的个数,如果我们点击边缘的时候,棋盘没有其他的位置,出现了数组的越界,因此,我们应该设置一个11x11的数组,就可以有效避免越界的问题。
在继续分析,当我们点击一个位置之后,这个位置附近的8个方块的1和0的个数应该被存储起来并且打印出,被我们看到,这样才能进行下一步的游戏,但是,如果单单一个数组,雷,雷的个数,存储类型太多,容易产生歧义,因此,可以创建两个数组,为了保持神秘感,在扫雷之前,各个位置应该存放‘*’并打印出来,为了保持两个数组的一致,可以使用两套相同类型的数组,雷和非雷可以用'1'和'0'表示。
mine数组用来存放雷的信息
show数组存放展示给玩家的信息
3.扫雷的实现及分析
(1)
test.c ⽂件中写游戏的测试逻辑
game.h 写游戏需要的数据类型和函数声明等
game.c ⽂件中写游戏中函数的实现等
游戏的模板
(2)代码及其实现
(1)首先在game.h中包含头文件和声明函数
(2)对展示的棋盘row行cols列进行初始化
(3)对展示的棋盘row行cols列进行初始化
(4)布置雷
(5)检测点击的位置的附近的雷的个数
(6)查找雷
自此,扫雷的大体构成了。
4.运行代码
5.总结
扫雷游戏的实现,用到了二维数组和函数,通过二者的结合可以实现一些程序的设计。
6.代码
(1)game.h的源代码
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
(2)game.c的源代码
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
//行
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 1;
printf("*********扫雷*********\n");
//先打印列号
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
int j = 0;
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("*********扫雷*********\n");
}
void SetMine(char arr[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = EASY_COUNT;
while (count)
{
//布置雷
int x = rand() % row + 1;//1~9
int y = rand() % col + 1;//1~9
//布置成功一个雷,count--
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y] + mine[x - 1][y - 1] +
mine[x][y - 1] + mine[x + 1][y - 1] +
mine[x + 1][y] + mine[x + 1][y + 1] +
mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
}
void FindMine(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 - EASY_COUNT)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//不是雷,就统计该坐标周围有几个雷
int n = GetMineCount(mine, x, y);
show[x][y] = n + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
//
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
(3)test.c的源代码
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "game.h"
void menu()
{
printf("************************\n");
printf("**** 1. play ****\n");
printf("**** 0. exit ****\n");
printf("************************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');//'0'
InitBoard(show, ROWS, COLS, '*');//'*'
//打印棋盘
DisplayBoard(show, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//1. 布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//2. 排查雷
FindMine(mine, show, 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("退出游戏\n");
break;
default:
printf("选择错误,重新选择!\n");
break;
}
//
} while (input);
return 0;
}