欢迎来到英杰社区https://bbs.csdn.net/topics/617804998
一、扫雷游戏规则
尽快找到雷区中的所有不是地雷的格子,而不许踩到地雷。点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地雷,则会输掉游戏。
二、代码思路:
-
宏定义:
Row
和Col
定义了棋盘的行数和列数。Rows
和Cols
分别定义了棋盘数组的行数和列数,多出来的两行两列是为了在棋盘的四周留出空白区域。EASY
定义了简单难度下的地雷数量。
-
函数原型:
InitBoard()
:初始化棋盘函数原型,用于在程序的其他地方实现初始化棋盘的功能。DisplayBoard()
:打印棋盘函数原型,用于在程序的其他地方实现打印棋盘的功能。SetMine()
:布置地雷函数原型,用于在程序的其他地方实现布置地雷的功能。FindMine()
:找地雷函数原型,用于在程序的其他地方实现找地雷的功能。
-
菜单函数
menu()
:- 这个函数用于显示游戏的菜单界面,提供了两个选项:开始游戏和退出游戏。
void menu() { printf("*****************************\n"); printf("*****************************\n"); printf("***********1.play************\n"); printf("***********0.exit************\n"); printf("*****************************\n"); printf("*****************************\n"); printf("*****************************\n"); }
-
主函数
main()
:- 在
main()
函数中,首先声明了一个整型变量input
,用于接收用户的输入选项。 - 进入一个
do-while
循环,这个循环会一直执行,直到用户选择退出游戏(输入0
)。 - 在循环内部,首先调用
menu()
函数显示菜单界面,然后通过scanf()
函数获取用户的选择,并存储在input
变量中。 - 使用
switch
语句根据用户的选择执行相应的操作:- 如果用户选择
1
,则调用game()
函数开始游戏。 - 如果用户选择
0
,则打印消息表示退出游戏。 - 如果用户输入其他数字,则提示用户重新选择。
- 如果用户选择
- 循环条件是
input != 0
,即只要用户不选择退出游戏,就会一直循环显示菜单。
int main() { srand((unsigned int)time(NULL)); int input = 0; do { menu(); printf("请选择:"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏"); break; default: printf("输入错误请重新输入"); break; } } while (input); return 0; }
- 在
-
游戏函数
game()
:- 这个函数负责实现扫雷游戏的核心逻辑。
- 首先声明了两个二维字符数组
mine
和show
,用于存储扫雷棋盘的地雷分布情况和显示给玩家的棋盘情况。 - 调用
InitBoard()
函数初始化两个棋盘。 - 调用
SetMine()
函数设置地雷的位置。 - 调用
DisplayBoard()
函数显示初始的棋盘给玩家。 - 最后调用
FindMine()
函数开始游戏,排查地雷并更新显示给玩家的棋盘。
void game() { char mine[Rows][Cols]; char show[Rows][Cols]; InitBoard(mine, Rows, Cols, '0'); InitBoard(show, Rows, Cols, '*'); DisplayBoard(mine, Row, Col); DisplayBoard(show, Row, Col); SetMine(mine, Row, Col); //DisplayBoard(mine, Row, Col); FindMine(mine, show, Row, Col); }
InitBoard()
函数:
- 用于初始化棋盘,将棋盘的每个格子都设置为指定的字符
set
。- 参数
rows
和cols
分别表示棋盘的行数和列数。
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;
}
}
}
-
DisplayBoard()
函数:- 用于显示棋盘的当前状态,包括地雷和已经排查的区域。
- 打印出棋盘的行号和列号,以及对应位置的字符。
- 参数
row
和col
表示棋盘的行数和列数。
void DisplayBoard(char board[Rows][Cols], int row, int col) {
int i = 0;
int j = 0;
printf("---------- 扫雷 -----------\n");
for (i = 0; i <= col; i++) {
printf("%d ", i);
}
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");
}
-
SetMine()
函数:- 用于设置地雷在棋盘上的位置。
- 参数
row
和col
分别表示棋盘的行数和列数。 - 使用
rand()
函数生成随机数,随机设置地雷的位置。 count
变量表示地雷的数量,根据不同的难度(这里是简单难度)来设置地雷的数量。
void SetMine(char board[Rows][Cols], int row, int col) {
int count = EASY;
while (count) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0') {
board[x][y] = '1';
count--;
}
}
}
-
GetMineCount()
函数:- 用于统计某个位置周围地雷的数量。
- 参数
x
和y
表示要统计的位置坐标。 - 遍历该位置周围的八个方向,统计周围地雷的数量。
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';
}
-
FindMine()
函数:- 实现了玩家排雷的过程。
- 使用
while
循环,直到排查完所有非地雷的位置或者踩到地雷为止。 - 每次循环提示玩家输入坐标,然后判断该位置是否有地雷。
- 如果踩到地雷,则游戏失败,显示所有地雷的位置。
- 如果没有踩到地雷,则统计周围地雷的数量,并更新显示给玩家的棋盘。
- 循环结束后,根据游戏是否成功来显示相应的消息
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) {
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 sum = GetMineCount(mine, x, y);
show[x][y] = sum + '0';//1+'0'='1'
DisplayBoard(show, Row, Col);
win++;
}
}
else {
printf("坐标错误重新输入");
}
}
if (win == Row * Col - EASY) {
printf("恭喜你排雷成功");
DisplayBoard(mine, Row, Col);
}
}
三、完整代码
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu() {
printf("*****************************\n");
printf("*****************************\n");
printf("***********1.play************\n");
printf("***********0.exit************\n");
printf("*****************************\n");
printf("*****************************\n");
printf("*****************************\n");
}
void game() {
char mine[Rows][Cols];
char show[Rows][Cols];
InitBoard(mine, Rows, Cols, '0');
InitBoard(show, Rows, Cols, '*');
DisplayBoard(mine, Row, Col);
DisplayBoard(show, Row, Col);
SetMine(mine, Row, Col);
//DisplayBoard(mine, Row, Col);
FindMine(mine, show, Row, Col);
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误请重新输入");
break;
}
} while (input);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#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 (i = 0; i <= col; i++) {
printf("%d ", i);
}
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;
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][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) {
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 sum = GetMineCount(mine, x, y);
show[x][y] = sum + '0';//1+'0'='1'
DisplayBoard(show, Row, Col);
win++;
}
}
else {
printf("坐标错误重新输入");
}
}
if (win == Row * Col - EASY) {
printf("恭喜你排雷成功");
DisplayBoard(mine, Row, Col);
}
}
game.h
#pragma once
#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 10
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);//找地雷