【C语言】扫雷【附源码】

一、扫雷游戏规则

尽快找到雷区中的所有不是地雷的格子,而不许踩到地雷。点开的数字是几,则说明该数字旁边的8个位置中有几个雷,如果挖开的是地雷,则会输掉游戏。

二、代码思路:

  • 宏定义

    • RowCol 定义了棋盘的行数和列数。
    • RowsCols 分别定义了棋盘数组的行数和列数,多出来的两行两列是为了在棋盘的四周留出空白区域。
    • EASY 定义了简单难度下的地雷数量。
  • 函数原型

    • InitBoard():初始化棋盘函数原型,用于在程序的其他地方实现初始化棋盘的功能。
    • DisplayBoard():打印棋盘函数原型,用于在程序的其他地方实现打印棋盘的功能。
    • SetMine():布置地雷函数原型,用于在程序的其他地方实现布置地雷的功能。
    • FindMine():找地雷函数原型,用于在程序的其他地方实现找地雷的功能。
  • 菜单函数 menu()

    • 这个函数用于显示游戏的菜单界面,提供了两个选项:开始游戏和退出游戏。
    cpp 复制代码
    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,即只要用户不选择退出游戏,就会一直循环显示菜单。
    cpp 复制代码
    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()

    • 这个函数负责实现扫雷游戏的核心逻辑。
    • 首先声明了两个二维字符数组 mineshow,用于存储扫雷棋盘的地雷分布情况和显示给玩家的棋盘情况。
    • 调用 InitBoard() 函数初始化两个棋盘。
    • 调用 SetMine() 函数设置地雷的位置。
    • 调用 DisplayBoard() 函数显示初始的棋盘给玩家。
    • 最后调用 FindMine() 函数开始游戏,排查地雷并更新显示给玩家的棋盘。
    cpp 复制代码
    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
  • 参数 rowscols 分别表示棋盘的行数和列数。
cpp 复制代码
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() 函数

    1. 用于显示棋盘的当前状态,包括地雷和已经排查的区域。
    2. 打印出棋盘的行号和列号,以及对应位置的字符。
    3. 参数 rowcol 表示棋盘的行数和列数。
cpp 复制代码
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() 函数

    1. 用于设置地雷在棋盘上的位置。
    2. 参数 rowcol 分别表示棋盘的行数和列数。
    3. 使用 rand() 函数生成随机数,随机设置地雷的位置。
    4. count 变量表示地雷的数量,根据不同的难度(这里是简单难度)来设置地雷的数量。
cpp 复制代码
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() 函数

    1. 用于统计某个位置周围地雷的数量。
    2. 参数 xy 表示要统计的位置坐标。
    3. 遍历该位置周围的八个方向,统计周围地雷的数量。
cpp 复制代码
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() 函数

    1. 实现了玩家排雷的过程。
    2. 使用 while 循环,直到排查完所有非地雷的位置或者踩到地雷为止。
    3. 每次循环提示玩家输入坐标,然后判断该位置是否有地雷。
    4. 如果踩到地雷,则游戏失败,显示所有地雷的位置。
    5. 如果没有踩到地雷,则统计周围地雷的数量,并更新显示给玩家的棋盘。
    6. 循环结束后,根据游戏是否成功来显示相应的消息
cpp 复制代码
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

cpp 复制代码
#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

cpp 复制代码
#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

cpp 复制代码
#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);//找地雷
相关推荐
荒川之神1 小时前
拉链表概念与基本设计
java·开发语言·数据库
chushiyunen1 小时前
python中的@Property和@Setter
java·开发语言·python
爱编码的小八嘎1 小时前
C语言完美演绎6-17
c语言
小樱花的樱花1 小时前
C++ new和delete用法详解
linux·开发语言·c++
froginwe111 小时前
C 运算符
开发语言
fengfuyao9852 小时前
低数据极限下模型预测控制的非线性动力学的稀疏识别 MATLAB实现
开发语言·matlab
摇滚侠2 小时前
搭建前端开发环境 安装 nodejs 设置淘宝镜像 最简化最标准版本 不使用 NVM NVM 高版本无法安装低版本 nodejs
java·开发语言·node.js
t198751282 小时前
MATLAB十字路口车辆通行情况模拟系统
开发语言·matlab
yyk的萌2 小时前
AI 应用开发工程师基础学习计划
开发语言·python·学习·ai·lua
DfromY3 小时前
【随手记】YOCTO下MQTT使用简记
c语言·网络协议