简单扫雷的实现(C)

事情太多了,更新迟了点。

上周学习了二维数组的知识,就写一个简单扫雷锻炼一下。

因为把之前写的简单小游戏(共3个)整合成为了一个简单游戏大厅的样子,方便以后继续向里面添加类似的游戏,所以主程序里面有一些与扫雷不相关的代码。

游戏逻辑

大家看看简单扫雷的逻辑就ok了。

1.首先要创建两个大小二维数组,把展示给玩家的数组称为面板,电脑用来布雷和数雷的面板称为雷板。
2.现假设面板的规格是n*n,那我们的两个板的规格要设置为(n+2)*(n+2)。
因为这样设置,检雷时不管输入的位置是啥,我们都可以绕一圈数雷,而不用特意处理雷板的边界和4个角。
3.宏定义面板大小和雷的数目。通过随机数让雷随机存在雷板里。
4.当用户输入位置时,需要检测用户输入的位置是否合法?越界和重复位置要让用户重复输入。若输入位置是雷,立即跳出,把雷板展示给用户,不能让用户输的不明不白。
5.数雷:把雷板初始为‘ ’,然后让‘#’代表雷。根据输入位置,检测以当前位置为中心的9个格子,数‘#’的数目,然后填入面板(不是雷板)。

以上,大概就是最简单的扫雷了。

代码实现

Clearmine.h   如下所示:
#ifndef __CLEARMINE_H__
#define __CLEARMINE_H__

#include <stdio.h>
#include <time.h>
#include <windows.h>
#pragma warning(disable:4996)
#define Size 10       //宏定义展示给人的面板的大小
#define DeathNum 35   //宏定义雷的数目

void ClearMine();
void SetMine(char arr[][Size + 2]);
void table(char arr[][Size + 2]);
void CountD(char arr[][Size + 2], char arr1[][Size + 2], int x, int y);

#endif
#endif
游戏逻辑Clearmine.c  如下所示:
#include "Clearmine.h"

void SetMine(char arr[][Size + 2])
{
	int cnt = DeathNum;  
	while (cnt) {
		int x = rand() % Size + 1;
		int y = rand() % Size + 1;
		if (arr[x][y] == ' ') {  //当前位置可以布雷
			arr[x][y] = '#';
		}
		cnt--;
	}
}

void table(char arr[][Size + 2])
{	//要好看的面板:试or计算
	printf("   |");
	for (int i = 0; i < Size; i++) {
		printf("%2d |", i + 1);
	}
	printf("\n--------------------------------------------\n");
	for (int i = 1; i <= Size; i++) {
		printf("%2d |", i);
		for (int j = 1; j <= Size; j++) {
			printf(" %c |", arr[i][j]);
		}
		printf("\n--------------------------------------------\n");
	}
}

void CountD(char arr[][Size + 2], char arr1[][Size + 2], int x, int y)
{
	int k = 0;  
	for (int i = x - 1; i <= x + 1; i++) {
		for (int j = y - 1; j <= y + 1; j++) {
			if (arr[i][j] == '#') {  
				k++;   //发现雷则自增1
			}
		}
	}
	arr1[x][y] = k + '0';  //将雷的数目填入面板相应位置
}

void ClearMine()
{
	srand((unsigned long)time(NULL));  //设置随机种子
	char showboard[Size + 2][Size + 2];  //面板:展示的数组
	char mineboard[Size + 2][Size + 2];  //布雷/检雷的面板
	memset(showboard, '*', sizeof(showboard));  //面板数组初始化
	memset(mineboard, ' ', sizeof(mineboard));  //雷板数组初始化
	SetMine(mineboard);    //布雷
	int cnt = Size * Size - DeathNum;    //设置安全位置的数目,控制游戏循环
	int x = 0,y = 0;
	do {
		system("cls");     //清空显示界面
		table(showboard);  //展示面板
		printf("请输入清扫位置# ");
		scanf("%d %d", &x, &y);
		if (x < 1 || x > Size || y < 1 || y > Size) {
			printf("输入位置越界,请重新输入!\n");
			continue;
		}
		if (showboard[x][y] != '*') {
			printf("该位置已经被排除!\n");
			continue;
		}
		if (mineboard[x][y] == '#') {  //踩雷即跳出
			break;
		}
		CountD(mineboard, showboard, x, y);  //计算输入位置附近雷的数目,并填入面板
		cnt--;  //安全位置减1
	} while (cnt >= 0);
	if (cnt > 0) {   //cnt>0则说明跳出循环时安全位置并没有被找完,只有一个原因:踩雷
		system("cls");
		printf("你被炸死了!你刚才输入的位置为(%d,%d)\n",x,y);
		table(mineboard);
	}
	else {
		printf("恭喜,你通过游戏!\n");
	}
	Sleep(1000);  
}


因为自己搞成了大厅,所以主函数就不展示了,要不然又得贴好多代码。主函数就写个简单菜单,用循环写一下就ok,能让用户进入游戏与退出游戏就行。

说明

这个扫雷代码没有实现那个达到某个条件就可以排除大片区域的逻辑,也没有难度的设置,后续有时间我再来更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值