C语言扫雷详解

下面我还是会用C语言代码的形式来编写一个扫雷程序,其实想通原理,扫雷用C语言实现其实不难。
在下面我还是会像上篇博客C语言三子棋一般采用多文件格式。
首先,要实现扫雷功能,要初始化数组,而多要想显示一个位置周围有多少雷,就得多定义,相当于显示1010的数组,就得定义1212的数组,因为周边会有反馈不了的情况,图有点丑,本人不会画图,能表达意思就行。
在这里插入图片描述
这样不管是哪个位置,它周围都会反馈8个位置的是否有雷的信息提醒用户。
1.开辟文件mine.h的头文件
在这里插入图片描述
这是在vs环境下创建mine.h头文件,图上还有源文件选择,这是为main.c和mine.c所用,下面会介绍。

该区域代码及注释如下:

#ifndef _MINE_H
#define _MINE_H

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

#pragma warning(disable:4996)

#define ROW 12
#define COL 12

#define NUM 20//宏定义了了20个雷

void Game();//该函数只会被调用,固无返回值。
void Initboard(char board[][COL],int row,int col,char elem);//elem是代表'0','*',这一会儿会初始化两个扫雷界面,一个用于记录,一个用于显示。
void Setmine(char mine[][COL], int row, int col);//这是一个埋雷的函数,里面会调用系统随机函数
void Showmine(char board[][COL], int row, int col);//为用户提供扫雷界面的显示,
char Getmine(char mine[][COL], int x, int y);//返回字符'0','1'.....,用于为用户提供周围雷的数量

#endif

2.编写main.c

代码如下:

#include "mine.h"
 
static void Menu()
{
	printf("######################################\n");
	printf("##      欢迎体验我的扫雷游戏       ###\n");
	printf("######################################\n");
	printf("###     1.play          2.exit     ###\n");
	printf("######################################\n");
	printf("Please select>>");

}
int main()
{
	int quit = 0;
	do
	{
		int select = 0;
		Menu();
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			printf("当前游戏已结束,是否再来一把?\n");
			break;
		case 2:
			quit = 1;//当用户选择2退出时,quit会被赋值成1,在while循环中取反后成0后退出循环。
			break;
		default:
			printf("你的选择有错误,请重新选择\n");
			break;
		}
	  }while (!quit);
		system("pause");
		return 0;
}

3.最重要的,也是最复杂的,编写mine.c,当中包含了各个函数的实现
代码如下

#include "mine.h"

void InitBoard(char board[][COL], int row, int col, char elem)//利用两个for循环来初始化12*12的二维数组
{
	int i = 0;
	for (; i < row; i++){
		int j = 0;
		for (; j < col; j++){
			board[i][j] = elem;
		}
	}
}
void SetMine(char mine[][COL], int row, int col)
{
	int n = NUM;
	while (n){
		int x = rand() % (row - 2) + 1;//本来row-2等于10,%10x的范围为0到9,再加上1范围变成了1到10,下面y也是同理
		int y = rand() % (col - 2) + 1;
		if (mine[x][y] == '1')//该条件是判断雷是否埋重复了,如果重复,continue则跳出此次循环,而执行下一次
		{
			continue;
		}

		mine[x][y] = '1';
		n--;
	}
}
void ShowBoard(char board[][COL], int row, int col)
{
	int i = 1;
	printf("   ");
	for (; i <= col - 2; i++){
		printf(" %-2d|", i);
	}
	printf("\n");
	for (i = 1; i <= col - 2; i++){
		printf("%3s", "----");
	}
	printf("---\n");

	for (i = 1; i <= row - 2; i++){
		printf("%2d|", i);
		int j = 1;
		for (; j <= col - 2; j++){
			printf(" %-2c|", board[i][j]);
		}
		printf("\n");
		for (j = 1; j <= col - 2; j++){
			printf("%3s", "----");
		}
		printf("---\n");
	}
}
char GetNum(char mine[][COL], int x, int y)//这里 -*'0'是根据ascii来的,返回的是字符'0',....,'8',而不是单纯的数字0到8中的数。
{
	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] - 7 * '0';//这里是返回的是用户在该位置周围8的位置雷的总数。
}

void Game()
{
	srand((unsigned long)time(NULL));//定义一个随机数种子,为后面埋雷提供基础。

	char board[ROW][COL];//定义一个12*12的数组,为初始化扫雷界面所用
	char mine[ROW][COL];//定义一个12*12的数组,为埋雷('0')所用

	InitBoard(board, ROW, COL, '*'); //'*'
	InitBoard(mine, ROW, COL, '0');  //'0'

	SetMine(mine, ROW, COL);

	int count = (ROW - 2)*(COL - 2) - NUM;//初始化为80
	do{
		system("cls");//调用系统函数"清屏"。
		int x = 0;
		int y = 0;
		ShowBoard(board, ROW, COL);
		printf("请输入你要扫的位置-> ");
		scanf("%d %d", &x, &y);
		if (x < 1 || x > 10 || y < 1 || y > 10)//输入数为1到10
		{
			printf("你输入的位置是错误的,请重新输入...\n");
			Sleep(1000);//调用系统函数间隔一秒
			continue;//跳出本次循环,继续下次循环
		}
		if (board[x][y] != '*'){
			printf("你输入的位置已经被扫过,请重新输入...\n");
			Sleep(1000);
			continue;
		}
		if (mine[x][y] == '0'){
			count--;
			char num = GetNum(mine, x, y);//统计用户输入坐标埋雷的数量(是字符数)
			board[x][y] = num;
		}
		else{
			printf("你输入的位置(%d, %d),有雷!\n", x, y);
			break;/直接跳出循环
		}
	} while (count > 0);

	char *result = NULL;//初始化一个指针变量
	if (count > 0){
		result = "##  扫雷结束, 你被炸死了:<   ##\n";
	}
	else{
		result = "##扫雷结束,恭喜你,成功啦:> ##\n";
	}
	printf("###############################\n");
	printf("%s", result);
	printf("###############################\n");
	ShowBoard(mine, ROW, COL);
}

运行截图
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
好了,扫雷小程序到此为此,是不是很有趣,自己可以动手试试哦。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值