用C语言实现扫雷游戏

引言:

        在本篇博客中,我们将使用C语言实现一个经典小游戏——扫雷。扫雷游戏是一款受欢迎的益智游戏,目标是根据提示找出没有地雷的方格,避开地雷,同时逐步揭开整个雷区。通过本篇博客,我们将一步步介绍如何设计和实现这个扫雷游戏。

目录

1、 游戏规则

2、游戏整体框架

2.1 初始化雷区

2.2 显示游戏界面

2.3 翻开格子

2.4 递归展开

2.5 判断胜利

3、实现逻辑

3.1 initBoard函数

3.2 displayBoard函数

3.3 setMine函数

3.4 getMineCount函数(递归展开)

3.5 findMine函数

4、完整代码和效果展示

头文件game.h

game.c

main.c

结果展示

1、排雷成功。ps:我们提前把地雷的数量设置为了1。

 2、排雷失败

1、 游戏规则

在开始之前,让我们先了解一下扫雷游戏的基本规则:

  • 通过点击棋盘上的方格来进行探雷。
  • 如果方格没有地雷,将显示周围八个方格中地雷的数量。
  • 如果方格有地雷,游戏失败。
  • 当玩家把除有地雷的方格外的所有方格都揭开,玩家胜利。

2、游戏整体框架

        在我们开始编写具体代码之前,让我们先来了解扫雷游戏的整体框架。游戏主要分为以下几个功能模块

2.1 初始化雷区

        游戏开始时,会初始化一个9x9的雷区,同时随机布置一定数量的地雷。

2.2 显示游戏界面

        游戏界面以表格形式呈现,玩家可以通过坐标输入来选择要翻开的格子。

2.3 翻开格子

        玩家输入坐标后,游戏会判断该格子是否是地雷,如果是地雷,则游戏结束;如果不是地雷,则会显示周围地雷的数量。

2.4 递归展开

        如果玩家选择了一个没有地雷并且周围地雷数为0的格子,游戏会自动展开周围的空格,并继续展开空格周围的空格,直到周围有地雷或边界为止。

2.5 判断胜利

        游戏会统计翻开的格子数量,当所有不含地雷的格子都被翻开时,游戏胜利。

3、实现逻辑

这个C语言实现的扫雷游戏采用了函数式的编程方式,主要包括以下几个函数:

3.1 initBoard函数

        用于初始化游戏的雷区和显示区,设置地雷和数字格的初始状态。

void initBoard(char arr[ROWS][COLS], int x, int y, int row, int col, char set) {
	for (int i = x; i < row+x; i++) {
		for (int j = y; j <col+y; j++) {
			arr[i][j] = set;
		}
	}
}

3.2 displayBoard函数

        显示游戏的界面,包括雷区和当前的翻开情况。

void displayBoard(char arr[ROWS][COLS]) {
	system("cls");
	printf("------------------扫雷------------------\n");
	for (int i = 0; i <= ROW; i++) {
		printf(" %d |", i);
	}
	printf("\n");
	for (int i = 0; i <= ROW; i++) {
		printf("----");
	}
	printf("\n");
	for (int i = 1; i <= ROW; i++) {
		printf(" %d |", i);
		for (int j = 1; j <= COL; j++) {
			if (arr[i][j] == 'X') {
				if (win != 0) {
					printf(" \033[31m%c\033[0m |", arr[i][j]);
				}
				else {
					printf(" \033[32m%c\033[0m |", arr[i][j]);
				}
			}
			else {
				printf(" %c |", arr[i][j]);
			}
		}
		printf("\n");
		for (int j = 0; j <= COL; j++) {
			printf("----", arr[i][j]);
		}
		printf("\n");
	}
	printf("------------------扫雷------------------\n");
}

3.3 setMine函数

        随机布置地雷,保证地雷的位置不重复。

void setMine(char arr[ROWS][COLS], int count) {
	while (count) {
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
		if (arr[x][y] == '0') {
			arr[x][y] = '1';
			count--;
		}
	}
}

3.4 getMineCount函数(递归展开)

        计算指定格子周围地雷的数量。

void getMineCount(char arr1[ROWS][COLS], char arr2[ROWS][COLS], int x, int y) {
	if(arr2[x][y] == '*'){
		int count = arr1[x - 1][y - 1] + arr1[x - 1][y] +
		arr1[x - 1][y + 1] + arr1[x][y - 1] +
		arr1[x][y + 1] + arr1[x + 1][y - 1] +
		arr1[x + 1][y] + arr1[x + 1][y + 1] - 8 * '0';
		if (count == 0) {
			arr2[x][y] = ' ';
			win--;
			getMineCount(arr1, arr2, x - 1, y - 1);
			getMineCount(arr1, arr2, x - 1, y);
			getMineCount(arr1, arr2, x - 1, y + 1);
			getMineCount(arr1, arr2, x, y - 1);
			getMineCount(arr1, arr2, x, y + 1);
			getMineCount(arr1, arr2, x + 1, y - 1);
			getMineCount(arr1, arr2, x + 1, y);
			getMineCount(arr1, arr2, x + 1, y + 1);
		}
		else {
			arr2[x][y] = count + '0';
			win--;
		}
	}
}

3.5 findMine函数

        处理玩家的输入,翻开格子,展开空白格,并判断游戏胜利或失败。

void findMine(char arr1[ROWS][COLS], char arr2[ROWS][COLS]) {
	while (win) {
		int x, y;
		printf("请输入坐标,并用空格隔开:");
		scanf("%d %d", &x, &y);
		if (arr1[x][y] == '1') {
			markMine(arr1, arr2);//游戏结束,把地雷的位置在用户表上标记出来
			displayBoard(arr2);
			printf("\033[31m很遗憾,游戏结束!!!\033[0m\n");
			break;
		}
		else {
			//统计这个坐标周围有几个雷,若是0;则变为' ',并自动计算周围八个格子的值
			getMineCount(arr1, arr2, x, y);
			displayBoard(arr2);
		}
	}
	if (win == 0) {
		markMine(arr1, arr2);
		displayBoard(arr2);
		printf("\033[32m恭喜你,排雷成功!!!\033[0m\n");
	}
}

4、完整代码和效果展示

在这一部分,我们将给出完整的C语言代码实现,并展示游戏效果。

头文件game.h

#pragma once


//定义雷区为9*9的方块
#define ROW 9
#define COL 9


//为了方便计算数字,定义的数组我们多加两行两列,
//地雷的位置和数字不放在最边上的行和列
#define ROWS ROW+2
#define COLS COL+2


//难度--地雷的数量
#define _EASY 10


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>


//初始化表,x,y表示初始化的起始坐标,row和col表示初始化的表的大小,ch表示初始化的内容
void initBoard(char arr[ROWS][COLS], int x, int y, int row, int col, char set);


//显示用户表
void displayBoard(char arr[ROWS][COLS]);


//排查地雷
void findMine(char arr1[ROWS][COLS], char arr2[ROWS][COLS]);

game.c

#define _CRT_SECURE_NO_WARNINGS 1


#include "game.h"


void initBoard(char arr[ROWS][COLS], int x, int y, int row, int col, char set) {
	for (int i = x; i < row+x; i++) {
		for (int j = y; j <col+y; j++) {
			arr[i][j] = set;
		}
	}
}


//定义win,表示除地雷外的空格数
int win = ROW * COL - _EASY;


void displayBoard(char arr[ROWS][COLS]) {
	system("cls");
	printf("------------------扫雷------------------\n");
	for (int i = 0; i <= ROW; i++) {
		printf(" %d |", i);
	}
	printf("\n");
	for (int i = 0; i <= ROW; i++) {
		printf("----");
	}
	printf("\n");
	for (int i = 1; i <= ROW; i++) {
		printf(" %d |", i);
		for (int j = 1; j <= COL; j++) {
			if (arr[i][j] == 'X') {
				if (win != 0) {
					printf(" \033[31m%c\033[0m |", arr[i][j]);
				}
				else {
					printf(" \033[32m%c\033[0m |", arr[i][j]);
				}
			}
			else {
				printf(" %c |", arr[i][j]);
			}
		}
		printf("\n");
		for (int j = 0; j <= COL; j++) {
			printf("----", arr[i][j]);
		}
		printf("\n");
	}
	printf("------------------扫雷------------------\n");
}


void setMine(char arr[ROWS][COLS], int count) {
	while (count) {
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
		if (arr[x][y] == '0') {
			arr[x][y] = '1';
			count--;
		}
	}
}


//游戏结束,把地雷的位置在用户表上标记出来
static void markMine(char arr1[ROWS][COLS], char arr2[ROWS][COLS]) {
	for (int i = 1; i <= ROW; i++) {
		for (int j = 1; j <= COL; j++) {
			if (arr1[i][j] == '1') {
				arr2[i][j] = 'X';
			}
		}
	}
}


//计算坐标周围雷的数量
static void getMineCount(char arr1[ROWS][COLS], char arr2[ROWS][COLS], int x, int y) {
	if(arr2[x][y] == '*'){
		int count = arr1[x - 1][y - 1] + arr1[x - 1][y] +
		arr1[x - 1][y + 1] + arr1[x][y - 1] +
		arr1[x][y + 1] + arr1[x + 1][y - 1] +
		arr1[x + 1][y] + arr1[x + 1][y + 1] - 8 * '0';
		if (count == 0) {
			arr2[x][y] = ' ';
			win--;
			getMineCount(arr1, arr2, x - 1, y - 1);
			getMineCount(arr1, arr2, x - 1, y);
			getMineCount(arr1, arr2, x - 1, y + 1);
			getMineCount(arr1, arr2, x, y - 1);
			getMineCount(arr1, arr2, x, y + 1);
			getMineCount(arr1, arr2, x + 1, y - 1);
			getMineCount(arr1, arr2, x + 1, y);
			getMineCount(arr1, arr2, x + 1, y + 1);
		}
		else {
			arr2[x][y] = count + '0';
			win--;
		}
	}
}


void findMine(char arr1[ROWS][COLS], char arr2[ROWS][COLS]) {
	while (win) {
		int x, y;
		printf("请输入坐标,并用空格隔开:");
		scanf("%d %d", &x, &y);
		if (arr1[x][y] == '1') {
			markMine(arr1, arr2);
			displayBoard(arr2);
			printf("\033[31m很遗憾,游戏结束!!!\033[0m\n");
			break;
		}
		else {
			//统计这个坐标周围有几个雷,若是0;则变为' ',并自动计算周围八个格子的值
			getMineCount(arr1, arr2, x, y);
			displayBoard(arr2);
		}
	}
	if (win == 0) {
		markMine(arr1, arr2);
		displayBoard(arr2);
		printf("\033[32m恭喜你,排雷成功!!!\033[0m\n");
	}
}

main.c

#define _CRT_SECURE_NO_WARNINGS 1


#include "game.h"


//打印菜单
void menu() {
	printf("****************************\n");
	printf("*******    1.play    *******\n");
	printf("*******    0.exit    *******\n");
	printf("****************************\n");
}


//游戏函数
void game() {
	//地雷区和扫雷得到的数字分别存放在两个数组中
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	
	//初始化两张表:把地雷表数据初始化为'0',数字表初始化为'*'
	initBoard(mine,0,0,ROWS,COLS,'0');
	initBoard(show,0,0,ROWS,COLS,' ');
	initBoard(show,1,1,ROW,COL,'*');


	//布置地雷
	setMine(mine, _EASY);


	//显示用户表
	displayBoard(show);


	//排查地雷-->若是地雷则游戏结束,反之计算这个坐标位置的数值,并显示结果
	findMine(mine, show);
		
}


int main() {
	int input = 0;
	srand((unsigned int)time(NULL));
	do {
		menu();
		printf("输入 1 开始游戏:");
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入有误,请重新输入\n");
		}
	} while (input);
}

结果展示

1、排雷成功。ps:我们提前把地雷的数量设置为了1。

 2、排雷失败

总结:

        在本篇博客中,我们详细介绍了如何用C语言实现扫雷游戏。通过阅读这篇博客,您将了解到扫雷游戏的基本规则、整体框架以及代码实现。希望本篇博客能帮助您更好地学习和理解C语言编程。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值