简易扫雷(仅用函数和数组实现)

一、游戏介绍

扫雷是一款比较传统的游戏,游戏规则是,选择一个格子,如果不是雷,则安全,继续寻找其他雷,如果是雷,游戏结束。当找到全部的雷时,游戏则通过。

在这里插入图片描述
如上,游戏失败,点击的格子中的数字代表周围的格子一共有那么多个雷。
在这里插入图片描述
中间的2代表周围有2个雷
在这里插入图片描述
中间的1代表周围有1个雷,根据最中间的1,得到还未点击的格子就一定是雷。

这里仅用函数和数组外加一些细小知识,带大家实现一个简易的扫雷,使大家学到的知识得到运用。

二、代码实现

1、菜单

一个朴实无华的打印的菜单

void Menu()
{
	printf("-------------------\n");
	printf("-------1.paly------\n");
	printf("-------0.exit------\n");
	printf("-------------------\n");
}

可以根据自己的喜好进行合适的修改。

2、封装一些函数

(1)、初始化棋盘

棋盘的每一个格子可以看成一个二维数组的元素,那么实现一个9*9的棋盘,只需要一个9*9的二维数组。

初始化棋盘的代码如下

void InitBoard(char ch[ROWS][COLS], int rows, int cols, char c)
//ch为需要初始化的数组,rows为行数,cols为列数,c为初始化的内容
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			ch[i][j] = c;
		}
	}
}

(2)、打印棋盘

初始化之后,需要将棋盘显示在屏幕,这就需要一个打印的函数,由于这里是输入坐标来判断需要排查的位置,则需要额外打印行号和列号,方便玩家进行输入。

void DisplayBoard(char ch[ROWS][COLS], int row, int col)
{
	printf("--------扫雷-------\n");
	for (int i = 0; i <= row; i++)
	{
		printf("%d ", i);         //打印列号
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);         //打印行号
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", ch[i][j]);
		}
		printf("\n");
	}
}

打印结果如图
在这里插入图片描述

(3)、布置雷

字符1代表雷,字符0代表安全,为了解决数字1是代表雷还是代表周围有一个雷的冲突问题,采用创建两个数组来解决这个问题。

数组mine和数组show。mine数组是存放雷的数组,show是打印在屏幕的数组。
这里布置十个雷,#define一个常量,方便做修改。

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int mineNums = MINENUMS;   //雷的数量

	while (mineNums)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';    //'1'代表雷
			mineNums--;
		}
	}
}

使用随机数生成坐标,来布置雷,当该位置不是雷的时候,就设置一个雷。

(4)、获得周围雷的数量

当玩家输入一个坐标后,需要判断该位置是不是雷,如果是,游戏结束,如果不是,需要获得该位置周围的雷的数量。

int GetMineNum(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y]
		+ mine[x - 1][y + 1] + mine[x][y - 1]
		+ mine[x][y + 1] + mine[x + 1][y - 1]
		+ mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0');
}

获得周围雷的数量,就是统计周围字符1的个数。

(5)、寻找雷

当玩家输入一个坐标,需要给出该位置的信息,0代表周围没有雷,其他数字代表周围有对应的雷。

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0, y = 0, win = 0;
	while (win<row*col-MINENUMS)
	{
		printf("请输入你要找的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1') //如果是雷,游戏结束
			{
				system("cls");
				printf("Game over!\n");
				printf("雷图如下,1代表雷\n\n");
				DisplayBoard(mine, ROW, COL); //游戏结束,打印雷的位置,‘1’代表雷
				printf("\n");
				break;
			}
			else
			{
				//不是雷的话,win++
				win++;
				int mineNum = GetMineNum(mine, x, y);//获得该坐标周围的雷的数量
				show[x][y] = mineNum + '0';          //赋值给打印出来的数组
				system("cls");                       //清屏
				DisplayBoard(show, ROW, COL);        
			}
		}
		else
		{
			printf("坐标非法,请重新输入!\n");
		}
		
	}
	if (win == row * col - MINENUMS)
	{
		printf("游戏胜利,排雷成功!");
		DisplayBoard(mine, ROW, COL);
	}
}

这里需要传两个数组进行比对,在打印show数组。

3、主函数

int main()
{
	srand((unsigned int)time(NULL));//设置随机数的种子
	int input = 0;
	do
	{
		Menu();
		printf("请输入您的选项:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			system("cls");
			Game();
			break;
		case 0:printf("退出游戏!\n");
			break;
		default:printf("请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

Game()函数代码如下

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);
	//设置雷
	SetMine(mine, ROW, COL);
	//寻找雷
	FindMine(mine, show, ROW, COL);
}

其他的一些常量以及头文件等

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


#define ROW 9    //行号
#define COL 9    //列号

#define ROWS ROW+2
#define COLS COL+2
#define MINENUMS 10   //雷的数量

4、其他问题的解决

第一行和最后一行,第一列和最后一列,周围是没有8个格子的,为了解决这个问题,创建数组和初始化数组的时候,多了两行和两列,但是打印时,只打印中间的9*9的内容。

为了使画面清晰,每一次输入坐标和判断后,都会清屏并打印show数组。如果该坐标是雷,游戏结束,结束后,打印mine数组,显示全部的雷的位置。

三、完整代码

#define _CRT_SECURE_NO_WARNINGS 1

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


#define ROW 9
#define COL 9

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

void Menu();

void Game();

//初始化棋盘
void InitBoard(char ch[ROWS][COLS], int rows, int cols, char c);
//打印棋盘
void DisplayBoard(char ch[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);
//获取周围雷的数量
int GetMineNum(char mine[ROWS][COLS], int row, int col);
//寻找雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//菜单
void Menu()
{
	printf("-------------------\n");
	printf("-------1.paly------\n");
	printf("-------0.exit------\n");
	printf("-------------------\n");
}

void InitBoard(char ch[ROWS][COLS], int rows, int cols, char c)
//ch为需要初始化的数组,rows为行数,cols为列数,c为初始化的内容
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			ch[i][j] = c;
		}
	}
}

void DisplayBoard(char ch[ROWS][COLS], int row, int col)
{
	printf("--------扫雷-------\n");
	for (int i = 0; i <= row; i++)
	{
		printf("%d ", i);         //打印列号
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);         //打印行号
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", ch[i][j]);
		}
		printf("\n");
	}
}

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int mineNums = MINENUMS;   //雷的数量

	while (mineNums)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';    //'1'代表雷
			mineNums--;
		}
	}
}

int GetMineNum(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y]
		+ mine[x - 1][y + 1] + mine[x][y - 1]
		+ mine[x][y + 1] + mine[x + 1][y - 1]
		+ mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0');
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0, y = 0, win = 0;
	while (win < row * col - MINENUMS)
	{
		printf("请输入你要找的坐标:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1') //如果是雷,游戏结束
			{
				system("cls");
				printf("Game over!\n");
				printf("雷图如下,1代表雷\n\n");
				DisplayBoard(mine, ROW, COL); //游戏结束,打印雷的位置,‘1’代表雷
				printf("\n");
				break;
			}
			else
			{
				//不是雷的话,win++
				win++;
				int mineNum = GetMineNum(mine, x, y);//获得该坐标周围的雷的数量
				show[x][y] = mineNum + '0';          //赋值给打印出来的数组
				system("cls");                       //清屏
				DisplayBoard(show, ROW, COL);
			}
		}
		else
		{
			printf("坐标非法,请重新输入!\n");
		}

	}
	if (win == row * col - MINENUMS)
	{
		printf("游戏胜利,排雷成功!");
		DisplayBoard(mine, ROW, COL);
	}
}

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);
	//设置雷
	SetMine(mine, ROW, COL);
	//寻找雷
	FindMine(mine, show, ROW, COL);
}

int main()
{
	srand((unsigned int)time(NULL));//设置随机数的种子
	int input = 0;
	do
	{
		Menu();
		printf("请输入您的选项:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			system("cls");
			Game();
			break;
		case 0:printf("退出游戏!\n");
			break;
		default:printf("请重新输入!\n");
			break;
		}
	} while (input);
	return 0;
}

仅仅使用了数组和函数就可以实现一个简易的扫雷游戏,当学会更多的知识,就可以实现更多更好的游戏了。

如果有什么不明白的,欢迎大家提问,如果有不足或者错误,也欢迎大家指出,一起进步!再见咯!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值