C语言:扫雷(简单制作版)

扫雷这个游戏大家都应该玩过,那么扫雷规则我就不细说了,我将会以9*9的扫雷棋盘进行讲解

制作一个扫雷游戏,肯定是比较复杂,所以我们选择多份文件、多个函数进行编写代码

一个,h头文件,两个.c文件

我们先来看看有文件

#pragma once
#include"game.h"
#include<stdio.h>
#define H 9
#define L 9
#define HS H+2
#define LS L+2
void game(char arr2[H][L], int h, int l);
void set_mine(char arr1[HS][LS], int hs, int ls);
#include<stdlib.h>
#include<time.h>
void play(char arr1[HS][LS],char arr2[H][L], int h, int l);
static int GetMineCount(char arr1[HS][LS], int x, int y);
void sign(char arr1[HS][LS], char arr2[H][L], int x, int y,int h,int l);

制作进入游戏界面

这个不难,和上一期猜数字(CSDN)一样就没什么问题了,你也可以有自己的想法,多增加以下观赏性,尽量与扫雷有关就好了

菜单函数

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

}

游戏中的界面

扫雷游戏是一个n*n的平面图,那么我们就可以想到使用二维数组,上一期讲到二维数组的创建

这就是我们的棋盘,字符‘0’就是没有炸弹的坐标,字符‘1’就是我们埋的炸弹

根据规则,当我们选定一个坐标的时候,如果这个坐标没有炸弹,那么将会显示它附近8个坐标的炸弹数量;如果这是炸弹,游戏失败并结束

我们可以想象,如果只设置一个二维数组那就真的太困难了,所以我们设置两个二维数组,可以理解为设置两个棋盘,只要用函数进行传参就能够使参数信息互通啦,一个用来给玩家看的,一个是用来埋炸弹的,不能给玩家看的

用for循环就用'*'可以布置图1

又因为这样看这些坐标不方便,所以我们加一些代码,使它有横坐标和纵坐标,然后合起来,形成一个不需要返回值的函数

玩家界面函数

void game(char arr2[H][L],int h,int l)
{
	
	for (int i = 1; i <= h; i++)
	{
		for (int n = 1; n <= l; n++)
		{
			arr2[i][n] = '*';
		}
	}
	for (int i = 0; i <= 9; i++)
	{
		printf("%d ", i);
	}printf("\n");
	for (int i = 1; i <= h; i++)
	{
		printf("%d ", i);
		for (int n = 1; n <= l; n++)
		{
			printf("%c ", arr2[i][n]);
		}
		printf("\n");
	}
 }

就成功啦!!

有个问题啊,怎么计算附近8个坐标的炸弹数量,而且有些坐标附近只有三个坐标,为了解决这个问题,我们可以将埋炸弹的棋盘改成11*11的,不就解决了

这样,将最外层的坐标全部改为字符‘0’就可以方便计算了

好,那么棋盘搞定了,接下来埋炸弹,炸弹是要随即放的,我们可以使用rand(),这可以生成0~32767,但是,我们是9*9的棋盘,int ret = rand()%9+1就好了,用ret接受返回值

因为是平面坐标嘛,所以设置两个

int retx = rand()%9+1;
int rety = rand()%9+1;

这样我们就随机生成坐标啦,但是,有个BUG,如果生成了两个一样的坐标那么不就少了炸弹了吗,所以我们要加一个判断语句,再加一个while循环和count来设置10个炸弹,再将坐标传入二维数组就行啦,这是不能给玩家看的棋盘喔

int count = 10;

while (count) {
int ret1 = rand() % 9 + 1;
int ret2 = rand() % 9 + 1;
	if (arr1[ret1][ret2] != '1') {
		arr1[ret1][ret2] = '1';
		count--;
	}
}

由于rand()的基准值不会变,所以我们要引用srand()和time函数,在猜数字那一期有讲

srand((unsigned int)time(NULL));

那么埋炸弹就没有问题了

埋雷函数

void set_mine(char arr1[HS][LS], int hs, int ls)
{
	for (int i = 0; i < hs; i++)
	{
		for (int n = 0; n < ls; n++)
		{
			arr1[i][n] = '0';
		}
	}
	int count = 10;

	while (count) {
	int ret1 = rand() % 9 + 1;
	int ret2 = rand() % 9 + 1;
		if (arr1[ret1][ret2] != '1') {
			arr1[ret1][ret2] = '1';
			count--;
		}
	}
}

游戏规则(函数实现)

我们先来计算附近的炸弹数量,很简单,直接简单粗暴相加,但是因为是字符相加减得到的是数值,所以要加上字符‘0’才能将得到的值转换为字符,然后再传给二维数组。用函数就可以解决了

计算附近雷的数量

int GetMineCount(char mine[HS][LS], int x, int y)
{
	return mine[x - 1][y] + mine[x - 1][y - 1] +
		mine[x][y - 1] + mine[x + 1][y - 1] +
		mine[x + 1][y] + mine[x + 1][y + 1] +
		mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0';
}

标记雷坐标函数

void sign(char arr1[HS][LS], char arr2[H][L],int x,int y,int h,int l)
{
re:
	printf("是否标记雷,是请按1,否请按0\n");
	int s = 0;
	scanf("%d", & s);
	while (s)
	{
		printf("请输入标记坐标:");
		int x, y;
		scanf("%d%d", &x, &y);
		if (x > 9 || x < 1 || y > 9 || y < 1)
		{
			printf("输入有误,请重新输入!\n");
			goto re;
		}
		else
		{
			system("cls");
			for (int i = 0; i <= 9; i++)
			{
				printf("%d ", i);
			}printf("\n");
			arr2[x][y] = '!';
			for (int i = 1; i <= h; i++)
			{
				printf("%d ", i);
				for (int n = 1; n <= l; n++)
				{
					printf("%c ", arr2[i][n]);
				}
				printf("\n");
			}
			goto re;
		}
	}
}

1.首先判断所填的坐标是否合法,然后判断是不是炸弹,那么使用判断语句就轻松解决啦

2.接下来就是将选中的坐标转变为附近的炸弹数值

3.如果游戏失败,就要给玩家看看炸弹的分布

4.标记雷坐标

void play(char arr1[HS][LS],char arr2[H][L], int h, int l)
{
	int count = H*L - 10;
	while (count)
	{
		count--;
		int x = 0, y = 0;
		printf("-----------------------\n");
		printf("请输入你的排雷坐标:");
		scanf("%d%d", &x, &y);
		if (x > 9 || x < 1 || y > 9 || y < 1)
		{
			printf("输入有误,请重新输入!\n");
		}
		else
		{
			if (arr1[x][y] != '1')
			{
				int g = GetMineCount(arr1, x, y);
				arr2[x][y] = g + '0';
				system("cls");
				for (int i = 0; i <= 9; i++)
				{
					printf("%d ", i);
				}printf("\n");
				for (int i = 1; i <= h; i++)
				{
					printf("%d ", i);
					for (int n = 1; n <= l; n++)
					{
						printf("%c ", arr2[i][n]);
					}
					printf("\n");
				}sign(arr1, arr2, x, y,h,l);
			}
			else
			{
				printf("BOOM!\nGAME OVER!\n你失败了\n"); 
				for (int i = 0; i <= 9; i++)
				{
					printf("%d ", i);
				}printf("\n");
				for (int i = 1; i <= h; i++)
				{
					printf("%d ", i);
					for (int n = 1; n <= l; n++)
					{
						printf("%c ", arr1[i][n]);
					}
					printf("\n");
				}break;
			}
		}
		
	}
	if (count==0){printf("恭喜你排雷成功!!!\n");
	for (int i = 0; i <= 9; i++)
	{
		printf("%d ", i);
	}printf("\n");
	for (int i = 1; i <= h; i++)
	{
		printf("%d ", i);
		for (int n = 1; n <= l; n++)
		{
			printf("%c ", arr1[i][n]);
		}
		printf("\n");
	}
	}

}

主函数

我们要让玩家选择是否游戏,所以要用到do while循环,必须先执行一次,看玩家玩不玩

然后再将我们写好的函数带入

int main()
{
	int a = 0;
	srand((unsigned int)time(NULL));
	char arr2[H][L];
	char arr1[HS][LS];
	do
	{
		menu();
		scanf("%d", &a);
		switch (a)
		{
		case 1:
		{
			game(arr2, H, L); set_mine(arr1, HS, LS); play(arr1,arr2, H, L);
			break; 
		}
		case 0:printf("退出游戏\n"); break;
		default:printf("输入错误\n");
		}
	} while (a);

	return 0;
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值