扫雷的实现

CSDN小伙伴们,大家好啊,这次我们来实现一个小游戏——扫雷

扫雷规则大概是点击未开的方块,若是雷,游戏失败,若不是雷,将该位置换为一个数字,该数字表示该位置一圈的8个位置的雷的个数

接下来,让我们一起实现它吧!

一、主体

1、框架

//test.c
int main()
{
    return 0;
}

2、主页

①选择主体

游戏首先画面是选择画面,开始游戏后结束游戏返回该界面,退出游戏直接停止程序

//test.c
int main()
{
	int input = 0;
	do
	{
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1: 
			printf("扫雷\n");
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

②主页主体

主页画面,我们简单设计一下

void menu()
{
	printf("******************************\n");
	printf("*********  1 . play  *********\n");
	printf("*********  0 . quit  *********\n");
	printf("******************************\n");
}

效果大致是这样

 之后我们就可以开始思考编写游戏规则代码啦,为了总体代码的效率和可读性,我们采用多自定义函数来实现。

 test.c为主,game.c为辅

二、客体

1、声明数组

首先我们思考,扫雷是   某*某   大的方格,这样我们可以用二维数组来实现,而且我们要用两个,一个用来布置雷,一个用来显示

以制作9*9为例

//game.h
#define POW 11
#define COL 11
//test.c
void game()
{
	int arr1[POW][COL] = { 0 };
	int arr2[POW][COL] = { 0 };
}

为什么我们用11而不是9呢?

在我们打开一个非雷的方格时,需要显示其中一圈的雷的个数,如果用9,在顶点的位置需要判断3个位置,边上需要判断5个位置,而其他地方需要判断8个位置,数量不统一,容易越界访问,这样会加大代码的难度,而我们在9*9的方格外再加一层的话,有效9*9的区域就都可以判断8个位置了,得到了统一,也不易越界。

2、初始化数组

我们将展示的数字为arr1(用“*”表示未打开),布置雷为arr2(0表示非雷,1表示雷)

//game.c
void arr_init(int arr[POW][COL], int pow, int col, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < pow; i++)
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = set;
		}
	}
}
//test.c
void game()
{
	int arr1[POW][COL] = { 0 };
	int arr2[POW][COL] = { 0 };
	arr_init(arr1, POW, COL, '*');
	arr_init(arr2, POW, COL, '0');
}

3、布置雷

布置雷要有随机性,所以我们使用rand函数和srand来实现,用时间戳来给srand提供变化值

//game.c
void lay_mine(int arr2[POW][COL], int pow, int col)
{
	int z = 10;
	while (z)
	{
		int x = rand() % pow + 1;
		int y = rand() % col + 1;
		if (arr2[x][y] == '0')
		{
			arr2[x][y] = '1';
			z--;
		}
	}
}
//pow=POW-2
//col=COL-2
//test.c
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;
}

4、打印雷盘

//game.c
void chess(int arr[POW][COL], int pow, int col)
{
	int i = 0;
	int j = 0;
	printf("*************扫雷*************\n");
	for (i = 0; i <= 9; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= 9; i++)
	{
		printf("%d ", i);
		for (j = 1; j <=9; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

效果大概就是这样 

 我们也可以打印一下arr2来看看雷的布置情况

 5、排雷

大概思路是,输入坐标,坐标范围正确,若该位置是雷,游戏结束,并打印arr2

若输入坐标不是雷,将该位置的“*”改为数字,该数字代表旁边有几个雷,并打印arr1

坐标错误重新输入坐标

(x-1,y-1)(x-1,y)(x-1,y+1)
(x,y-1)打开的位置(x,y)(x,y+1)
(x+1,y-1)(x+1,y)(x+1,y+1)

非雷是用字符‘0’表示的,雷是用字符‘1’表示的

所以(x,y)所显示的数字应该是旁边8个数的ASCII码相加再减8个字符‘0’的ASCII码

//game.c
void check(int arr2[POW][COL], int arr1[POW][COL], int pow, int col)
{
	int x = 0;
	int y = 0;
	int z = 0;
	while (z <= 71)
	{
		printf("请输入坐标:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= pow && y >= 1 && y <= col)
		{
			if (arr2[x][y] == '1')
			{
				printf("很遗憾,你踩雷了\n");
				chess(arr2, POW, COL);
				break;
			}
			else
			{
				int s = judge(arr2, x, y);
				arr1[x][y] = s + '0';
				chess(arr1, POW, COL);
				z++;
			}
		}
		else printf("请输入正确坐标\n");
	}
	if (z == 71) printf("恭喜你,排雷成功\n");
}

int judge(int arr2[POW][COL], int x, int y)
{
	return ((arr2[x - 1][y - 1] +
		arr2[x - 1][y] + arr2[x - 1][y + 1] +
		arr2[x][y - 1] + arr2[x][y + 1] +
		arr2[x + 1][y - 1] + arr2[x + 1][y] + arr2[x + 1][y + 1]) - 8 * 48);
}

三、主体和客体连接

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

#define POW 11
#define COL 11

//数组初始化
void arr_init(int arr1[POW][COL], int pow, int col, char set);
//打印棋盘
void chess(int arr[POW][COL], int pow, int col);
//布置雷
void lay_mine(int arr2[POW][COL], int pow, int col);
//排查雷
void check(int arr2[POW][COL], int arr1[POW][COL], int pow, int col);

 四、总代码

最后所以代码为下

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

#define POW 11
#define COL 11

//数组初始化
void arr_init(int arr1[POW][COL], int pow, int col, char set);
//打印棋盘
void chess(int arr[POW][COL], int pow, int col);
//布置雷
void lay_mine(int arr2[POW][COL], int pow, int col);
//排查雷
void check(int arr2[POW][COL], int arr1[POW][COL], int pow, int col);
//game.c
#include"game.h"
//数组初始化
void arr_init(int arr[POW][COL], int pow, int col, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < pow; i++)
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = set;
		}
	}
}
//布置雷
void lay_mine(int arr2[POW][COL], int pow, int col)
{
	int z = 10;
	while (z)
	{
		int x = rand() % pow + 1;
		int y = rand() % col + 1;
		if (arr2[x][y] == '0')
		{
			arr2[x][y] = '1';
			z--;
		}
	}
}
void chess(int arr[POW][COL], int pow, int col)
{
	int i = 0;
	int j = 0;
	printf("*************扫雷*************\n");
	for (i = 0; i <= 9; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= 9; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= 9; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

//排查雷
void check(int arr2[POW][COL], int arr1[POW][COL], int pow, int col)
{
	int x = 0;
	int y = 0;
	int z = 0;
	while (z <= 71)
	{
		printf("请输入坐标:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= pow && y >= 1 && y <= col)
		{
			if (arr2[x][y] == '1')
			{
				printf("很遗憾,你踩雷了\n");
				chess(arr2, POW, COL);
				break;
			}
			else
			{
				int s = judge(arr2, x, y);
				arr1[x][y] = s + '0';
				chess(arr1, POW, COL);
				z++;
			}
		}
		else printf("请输入正确坐标\n");
	}
	if (z == 71) printf("恭喜你,排雷成功\n");
}

int judge(int arr2[POW][COL], int x, int y)
{
	return ((arr2[x - 1][y - 1] +
		arr2[x - 1][y] + arr2[x - 1][y + 1] +
		arr2[x][y - 1] + arr2[x][y + 1] +
		arr2[x + 1][y - 1] + arr2[x + 1][y] + arr2[x + 1][y + 1]) - 8 * 48);
}
//test.c
#include"game.h"
void menu()
{
	printf("******************************\n");
	printf("*********  1 . play  *********\n");
	printf("*********  0 . quit  *********\n");
	printf("******************************\n");
}
void game()
{
	int arr1[POW][COL] = { 0 };
	int arr2[POW][COL] = { 0 };
	arr_init(arr1, POW, COL, '*');
	arr_init(arr2, POW, COL, '0');
	lay_mine(arr2, POW-2, COL-2);
	chess(arr1, POW-2, COL-2);
	check(arr2, arr1, POW-2, COL-2);
}
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;
}

以上就是基本扫雷的全部内容,主要运用的是循环,分支语句,函数调用,ASCII运用等,感谢观看~ 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值