扫雷(超详解+全部码源)

目录

一.游戏及规则介绍

前提准备

         1要了解的知识
         2包含的头文件和函数
         3主函数和初始化界面

三.游戏核心函数实现

               1初始化棋盘init()
                 2.打印棋盘print()
                 3随机设置雷Set()
                4排查雷 find()

四.游戏运行实操
总结及源代码

这是博主用写的第二个游戏,对于我来说有点困难,好在克服了,哈哈。希望大家六个赞再走吧

一.游戏及规则介绍

使⽤控制台实现经典的扫雷游戏
• 游戏可以通过菜单实现继续玩或者退出游戏
• 扫雷的棋盘是9*9的格⼦
• 默认随机布置10个雷可以排查雷
◦ 如果位置不是雷,就显⽰周围有⼏个雷
◦ 如果位置是雷,就炸死游戏结束
◦ 把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束

二前提准备

1要了解的知识

srand函数的应用关于如何用rand(),srand()和time()函数创建简单的随机数

2包含的头文件和函数

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define NUM 10;
void init(char board[ROWS][COLS], int rows, int cols, char set);
void print(char board[ROWS][COLS], int row, int col);
void Set(char board[ROWS][COLS], int row, int col);
void find(char S[ROWS][COLS], char M[ROWS][COLS], int row, int cols);

3 主函数和初始化界面

通过while循环和打印menu()函数来实现游戏的持续进行和初始选择界面

void menu() {

	printf("***********\n");
	printf("****选择游戏****\n");
	printf("****1:进行游戏****\n");
	printf("****0:退出游戏****\n");


}
int main()

{
	srand((unsigned)time(NULL));
	int input = 0;

	do
	{
		menu();
		scanf("%d", &input);

		switch (input)
		{
		case 1: {game();
			break;

		}
		case 0:break;
		default:printf("重新选择\n");
			break;
		}

	} while (input);

	return 0;

}

三.游戏核心函数实现

因为要打印出结果和判断此位置是否是雷两个功能。所以我们创建char S[ROWS][COLS]char M[ROWS][COL]实现两个功能

请添加图片描述

请添加图片描述

void game() {
	char S[ROWS][COLS];
	char M[ROWS][COLS];
	init(S, ROWS, COLS, '*');//初始化棋盘
	init(M, ROWS, COLS, '0');
	print(S, ROW, COL);//打印棋盘
	Set(M, ROW, COL);//随机设置雷
	find(S, M, ROWS, COLS);//排查雷
	}

1初始化棋盘init()

因为为了防⽌越界,我们在设计的时候,给数组扩⼤⼀圈,雷还是布置在中间的9*9的坐
标上,周围⼀圈不去布置雷就⾏,这样就解决了越界的问题。所以我们将存放数据的数组创建成11 * 11
是⽐较合适。

请添加图片描述

M数组里放置*M数组里放置‘0’

void init(char board[11][11], int rows, int cols, char set)
{
	for (int i = 0; i < rows; i++) {

		for (int j = 0; j < cols; j++) {

			board[i][j] = set;

		}

	}

}

2.打印棋盘print()

实现打印的函数每次结果显示都要用到这个函数

void print(char board[ROWS][COLS], int row, int col)
{
	for (int m = 0; m <= row; m++) {


		printf("%d ", m);
	

	}
	printf("\n");
	for (int i = 1; i <= row; i++) {
		printf("%d ", i);
		
		for (int j = 1; j <= col; j++)
		{

			printf("%c ", board[i][j]);



		}

		printf("\n");


	}
}

3随机设置雷Set()

用随机数来在9*9的M棋盘上布置10个雷

请添加图片描述

void Set(char board[ROWS][COLS], int row, int col)

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

4排查雷 find()

在这个环节我们要写一个循环排除掉十个雷就循环结束,被炸死也提前结束。

我们要再写一个int get()函数来统计所选位置周围8个方位的雷的个数返回值是int
如果有雷‘1’-‘0’=1所以八个位置雷个数就是M[x - 1][y] + M[x + 1][y] + M[x - 1][y + 1] + M[x + 1][y + 1] + M[x - 1][y - 1] +
M[x + 1][y - 1] +M[x][y-1]+M[x][y+1] - 8 * ‘0’;

因为每次都要调用print函数所以统计出的数要加上‘0’变成%c的形式。如5变成‘5’

int get(char M[ROWS][COLS], int x, int y) {

 return M[x - 1][y] + M[x + 1][y] + M[x - 1][y + 1] + M[x + 1][y + 1] + M[x - 1][y - 1] +
 	M[x + 1][y - 1] +M[x][y-1]+M[x][y+1] - 8 * '0';


}
void find(char S[ROWS][COLS], char M[ROWS][COLS], int row, int col) {
 int x, y = 0;
 int m = 0;

 
 while (m < row * col - 10) {
     printf("请输入坐标");
 	scanf("%d %d", &x, &y);
 	if (x > 0 && x <= row && y > 0 && y <= col)
 	{
 		if (M[x][y] == '1') {
 			printf("你被炸死了\n");
 				print(M, ROW, COL);
 				break;
 		}
 		else
 		{
 			int count = get(M, x, y);
 			S[x][y] = '0' + count;
 			print(S, ROW, COL);
 			m++;
 		}



 	}
 	else
 	{
 		printf("输入错误,重新输入\n");

 	}

 }

}


四.游戏运行实操

请添加图片描述

请添加图片描述
五总结及源代码

我们这次写的游戏要用两个棋盘实现,用到了分布的思想。把复杂的问题拆分成简单的问题

game.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define NUM 10;
void init(char board[ROWS][COLS], int rows, int cols, char set);
void print(char board[ROWS][COLS], int row, int col);
void Set(char board[ROWS][COLS], int row, int col);
void find(char S[ROWS][COLS], char M[ROWS][COLS], int row, int cols);

game.c

#include"game.h"
void init(char board[11][11], int rows, int cols, char set)
{
	for (int i = 0; i < rows; i++) {

		for (int j = 0; j < cols; j++) {

			board[i][j] = set;

		}

	}

}
void print(char board[ROWS][COLS], int row, int col)
{
	for (int m = 0; m <= row; m++) {


		printf("%d ", m);
	

	}
	printf("\n");
	for (int i = 1; i <= row; i++) {
		printf("%d ", i);
		
		for (int j = 1; j <= col; j++)
		{

			printf("%c ", board[i][j]);



		}

		printf("\n");


	}
}
	void Set(char board[ROWS][COLS], int row, int col)
	
		
	{    int count = NUM;
		while (count)
		{
			int x = rand() % row + 1;
			int y = rand() % col + 1;
			if (board[x][y] == '0')
			{
				board[x][y] = '1';
				count--;
			}
		}
	}

	int get(char M[ROWS][COLS], int x, int y) {

		return M[x - 1][y] + M[x + 1][y] + M[x - 1][y + 1] + M[x + 1][y + 1] + M[x - 1][y - 1] +
			M[x + 1][y - 1] +M[x][y-1]+M[x][y+1] - 8 * '0';


	}
	void find(char S[ROWS][COLS], char M[ROWS][COLS], int row, int col) {
		int x, y = 0;
		int m = 0;

		
		while (m < row * col - 10) {
			printf("请输入坐标");
			scanf("%d %d", &x, &y);
			if (x > 0 && x <= row && y > 0 && y <= col)
			{
				if (M[x][y] == '1') {
					printf("你被炸死了\n");
						print(M, ROW, COL);
						break;
				}
				else
				{
					int count = get(M, x, y);
					S[x][y] = '0' + count;
					print(S, ROW, COL);
					m++;
				}



			}
			else
			{
				printf("输入错误,重新输入\n");

			}

		}

	}

test.c

#include"game.h"
void menu() {

	printf("***********\n");
	printf("****选择游戏****\n");
	printf("****1:进行游戏****\n");
	printf("****0:退出游戏****\n");


}
void game() {
	char S[ROWS][COLS];
	char M[ROWS][COLS];
	init(S, ROWS, COLS, '*');//初始化棋盘
	init(M, ROWS, COLS, '0');
	print(S, ROW, COL);//打印棋盘
	Set(M, ROW, COL);//随机设置雷
	find(S, M, ROWS, COLS);//排查雷




}

int main()

{
	srand((unsigned)time(NULL));
	int input = 0;

	do
	{
		menu();
		scanf("%d", &input);

		switch (input)


		{
		case 1: {game();
			break;


		}
		case 0:break;



		default:printf("重新选择\n");
			break;
		}

	} while (input);

	return 0;

}

终于写完了,哎累死了~~~~

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值