栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

如何用C语言实现扫雷(可展开)——最详细

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何用C语言实现扫雷(可展开)——最详细

前言: 

对于这个游戏大家都不陌生了,扫雷游戏起源于1973年的“方块”游戏。1992年微软发布的Windows 3.1中加入该游戏,从此风靡全世界。

今天我们就动手自己来写一个扫雷游戏

经典扫雷游戏规则:

当玩家点击游戏区域,该处周围的八个位置有几个雷(如果是角落则是周边三个位置雷的个数,边缘位置同理),就展示数字几.如果该处是雷则直接结束游戏.

一,想法与构思 1基本思路

如果我们要实现一个9*9棋盘的扫雷,为了计算边缘或者角落雷的个数我们可以将雷区变成12*12的棋盘,将最外围的棋盘全部变为0,

这样不论是哪个位置的雷,我们都可以计算其周边8个位置雷个数的和,

2.实现过程

想要创作一个扫雷游戏我们需要以下过程

1创造一个进入游戏的菜单,让用户输入是否要进入游戏

2创建两个二维数组,一个展示给玩家,一个用来设置雷的信息

3将两个棋盘初始化为'0'和'*'

4设置雷的存放信息,在棋盘上随机生成雷

5将给用户的棋盘打印出来

6让玩家输入坐标,然后判断,如果是雷,则宣告游戏失败,如果不是雷则计算周围雷的个数并打印在棋盘上

代码实现

首先为了让代码可以修改和看起来更加方便我们将他分为三个部分

test.c

游戏的大体框架

game.h

函数的声明

game.c

整个游戏的实现

首先我们要有一个代码的框架test.c

#include"game.h"
menu()//打印一个开始菜单
{
	printf("*******扫雷游戏*******n");
	printf("*********************n");
	printf("***0.exit    1.exe***n");
	printf("*********************n");

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


	return 0;
}

这里就是我们的一个大致思路,让用户来选择游戏的开始与结束。

这里存放的是一些函数的声明,game.h

#pragma once
#include 
#include 
#include 
#pragma warning (disable :4996)

#define ROW 9
#define COL 9

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

#define NUM 10

//初始化棋盘函数
void InitBoard(char board[ROWS][COLS], int, int, char);

//打印棋盘函数
void Display(char board[ROWS][COLS], int,int);

//埋雷
void SETMINE(char board[ROWS][COLS], int row, int col);

//排	雷
void FINDMINE(char[ROWS][COLS], char[ROWS][COLS], int, int);

//计算周围的雷数
int get_round(char[ROWS][COLS], int, int);

//如果周围不是雷那么展开这一片
void NoMine(char mine[ROWS][COLS],char show [ROWS][COLS],int x, int y);

game.c的实现

这里是我们的重点,让我们一起来看看如何实现这个游戏

void game()
{
	//设置棋盘
	char mine[ROWS][COLS] = { 0 };//用来存放雷的棋盘
	char show[ROWS][COLS] = { 0 };//展示给用户的棋盘
	
	//初始化棋盘
	InitBoard(mine, ROWS, COLS,'0');
	InitBoard(show, ROWS, COLS,'*');
	
	//打印棋盘
	 Display(show, ROW, COL);
	//Display(mine, ROW, COL);
	
	//埋雷在mine数组中
	SETMINE(mine, ROW, COL);
	//Display(mine, ROW, COL);
	//排雷
	FINDMINE(mine, show, ROW, COL);

}

这是我们要在game函数中需要完成的事情接下来我们将会一一实现

1.设置棋盘

设置两个棋盘一个来存放雷的信息一个展示给用户,这里我们不将其固定死,以便未来可以修改和设置难度

#define ROW 9
#define COL 9

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

这样的定义为我们接下来计算周围雷的数量提供了方便

2.初始化棋盘
 
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;
		}
	}
}

这里将我们把要棋盘初始化为什么元素,将这个元素传过来,这样提高了代码的可适用性,初始化两个棋盘都可以用这个函数

3.打印出我们要给用户展示的棋盘
void Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	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");
	}
}
4.设置雷

这里我们要让雷随机生成在棋盘中,我们可以用一个rand函数

srand((unsigned int)time(NULL))生成随机数,

void SETMINE(char mine[ROWS][COLS], int row, int col)
{
	int count = NUM;

	while (count)
	{
		
		int x = rand() %row + 1;
		int y = rand() %col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
	
}
5排雷过程

当雷没有排尽时我们写一个循环,再不踩雷的情况下可以继续排雷

如果踩到雷那么游戏结束

如果没有踩到雷,那么我们计算周围雷的数量

这里是一个难点,我们都玩过扫雷游戏如果周围没有雷的话这里会展开一片,直到遇到周围有雷的情况

接下来我们将详细介绍如何实现这一步骤

void FINDMINE(char mine[ROWS][COLS], char show[ROWS][COLS], int row,int col)
{
	int x = 0;
	int y = 0;
	int WIN = 0;
	int ret = 0;
	while (WIN= 1 && x <= 9 && y >= 1, y <= 9 && show[x][y]=='*')//防止输入过的坐标重复输入
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被雷炸死了n");
				Display(mine, ROW, COL);
				break;
			}
			else//计算周围坐标的和
			{
				if (mine[x][y] == '0' && show[x][y] == '*')
				{
					NoMine(mine, show, x, y);
					Display(show, ROW, COL);
					WIN = WIN+8;//
				}

			}
		}
		
		else
			printf("输入的坐标有误,请重新输入n");
	}
	
	if (WIN >= ROW * COL - NUM)
	{
		printf("恭喜你取得胜利n");
		Display(mine, ROW, COL);
	}
}
//计算雷的数量
int  get_round(char mine[ROWS][COLS],int x,int y)//注意我们这里函数的类型返回的是整形,表示雷的个数
{
	int i = 0;
	int j = 0;
	int sum = 0;
	for (i=-1;i<=1;i++)
	{
		for (j = -1; j <= 1; j++)
		{
			sum += mine[x + i][y + j];//将周围一圈的ascall码值加起来
		}
	}

	return (sum - 9 * '0');
//九个格子的ascall码值加起来减去每个格子初始化'0'的ascall码值来确定有几个雷

}
使用一个递归函数来达到展开一片的效果

将他的范围限制在棋盘内,不造成越界访问
//show[x+i][y+j]=='*'使得跳过show[x][y]为0这个位置,不造成死递归
 

//展开一片区域,用递归来实现
void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int ret = get_round(mine, x, y);

	if (ret == 0)
	{
		show[x][y] = ' ';
		int i = 0;
		int j = 0;
		for (i = -1; i <= 1; i++)
		{
			for (j = -1; j <= 1; j++)
			{
				if ((x + i) > 0 && (y + i) > 0 && (x + i  
总体代码  

game.h

#pragma once
#include 
#include 
#include 
#pragma warning (disable :4996)

#define ROW 9
#define COL 9

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

#define NUM 10

//初始化棋盘函数
void InitBoard(char board[ROWS][COLS], int, int, char);

//打印棋盘函数
void Display(char board[ROWS][COLS], int,int);

//埋雷
void SETMINE(char board[ROWS][COLS], int row, int col);

//排	雷
void FINDMINE(char[ROWS][COLS], char[ROWS][COLS], int, int);

//计算周围的雷数
int get_round(char[ROWS][COLS], int, int);

//展开一片
void NoMine(char mine[ROWS][COLS],char show [ROWS][COLS],int x, int y);
test.c
#include"game.h"
menu()//打印一个开始菜单
{
	printf("*******扫雷游戏*******n");
	printf("*********************n");
	printf("***0.exit    1.exe***n");
	printf("*********************n");

}

void game()
{
	//设置棋盘
	char mine[ROWS][COLS] = { 0 };//用来存放雷的棋盘
	char show[ROWS][COLS] = { 0 };//展示给用户的棋盘
	
	//初始化棋盘
	InitBoard(mine, ROWS, COLS,'0');
	InitBoard(show, ROWS, COLS,'*');
	
	//打印棋盘
	 Display(show, ROW, COL);
	//Display(mine, ROW, COL);
	
	//埋雷在mine数组中
	SETMINE(mine, ROW, COL);
	//Display(mine, ROW, COL);
	//排雷
	FINDMINE(mine, show, ROW, COL);

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


	return 0;
}
game.h 
#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 Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	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");
	}
}


void SETMINE(char mine[ROWS][COLS], int row, int col)
{
	int count = NUM;

	while (count)
	{
		
		int x = rand() %row + 1;
		int y = rand() %col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
	
}


//计算雷的数量
int  get_round(char mine[ROWS][COLS],int x,int y)
{
	int i = 0;
	int j = 0;
	int sum = 0;
	for (i=-1;i<=1;i++)
	{
		for (j = -1; j <= 1; j++)
		{
			sum += mine[x + i][y + j];
		}
	}

	return (sum - 9 * '0');

}

//展开一片区域,用递归来实现
void NoMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int ret = get_round(mine, x, y);

	if (ret == 0)
	{
		show[x][y] = ' ';
		int i = 0;
		int j = 0;
		for (i = -1; i <= 1; i++)
		{
			for (j = -1; j <= 1; j++)
			{
				if ((x + i) > 0 && (y + i) > 0 && (x + i = 1 && x <= 9 && y >= 1, y <= 9 && show[x][y]=='*')
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被雷炸死了n");
				Display(mine, ROW, COL);
				break;
			}
			else//计算周围坐标的和
			{
				if (mine[x][y] == '0' && show[x][y] == '*')
				{
					NoMine(mine, show, x, y);
					Display(show, ROW, COL);
					WIN = WIN+8;
				}

				//不展开
				//ret = get_round(mine, x, y);
				//show[x][y] = ret + '0';
				//Display(show, ROW, COL);				
				//WIN++;
			}
		}
		
		else
			printf("输入的坐标有误,请重新输入n");
	}
	
	if (WIN >= ROW * COL - NUM)
	{
		printf("恭喜你取得胜利n");
		Display(mine, ROW, COL);
	}
}

以上就是所有内容了!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/861632.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号