1 引言
第二篇博客,这是一个用c语言写的扫雷小游戏,比较的简易。
主要用到的知识是——数组。
2 游戏规则
2.1 网页版:
第一次点击不会是雷,格子里的数表示它周围有几个雷。游戏的目标是找出所有的雷。触雷则输。
同时如果判断有雷,可以单机鼠标右键,标记该地方有雷。
2.2 本篇扫雷规则:
1.随机布置十个雷,在9乘9的二维数组中
2.排查雷,通过输入格子坐标来排查雷,在排查过程中,如果该格子没有雷,会显示出周围一圈其他8个格子中有几个雷;如果该格子有雷,很遗憾!表示触雷了。
3 扫雷自制
3.1 文件
需要三个文件:
分别在源文件和头文件下创建game.c,test.c,和game.h
test.c:用于构建扫雷的整体框架结构
game.h:用于存放扫雷中出现的函数的声明,以及所要用到的头文件(简单来说是main函数头上那一堆)
game.c:用于编写扫雷用到的函数定义
3.2 test.c 详解
1.主要包括main函数:
2.菜单栏:
主要作用是显示菜单经行选择进入游戏或者退出游戏
运行截图:
3.game函数:
初始化棋盘:设置一个mine[ ] [ ] 数组存放棋盘中的雷——默认是字符0;
一个show[ ][ ]数组存放棋盘中周围的雷——默认是数组*;
还有在game.c中的一些函数
4.foramework函数:
通过do...while循环语言实现菜单栏的选项:
在循环中使用 switch 语句根据用户的选择执行相应的操作:
- 如果用户选择 1,则调用 game() 函数开始游戏。
- 如果用户选择 0,则打印消息表示退出游戏。
- 如果用户输入其他数字,则提示用户重新选择。
5.具体代码
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu() {
printf("********************\n");
printf("*****1.进入游戏******\n");
printf("*****0.退出游戏******\n");
printf("********************\n");
}
void game() {
char mine[ROWS][COLS] = { 0 };//存放棋盘中的雷
char show[ROWS][COLS] = { 0 };//存放棋盘中周围雷的数量
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印扫雷棋盘
DisplayBoard(show, ROW, COL);
//进行安装雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//排查雷与雷的信息
FindMine(mine, show, ROW, COL);
}
void framework() {
int input = 0;
do {
menu();
printf("请选择:");
scanf("%d", &input);
if (input == 0) {
printf("退出游戏\n");
break;
}
else if (input == 1) {
game();
continue;
}
else
{
printf("重新输入\n");
input = 1;
}
} while (input);
}
int main() {
framework();
return 0;
}
3.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 EASY_COUNT 10
//定义扫雷的棋盘
void InitBoard(char board[ROWS][COLS], int rows, int clos, char set);
//打印扫雷的棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//进行安装雷
void SetMine(char board[ROWS][COLS], int rows, int cols);
//排查雷与雷的信息
int GetMineCount(char mine[ROWS][COLS], int x, int y);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
3.4 game.c详解
1.InitBoard函数
用于初始化棋盘——将棋盘默认为字符0
2.DisplayBoard函数
用于打印扫雷的棋盘——用字符*将棋盘中的字符0隐藏
3.SetMine函数
用于随机生成10颗雷——通过time函数随机生成
4. FindMine函数
排雷并表明格子附近有几颗雷
其中包括一个GetMineCount函数:遍历周围有几颗雷
5.具体代码:
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int n = 0;
for (n = 0; n < cols; n++) {
board[i][n] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int rows, int cols) {
printf("********扫雷********\n");
int i;
for (i = 0; i <= cols; i++) {
printf("%d ", i);
}
printf("\n");
int n;
for (n = 1; n <= rows; n++) {
printf("%d ", n);
int j;
for (j = 1; j <= cols; j++) {
printf("%c ", board[n][j]);
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int rows, int cols) {
int count = EASY_COUNT;
int a;
int b;
while (count)
{
srand(time(0));
a = rand() % rows + 1;
b = rand() % cols + 1;
if (board[a][b] != '1') {
board[a][b] = '1';
count--;
}
}
}
int GetMineCount(char mine[ROWS][COLS], int x, int y) {
int a = 0;
int i = 0;
for (i = -1; i <= 1; i++) {
int n = 0;
for (n = -1; n <= 1; n++) {
a += (mine[x + i][y + n] - '0');
}
}
return a; //a代表周围雷的个数
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x;
int y;
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 count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("输入的坐标有问题,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你!排雷成功!\n");
DisplayBoard(mine, ROW, COL);
}
}
4 运行截图
5 改进
扫雷有很多可以改进的地方比如:
可以通过递归的方式将一个没有雷且周围也没有雷的格子附近都显示出来。
需要满足条件
1.该坐标不是雷
2.该坐标周围没有雷
3。该坐标没有被排查过——对该坐标周围的8个坐标,做上述的递归操作。