C语言 扫雷游戏(命令行界面模式)C语言实现

一.游戏介绍

相信大家都玩过扫雷这个小游戏,扫雷是一款益智类娱乐游戏,既可以放松心情也可以锻炼自己。

游戏规则:玩家需要在不踩雷的情况下,找出所有的雷才算胜利,若踩雷了,则游戏失败并结束。

二.实现功能的步骤及介绍

1.初始化棋盘

2.打印棋盘

3.布置雷功能的实现

4.防止玩家第一次被炸死

5.计算所选位置周围的八个位置中雷的个数

6展开一片功能的实现(递归拓展所选位置周围的区域)

7.标记功能的实现(标记-取消标记)

8.排雷功能的实现

(一)游戏的步骤

1.玩家可以选择1.paly开始游戏选择0.exit退出游戏

 2.当玩家开始游戏后当在排雷的时候选择1.非雷区域可以直接进入游戏排雷,

选择2.标记雷的位置可以先标记可疑为雷的位置再进入游戏进行排雷,选择

3.取消雷的标记在进行一局游戏后,如果想取消可疑位置选3即可。

3.当所有的雷被玩家排完,则游戏胜利

 (二)实现功能

1.初始化棋盘

初始化棋盘需要用到两个二维数,一个数组(mine数组)用来存放布置雷的信息,一个数组(show数组)用来存放排查雷的信息,show数组是玩家玩的时候看不到雷的位置

mine数组会比show数组多两行两列,因为在排雷过程中所选位置会统计周围八个位置中雷的个数,为了更加简单的实现功能所以mine数组比show数组多两行两列

//初始化棋盘
/*
mine数组未布置雷之前存放0
show数组为排查雷之前存放*
*/
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;//用来存放0/*
		}
	}

}

2.打印棋盘

在玩家排雷的过程打印出棋盘便于玩家游戏体验

//棋盘功能的实现
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");
}

3.布置雷功能的实现

//设置雷功能的实现
//mine数组用来设置雷 0表示未设置雷区域,1表示雷
//row 行数
//col 列数
//随机布置雷需要使用srand和rand函数
void SetMine(char board[ROWS][COLS], int row, int col)
{
	//设置雷的个数
	int count = EASY_COUNT;
	while (count)
	{
		//设置雷的起点
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';//把雷设置成1
			count--;
		}
	} 
}

4.防止玩家第一次被炸死(玩家排雷 中需要此实现功能

如果玩家第一次玩就踩到雷就重新选择

//防止玩家第一次被雷炸死
void FirstPlace(char mine[ROWS][COLS], int x, int y,int row,int col)
{
	x = rand() % row;
	y = rand() % col;
	mine[x][y] = '1';
	printf("第一次就踩雷,重新选择\n");
}

5.计算所选位置周围雷的个数(玩家排雷 中需要此实现功能

//计算坐标点周围雷的个数
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x][y - 1] +
		board[x + 1][y + 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] +
		board[x][y + 1] +
		board[x - 1][y + 1] - 8 * '0';
}

6.展开一片功能的实现(玩家排雷 中需要此实现功能)

以递归的方式拓展排雷

//拓展周围不是雷的区域
void NopeBorad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)
		return;
	if (show[x][y] != '*')
	{
		return;
	}
	int count = get_mine_count(mine, x, y);
	if (count > 0)
	{
		//将周围雷的数字显示出来,把字符转换成数字形式
		show[x][y] = count + '0';
		return;
	}
	else if (count == 0)
	{
		show[x][y] = '0';
		NopeBorad(mine, show, x - 1, y);
		NopeBorad(mine, show, x - 1, y - 1);
		NopeBorad(mine, show, x, y - 1);
		NopeBorad(mine, show, x + 1,y + 1);
		NopeBorad(mine, show, x + 1, y);
		NopeBorad(mine, show, x + 1, y + 1);
		NopeBorad(mine, show, x, y + 1);
		NopeBorad(mine, show, x - 1, y + 1);

	}
}

7.标记功能的实现(标记-取消标记)(玩家排雷 中需要此实现功能)

//标记
int Flagmine(char show[ROWS][COLS], int row, int col, size_t flag)
{
	int x = 0;
	int y = 0;
	if (flag == EASY_COUNT)
	{
		printf("标记的雷数和实际雷数相等,无法再标记\n");
		return;
	}
	printf("请输入你要标记的位置坐标:>\n");
	scanf("%d%d", &x, &y);
	if (x >= 1 && x <= row&&y >= 1 && y <= col)
	{
		//判断该位置坐标是否已经确认不为雷
		if (show[x][y] == '*')
		{
			show[x][y] = '?';
			flag++;
		}
		else
		{
			printf("该位置不是雷,请重新输入\n");
		}
	}
	else
	{
		printf("该坐标不合法请重新输入:>\n");
	}
	return flag;
}
//取消标记功能
int Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count)
{
	int x = 0; 
	int y = 0;
	scanf("%d%d", &x, &y);
	//判断坐标是否合法
	if (x >= 1 && x <= row&&y >= 1 && y <= col)
	{
		//判断该位置是否被标记过
		if (show[x][y] == '?')
		{
			show[x][y] = '*';
			flag_count--;
		}
		else
		{
			printf("该位置未被标记过,无需取消标记\n");
		}
	}
	else
	{
		printf("该坐标不合法,请重新输入\n");
	}
	return flag_count;
}

 标记的位置选择的是9 1;

8.玩家排雷功能的实现


//标记的菜单功能
void menu1()
{
	printf("***********************\n");
	printf("***** 1.选择非雷区域***\n");
	printf("***** 2.标记雷的位置***\n");
	printf("***** 3.取消雷的标记***\n");
	printf("***********************\n");
}

//玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	size_t flag_count = 0;
	int ch = 0;
	int x = 0;
	int y = 0;
	int win = 0;
	int first = 1;//标记玩家是否为第一次排雷
	while (win < row*col - EASY_COUNT)
	{
		menu1();
		scanf("%d", &ch);
		if (ch == 1)
		{
			//输入要排查的坐标
			printf("请输入要排查的坐标:>");
			scanf("%d%d", &x, &y);
			if (show[x][y] != '*')
			{
				printf("该坐标已排查过,请重新输入新坐标\n");
			}
			else
			{
				//判断坐标的合法性
				if (x >= 1 && x <= row&&y >= 1 && y <= col)
				{
					//判断玩家是否为第一次排雷
					if (first == 1 && mine[x][y] == '1')
					{
						FirstPlace(mine, row, col, x, y);
						first++;
					}
					else
					{
						//如果不是第一次排雷并且有雷
						if (mine[x][y] == '1')
						{
							printf("很遗憾,你踩到雷了,游戏结束\n");
							DisplayBoard(mine, row, col);
							break;
						}
						else
						{
							//如果无雷
							win++;
							判断周围有几个雷
							//int count = get_mine_count(mine, x, y);
							将字符数转换周围雷的数字
							//show[x][y] = count + '0';
							显示排查雷的信息
							NopeBorad(mine, show, x, y);
							DisplayBoard(show, ROW, COL);
						}
						first++;
					}
				}
				else
				{
					printf("坐标不合法,请重新输入\n");
				}
			}
		}
		else if (ch == 2)
		{
			printf("请开始标记雷:>\n");
			flag_count = Flagmine(show, row, col, flag_count);
			DisplayBoard(show, row, col);
		}
		else if (ch == 3)
		{
			printf("请选择要取消标记的位置:>\n");
			flag_count = Cancelflag(show, row, col, flag_count);
			DisplayBoard(show, row, col);
		}
	}
	if (win == row*col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

所有函数的调用和声明均已在主函数中给出

#define _CRT_SECURE_NO_WARNINGS 

#include "game.h"

//游戏菜单
void menu()
{
	printf("*******************\n");
	printf("******* 1.play ****\n");
	printf("******* 0.exit ****\n");
	printf("*******************\n");
}
//游戏实现的功能
void game()
{
	//创建两个数组 mine用来存放布置雷的信息,show用来存放排查雷的信息
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	
	//设置雷
	SetMine(mine, ROW, COL);
	//设置雷的起点
	srand((unsigned int)time(NULL));
	DisplayBoard(mine, ROW, COL);

	//排查雷
	FindMine(mine, show, ROW, COL);

}
void test()
{
	int input = 0;

	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);
}
int main(void)
{
	test();
	return 0;
}

函数声明

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

#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 board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值