1.前言
开始新的小游戏——扫雷。相信各位都是玩过扫雷的,今天我们就来讲一讲如何用C语言写出扫雷游戏。
同之前的三子棋一样,我们依旧创建三个文件,tesc.c、game.c、game.h。
test.c ——测试游戏的逻辑
game.c ——游戏代码的实现
game.h ——游戏代码的声明(函数声明,符号定义)
文件名可自定义哦。
以 9 × 9 的简单扫雷为例。
首先,我们知道扫雷即知道某点周围一圈的雷数,根据雷数踩下无雷的位置,踩下后显示该点雷数,依此类推,便可通关游戏。
2.选择是否开始游戏(打印菜单)
用switch语句选择是否开始游戏,选1,开始游戏;选0,退出游戏;其他数字选项,均为错误选项,让用户重新选择。如下图所示:
而,头文件#include<game.h>文件中,又包括了#include<stdio.h>
3.开始游戏
写一个game函数,包括打印初始的扫雷格子,以及在扫雷后,显示的扫雷格子。这就需要我们创建两个数组,一个用来布置雷的位置,另一个用来排查雷。
(1) 初始化数组
首先,我们创建数组,一个mine数组(用来布置雷),且在没有布置雷的地方都初始化为 ‘ 0 ’ ,另一个show数组(排查雷),在没有排查雷的地方都初始化为 ‘ * ’ 。
这里在初始化是,我们要传四个参数,其中最后一个参数,是用来区分初始化的是mine数组,还是show数组。
(2)打印扫雷界面
通过函数DisplayBoard打印扫雷界面,代码如下:
**打印了show数组的扫雷界面,毕竟雷的位置是需要隐藏起来的。 **
(3)设置雷
设置雷,可以放到显示前,也可以放到显示后。因为反正我们显示的这个数是显示的排查雷的情况。设置雷,我们就写一个SetMine函数。
(4)排查雷
我们就定义一个Fine Mine函数,先判断所选坐标是不是雷,如果不是雷,就统计该坐标周围的总雷数,并标记到该坐标。如果全部排雷,则排雷成功!
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 (show[x][y] != '*')
{
printf("该坐标被排查过了,不能重复排查\n");
}
//如果是雷
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else//如果不是雷
{
win++;
//统计mine数组中x,y坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';//转换成数字字符
DisplayBoard(show, ROW, COL);
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
这里,我们还需统计一下该点坐标周围的雷数,我们写一个get_mine_count函数来统计。
主要是判断八个方位上的点是否已经被标记为 ‘ 1 ’。
int get_mine_count(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');
}
4.源代码
(1)test.c
#include"game.h"
void menu()
{
printf("****************************\n");
printf("******** 1 . play ********\n");
printf("******** 0 . exit ********\n");
printf("****************************\n");
}
void game()
{
char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
//初始化数组的内容为指定的内容
//mine 数组在没有布置雷的时候,都是‘0’
InitBoard(mine, ROWS, COLS, '0');
//show 数组在没有排查雷的时候,都是‘*’
InitBoard(show, ROWS, COLS, '*');
//DisplayBoard(mine, ROW, COL);
//设置雷
SetMine(mine,ROW,COL);
DisplayBoard(show, ROW, COL);
//排查雷
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:
printf("扫雷游戏开始!\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
(2)game.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("-----扫雷游戏-----\n");
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("-----扫雷游戏-----\n");
}
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
//1~9
//1~9
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
int get_mine_count(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 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 (show[x][y] != '*')
{
printf("该坐标被排查过了,不能重复排查\n");
}
//如果是雷
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else//如果不是雷
{
win++;
//统计mine数组中x,y坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';//转换成数字字符
DisplayBoard(show, ROW, COL);
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
(3)game.h
#include<stdio.h>
#include<time.h>
#include<stdlib.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 cols, char set);
void DisplayBoard(char board[ROWS][COLS], int rows, int cols);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
5.可开辟的功能
在这篇文章上,我们还可以开辟其他的功能。
例如:展开一片的功能;
标记(插旗)的功能。
版权归原作者 Audery867 所有, 如有侵权,请联系我们删除。