资讯专栏INFORMATION COLUMN

【C语言实现游戏】(二)扫雷(递归实现排雷)

U2FsdGVkX1x / 3293人阅读

摘要:玩家选择开始游戏后,出现雷盘,并且随机布置雷。雷盘的数组大小为,方便计算扫雷时周围雷的数量,并防止数组越界。放置布置的雷的信息放置排查出雷的信息初始化雷盘初始化展示界面打印展示界面效果如下布置雷随机在数组中让十个变成作为雷。

目录

前言

一、游戏思路

二、游戏框架

1.菜单界面

1.菜单:

2.菜单的选择:

3.实际效果:

2.游戏主体

1.初始化雷盘及展示界面

2.布置雷

 3.排雷

3.游戏函数

三、游戏运行

四、所有代码

1.game.h

2.game.c

3.test.c

总结




前言

扫雷,相信各位都不陌生,以前每台电脑上面都会自带这个小游戏。因此,它可以说是我们的童年回忆了,今天来用C语言实现简单的扫雷小游戏。




一、游戏思路

1、程序开始时出现菜单,让玩家选择开始游戏或者退出游戏。

2、玩家选择开始游戏后,出现雷盘,并且随机布置雷。

3、玩家进行排雷



二、游戏框架



1.菜单界面

1.菜单:

void menu(){	printf("**************************/n");	printf("*****按 1 开 始 游 戏*****/n");	printf("*****按 0 退 出 游 戏*****/n");	printf("**************************/n");}

2.菜单的选择

int main(){	int input = 0;		do	{		menu();		printf("做出你的选择:");		scanf("%d", &input);		switch (input)		{		case 1:			game();			break;		case 0:			printf("退出游戏~)/n");			break;		default:			printf("请重新选择/n");			break;		}	} while (input);	return 0;}

3.实际效果:



2.游戏主体

1.初始化雷盘及展示界面

建立两个二维数组作为雷盘,一个用于初始化雷盘,即埋雷;另一个雷盘用于作展示界面,显示玩家的排雷过程。雷盘的数组大小为11*11,方便计算扫雷时周围雷的数量,并防止数组越界。展示界面的数组大小9*9即可。

void game(){	char mine[ROWS][COLS] = { 0 }; //放置布置的雷的信息	char show[ROWS][COLS] = { 0 }; //放置排查出雷的信息	InitBoard(mine, ROWS, COLS, "0"); //初始化雷盘	InitBoard(show, ROWS, COLS, "*"); //初始化展示界面	DisplayBoard(show, ROW, COL); //打印展示界面}

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;	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");	}}

效果如下

2.布置雷

随机在mine数组中让十个‘0’变成‘1’作为雷。

void SetMine(char mine[ROWS][COLS], int row, int col){	int count = 10;    		while (count)	{				int x = rand() % row + 1;   				int y = rand() % col + 1;			if (mine[x][y] == "0")			{				mine[x][y] = "1";					count--;			}	}}

 打印下展示界面和雷盘看下效果,可以看到刚好出现了十个1,且每次新游戏的位置都是不一样的。

                

 3.排雷

 玩家输入要排查的坐标,如果是雷,游戏结束;如果不是雷,显示周围一圈雷的数量,如果周围一圈没有雷,则自动继续向外排查(通过简单的递归实现)。当所有雷都被排查出时,游戏胜利。

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");				DisplayBoard(mine, row, col);				break;			}			else			{				int n = get_mine_count(mine, x, y);				show[x][y] = n + "0";								system("cls"); //美观				DisplayBoard(show, row, col);				win++;			}		}		else		{			printf("往哪排雷呢你,重新来/n");		}	}	if (win == row * col - EASY_COUNT)	{		printf("不错哦,赢了");		DisplayBoard(mine, row, col);	}	}
static int get_mine_count(char mine[ROWS][COLS], int x,int y){	return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x - 1][y + 1] +		mine[x][y - 1] + mine[x][y + 1] + 		mine[x + 1][y] + mine[x + 1][y - 1] + mine[x + 1][y + 1] - 8 * "0";}

但是这样子出来的扫雷无法自动向外排查,于是我选择用递归来实现,当然胜利的条件也会随着发生变化,变成了统计未排查数量是否与雷数量相等。

于是我将判断胜负的代码换成了如下代码。

int i = 0;int j = 0;int mines = 0;		for (i = 1; i <= ROW; i++)		{						for (j = 1; j <= COL; j++)			{				if (show[i][j] == "*")					mines++;			}		}		if (EASY_COUNT == mines)		{			printf("不错哦,你赢了!/n");			break;		}

然后用递归实现自动排查

void count(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y){	int i = 0;	int j = 0;	if (get_mine_count(mine, x, y) == 0)	{		show[x][y] = " ";		for (i = x - 1; i <= x + 1; i++)		{						for (j = y - 1; j <= y + 1; j++)			{				if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != "1" && show[i][j] == "*")				{					count(show, mine, i, j);				}			}		}	}	else		show[x][y] = "0" + get_mine_count(mine, x, y);}

3.游戏函数

当然还需要游戏函数将上述结合起来

void game(){	char mine[ROWS][COLS] = { 0 }; //放置布置的雷的信息	char show[ROWS][COLS] = { 0 }; //放置排查出雷的信息	InitBoard(mine, ROWS, COLS, "0"); //初始化雷盘	InitBoard(show, ROWS, COLS, "*"); //初始化展示界面	SetMine(mine, ROW, COL);	DisplayBoard(show, ROW, COL); //打印展示界面	/*DisplayBoard(mine, ROW, COL);*/	FindMine(mine, show,ROW, COL);}

三、游戏运行

 来看看实际效果由于清屏的存在,界面也算是整洁美观。

  

四、所有代码

按照惯例,贴出所有代码

1.game.h

#pragma once#include #include #include #include #define ROW 9 #define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 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 mine[ROWS][COLS], int row, int col);//排雷void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

2.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 mine[ROWS][COLS], int row, int col){	int count = EASY_COUNT;	while (count)	{				int x = rand() % row + 1;   				int y = rand() % col + 1;			if (mine[x][y] == "0")			{				mine[x][y] = "1";					count--;			}	}}static int get_mine_count(char mine[ROWS][COLS], int x,int y){	return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x - 1][y + 1] +		mine[x][y - 1] + mine[x][y + 1] + 		mine[x + 1][y] + mine[x + 1][y - 1] + mine[x + 1][y + 1] - 8 * "0";}void count(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y){	int i = 0;	int j = 0;	if (get_mine_count(mine, x, y) == 0)	{		show[x][y] = " ";		for (i = x - 1; i <= x + 1; i++)		{						for (j = y - 1; j <= y + 1; j++)			{				if (i > 0 && i <= ROW && j > 0 && j <= COL && mine[i][j] != "1" && show[i][j] == "*")				{					count(show, mine, i, j);				}			}		}	}	else		show[x][y] = "0" + get_mine_count(mine, x, y);}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){	int x = 0;	int y = 0;	int i = 0;    int j = 0;	while (1)	{		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 n = get_mine_count(mine, x, y);				show[x][y] = n + "0";				count(show, mine, x, y);				system("cls");				DisplayBoard(show, row, col);			}		}		else		{			printf("往哪排雷呢你,重新来/n");		}		int mines = 0;		for (i = 1; i <= ROW; i++)		{			for (j = 1; j <= COL; j++)			{				if (show[i][j] == "*")					mines++;			}		}		if (EASY_COUNT == mines)		{			printf("不错哦,你赢了!/n");			break;		}	}}

3.test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu(){	printf("**************************/n");	printf("*****按 1 开 始 游 戏*****/n");	printf("*****按 0 退 出 游 戏*****/n");	printf("**************************/n");}void game(){	char mine[ROWS][COLS] = { 0 }; //放置布置的雷的信息	char show[ROWS][COLS] = { 0 }; //放置排查出雷的信息	InitBoard(mine, ROWS, COLS, "0"); //初始化雷盘	InitBoard(show, ROWS, COLS, "*"); //初始化展示界面	SetMine(mine, ROW, COL);	DisplayBoard(show, 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:			game();			break;		case 0:			printf("退出游戏~)/n");			break;		default:			printf("请重新选择/n");			break;		}	} while (input);	return 0;}



总结

好累,去睡觉了。

当然这个游戏可以在头文件中改变数值达到不同的雷盘大小,以及不同的雷数量,达成不同难度的扫雷游戏,当然我也可以直接将这个做成简单模式、困难模式之类的,但是我懒!

欢迎大家一起交流心得!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123188.html

相关文章

  • C语言实现扫雷游戏】拓展版

    摘要:作者时间网站地址摘要语言实现我们小时候玩过的扫雷游戏,最近看到了一些扫雷游戏的简单实现,但是总有功能上的缺失,玩起来不那么的原汁原味,因此我增加了一些新功能确保玩家首次排雷一定不会炸死。 ...

    JayChen 评论0 收藏0
  • 扫雷1.0(递归实现

    摘要:头文件部分进行符号常量的声明,宏定义等源文件和用时需要引用。包括布置雷区,埋雷,扫雷,判断输赢等。游戏规则扫雷就是要把所有非地雷的格子揭开即胜利踩到地雷格子就算失败。一次就可以完成两次函数调用的实现。这是因为防止在扫雷的时候数组越界。 ...

    CoderDock 评论0 收藏0
  • 扫雷连爆(望大佬也可以帮忙优化或提出意见)(C语言版)------上

    摘要:新人小白的第一篇博客,有什么不好之处望多提意见。这个扫雷小游戏主要是基于二维数组,循环与基本的函数知识等。请输入坐标提示玩家输入坐标。换行是为了看着好看,要不然打印出来的数组会变形的。用来接收判断输赢的函数的返回值。 ​​​​​​​新人小白的第一篇博客,有什么不好之处望多提意见。      ...

    incredible 评论0 收藏0
  • c语言实现扫雷(简易版)

    摘要:每成功排一次雷,我们都要展示雷盘当场上剩下的格子数等于雷数时,游戏胜利,玩家踩雷时,游戏结束,所以我们这是一个判断输赢的函数。 前言:写完三子棋后,慢慢地熟悉了这种...

    walterrwu 评论0 收藏0
  • C语言实现初级扫雷

    摘要:文章目录一游戏简介二代码实现调用函数打印菜单函数函数初始化函数布置雷函数排雷函数三总代码一游戏简介一款小游戏,一张棋盘可以自己设计,,,都可以,或是添加一些自己喜欢的元素布满许多未知是雷或是安全的格子,输入坐标,若触雷,游戏结束,反之,显 文章目录 一、游戏简介 二、代码实现 1.调用tes...

    Rango 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<