扫雷游戏__9*9

本文详细介绍了如何在控制台上实现经典扫雷游戏,包括游戏规则、数据结构设计(如解决越界问题和存储雷信息的方法),以及关键代码片段如game.h,game.c和test.c的功能。游戏使用9x9棋盘,随机布置10个雷,玩家可以排查雷并统计周围雷的数量,以避免被炸死。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、扫雷游戏的功能说明

1、使用控制台实现经典的扫雷游戏

2、游戏可以通过菜单实现继续玩或者退出游戏

3、扫雷的棋盘是9*9的格子

4、 默认随机布置10个雷

5、可以排查雷【如果位置不是雷,就显示周围有几个雷】【如果位置是雷,就炸死游戏结束】

6、把除10个雷之外的所有非雷都找出来,排雷成功,游戏结束

二、数据结构分析

【越界问题的解决】:

【如何解决数据冲突呢?】:

【文件结构】:

三、扫雷代码

【game.h】

【game.c】

【test.c】

四、运行示意图

【被炸死了】

【未完待续】


一、扫雷游戏的功能说明


1、使用控制台实现经典的扫雷游戏

2、游戏可以通过菜单实现继续玩或者退出游戏

3、扫雷的棋盘是9*9的格子

4、 默认随机布置10个雷

5、可以排查雷
【如果位置不是雷,就显示周围有几个雷】
【如果位置是雷,就炸死游戏结束】

6、把除10个雷之外的所有非雷都找出来,排雷成功,游戏结束

二、数据结构分析

1、扫雷时,我们需要创建一个数组来储存布置的雷和排查出的雷信息。

首先想到创立9*9的数组存放信息(这个位置布置雷放1,反之,则为0)

假设排查(2,4)这个坐标,访问它周围一圈8个方格位,统计周围雷的个数

【越界问题的解决】:

假设排查(1,8)这个坐标,访问它周围一圈8个方格位,统计周围雷的个数时,发现上面三个坐标会越界。

那我们就给数组扩大一圈,设计为11*11,雷的放置区域依旧是9*9,这样就解决这个问题啦。

当我们在棋盘上布置雷时,棋盘上雷的信息为1,无雷的信息为0;

假设我们排查一个位置的坐标后,它不是雷,统计它周围一圈雷的个数为1,我们需要把排查出的雷的数量信息记录储存,并且打印出来,作为排雷的重要参考信息。

但是这个雷的个数信息放哪里?如果是放在布置雷的数组中,那么雷的信息和周围一圈雷的个数信息,这两者会发生混淆和打印错误。

【如何解决数据冲突呢?】:

Plan A:布置雷时,不用数字,使用字符。【例:雷为(@),非雷为(^)】

Plan B:设置2个棋盘(11*11),一个放布置好雷的信息(对应数组mine),另一个放排查出的雷的信息(对应数组show)。【本文使用Plan B】:把雷布置于数组mine中,并在这里排查雷,排查出的数据放在数组show,并打印数组show为后面排查做参考。

char mine[11][11] = {0};  //存放布置好雷的信息
char show[11][11] = {0};  //存放排查出雷个数的信息
【文件结构】:
test.c   //文件中写游戏的运行测试逻辑
game.c   //文件中写游戏中函数的实现
game.h   //文件中写游戏需要使用的数据类型和函数声明

三、扫雷代码

【game.h】

#pragma once

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

#define EASY_COUNT 10

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

//初始化棋盘
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);

【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;
	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");
	//打印数组show棋盘
	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 = EASY_COUNT;     //count=10
	while (count)  
	//count=0时,雷都布置完了,不再进去循环了
	{
		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_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
			//防止输入的坐标超过棋盘范围
		{
			if (mine[x][y] == '1')
			//点到雷了
			{
				printf("很遗憾,你被炸死啦!\n");
				//展示数组mine中雷的位置
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
          //没点到雷,统计这个坐标周围一圈雷的个数
			{
				int count = GetMineCount(mine, x, y);
				show[x][y] = count + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		//输入的坐标超出范围
		{
			printf("输入坐标错误,重新输入!\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功啦!!\n");
		DisplayBoard(mine, ROW, COL);
	}

}

【test.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];   //存放已经排查出的雷的信息

	//对棋盘进行初始化
	InitBoard(mine, ROWS, COLS, '0');   //数组mine开始全为0
	InitBoard(show, ROWS, COLS, '*');   //数组show开始全为*

	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);

	//布置雷的位置
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, 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;
}

四、运行示意图

【被炸死了】

【未完待续】

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值