这个扫雷游戏是一个经典的计算机单人游戏,玩家的目标是在一个矩阵(通常是一个矩形或正方形网格)中找出所有没有雷的格子而不触发任何雷。游戏的规则如下:
-
游戏开始时,雷区(
mine
数组)中的雷的位置是随机设置的。玩家看不到雷区的布局,只能看到一个初始的棋盘(show
数组),这个棋盘上的每个格子最开始都被标记为未知(通常用*
表示)。 -
玩家选择一个格子进行打开,如果选中的格子下面是雷(
mine
数组中对应的值为 '1'),游戏结束,玩家输掉游戏。 -
如果选中的格子下面不是雷,则会显示一个数字,这个数字表示该格子周围八个格子中雷的总数。如果周围没有雷,则代替数字会显示一个空格,表示这个区域是安全的。
-
当一个空白格子被打开时,游戏会自动打开周围的其他空白格子,直到所有与之相连的空白区域都被揭示出来。这个过程是递归完成的。
-
玩家继续选择格子进行打开,直到所有不含雷的格子都被打开。如果玩家成功打开所有不含雷的格子,而没有触发任何雷,玩家赢得游戏。
在程序代码中,有几个关键的函数来实现这些规则:
InitBoard
:初始化两个棋盘,mine
和show
。DisplayBoard
:显示棋盘,用于给玩家展示当前游戏状态。SetMine
:在雷区布置雷。GetMineCount
:计算指定格子周围雷的数量。FindMine
:游戏的主逻辑处理,接收玩家的输入,并根据玩家的选择更新棋盘状态。open
:递归打开周围的格子,如果玩家打开的是一个空白格子。
#define _CRT_SECURE_NO_WARNINGS 1
#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 j = 0;
for (j = 0; j < cols; j++) {
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
int i = 0;
printf("----扫雷游戏----\n");
for (i = 0; i <= col; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= row; i++) {
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++) {
printf("%c ",board[i][j]);
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int row, int col) {
int count = COUNT;
int x = 0;
int y = 0;
//布置雷10个
//随机生成坐标
while (count) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0') {
board[x][y] = '1';
count--;
}
}
}
//
//int GetMineCount(char mine[ROWS][COLS], int x, int y) {
// return (mine[x - 1][y] + mine[x - 1][y + 1] + mine[x - 1][y - 1] + mine[x][y + 1] + mine[x][y - 1]
// + mine[x + 1][y - 1] + mine[x + 1][y + 1] + mine[x + 1][y] - 8 * '0');
//}
int GetMineCount(char mine[ROWS][COLS], int x, int y) {
int i = 0;
int count = 0;
for (i = x - 1; i <= x + 1; i++)
{
int j = 0;
for (j = y - 1; j <= y + 1; j++)
{
if (mine[i][j] == '1')
count++;
}
}
return count;
}
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 - COUNT )
{
printf("write down the position>:");
scanf("%d%d", &x, &y);
if (show[x][y] != '*')
{
printf("该坐标被查过了");
continue;
}
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("wrong choice, failed the game\n");
DisplayBoard(mine, ROW, COL);
break;
}
else {
open(mine,show, x, y);
//如果该位置不是雷,统计坐标周围有几个雷
DisplayBoard(show, ROW, COL);
win++;
}
}
else {
printf("wrong position\n");
}
}
if (win == (row * col - COUNT)) {
printf("sucess!\n");
DisplayBoard(mine, ROW, COL);
}
}
void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
if (x >= 1 && x <= ROW && y >= 1 && y <= COL)
{
int count = GetMineCount(mine, x, y);//统计一个格子周围雷的个数,并返回个数count
if (count != 0)
show[x][y] = count + '0';
else if (show[x][y] != ' ')
{
show[x][y] = ' ';
int i = 0;
for (i = x - 1; i <= x + 1; i++)
{
int j = 0;
for (j = y - 1; j <= y + 1; j++)
{
open(mine, show, i, j);
}
}
}
else
{
return;
}
}
}
这些函数是扫雷游戏的一部分,每个都有特定的功能:
通过这个 main
函数,用户可以反复开始新游戏或退出程序。这个函数处理了用户输入、游戏状态的初始化、游戏过程的执行以及游戏结束后的退出。
-
InitBoard
函数用于初始化棋盘。它接收一个棋盘数组board
、行数rows
、列数cols
以及一个用于设置棋盘初始值的字符set
。函数通过双层循环将棋盘的每个位置都设置为set
指定的字符。 -
DisplayBoard
函数用于显示棋盘。它接收棋盘数组board
以及棋盘的行数row
和列数col
。函数首先打印标题和列号,然后打印每一行的行号和该行的内容,每个位置的值后面都跟着一个空格,使得棋盘易于阅读。 -
SetMine
函数用于在棋盘上随机布置雷。它接收棋盘数组board
,行数row
和列数col
,并在棋盘上随机位置布置COUNT
个雷。布雷时会检查所选位置是否已经是雷,如果不是,则设置为雷并减少雷的计数。 -
GetMineCount
函数用于计算指定位置(x, y)
周围的雷的数量。它接收雷区数组mine
和位置坐标x
、y
,然后检查该位置周围八个格子内雷的数量并返回这个数量。 -
FindMine
函数是游戏的主要逻辑部分。它接收雷区数组mine
,玩家显示数组show
,行数row
和列数col
。玩家输入坐标尝试找雷,如果找到雷则游戏失败,如果找到的不是雷,则调用open
函数打开该位置,并更新玩家的显示棋盘。如果玩家找到的非雷区达到了一定数量(总格数减去雷数),则玩家胜利。 -
open
函数用于打开指定位置(x, y)
。如果该位置周围有雷,它将显示雷的数量;如果没有,则将该位置设置为空,并递归地打开周围的格子。这个递归过程会继续,直到所有周围没有雷的格子都被打开。#define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define COUNT 10 #include <stdio.h> #include <stdlib.h> #include <time.h> 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); void open(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
main
函数是这个扫雷游戏程序的入口点。它的工作流程如下: -
首先,包含了一个名为 "game.h" 的头文件,这个头文件可能包含了游戏相关的常量定义、函数原型声明等。
-
接着定义了一个
menu
函数,这个函数打印了一个简单的菜单,提供了游戏开始和退出的选项。 -
然后定义了
game
函数,这是游戏的主体函数。它首先声明并初始化了两个棋盘数组:mine
用于存储雷的位置,show
用于显示给玩家看的棋盘。初始化后,mine
数组中的所有位置都设置为 '0' 表示没有雷,而show
数组则全部设置为 '*' 表示未探明的区域。之后,函数显示玩家棋盘、设置雷的位置、并启动寻雷过程。 -
main
函数开始于设置随机数种子,这是为了确保SetMine
函数能每次运行时都能在不同位置随机布置雷。 -
main
函数进入一个do-while
循环,循环体首先调用menu
函数显示菜单,然后提示用户选择操作。 -
用户输入选择后,程序通过
switch
语句判断用户的输入。如果用户输入1
,则调用game
函数开始游戏;如果输入0
,则打印 "exiting" 并退出循环(随后退出程序);如果输入其他值,程序将提示 "wrong choice" 并再次显示菜单等待用户输入。 -
do-while
循环会持续运行直到用户输入0
为止。