C语言实现扫雷

函数实现类 Lei.c

#define _CRT_SECURE_NO_WARNINGS
#include "Lei.h"
//打印菜单
void menu() {
	printf("==========扫雷===========\n");
	printf("=========================\n");
	printf("=========(1)Play=========\n");
	printf("=========(0)Eist=========\n");
}
//初始化棋盘
//arr[real_leng][real_wide]用来接收传过来的数组
//line是指定要初始化的行数
//row是指定要初始化的列数
//index是要初始化成什么符号
void initChess(int arr[real_leng][real_wide], int line, int row,int index) {
	for (int i = 0; i < real_leng; i++) {
		for (int j = 0; j < real_wide; j++) {
			arr[i][j] = index;
		}
		
	}
}
//打印棋盘
//line是指定要打印的行数
//row是指定要打印的列数
//format是要打印的格式,为1则说明要打印游玩棋盘,为0则说明要打印实际棋盘
void printChess(int arr[real_leng][real_wide],int line,int row,int format) {
	printf("\n==========雷区图===========\n");
	printf(" ");
    //打印列坐标
	for (int i = 1; i <= row; i++) {
		printf(" %2d",i);
	}
	printf("\n");
    
	for (int i = 1; i <= line; i++) {
	    //打印行坐标
    	printf("%2d|", i);
		for (int j = 1; j <= row; j++) {
			
            if(1==format)
			printf("%c |", arr[i][j]);
			else
			printf("%d |", arr[i][j]);

		}
		printf("\n  ");
		for (int j = 1; j <= row; j++) {
			printf("---");
		}
		printf("\n");
	}
}
//布雷
void BuLei(int arr[real_leng][real_wide], int line, int row) {
	int i = 0;
    //lenNum是默认雷数,条件不满足则说明布雷的数量已达到默认值
	while (i < lenNum) {
        //让x、y始终小于等于line、row
        //以便将雷布置在arr[1~line][1~row]区间中
		int x = (rand() % line) + 1;
		int y = (rand() % row) + 1;
        //如果这里还没布雷,那就布个雷
		if (arr[x][y] == 0) {
			arr[x][y] = 1;
			i++;
		}
	}
}
//扫雷
//返回值为1说明没被雷炸死,还能继续扫雷
int scan(int arr[real_leng][real_wide], int line, int row) {
	//判断坐标是否处于棋盘范围
	if (!(line >= 1 && line <= leng && row >= 1 && row <= wide)) {
		printf("不在棋盘范围内,请重新选择\n");
		return 1;
	}
    //如果此处已被探明或被插了棋,那就返回
	if (arr[line][row] != '*') {
		printf("此处已被排查\n");
		return 1;
	}
	else if(1==RealChess[line][row]) {
		printf("========= 你被雷炸死了!=========\n");
		//打印棋盘
        //打印出雷的布局,让你死得瞑目
		printChess(RealChess, leng, wide,0);
		return 0;
	}
	else {
        //展开雷区
		Open(arr, line, row);
		return 1;
	}


}
//点击展开功能
void Open(int arr[real_leng][real_wide], int line, int row) {
	//判断坐标是否处于棋盘范围
	if (line >= 1 && line <= leng && row >= 1 && row <= wide) {
        //如果此处未被探查
		if (Chess[line][row] == '*') {
			//则以此坐标探查四周,加起来的总值就是该坐标周围的雷数
            //并将探查到的结果标记在此坐标上
			Chess[line][row] = (RealChess[line - 1][row - 1] +
				RealChess[line - 1][row] +
				RealChess[line - 1][row + 1] +
				RealChess[line][row - 1] +
				RealChess[line][row + 1] +
				RealChess[line + 1][row - 1] +
				RealChess[line + 1][row] +
				RealChess[line + 1][row + 1]) + '0';
            //如果周围有雷,那就不探了,见好就收
			if (Chess[line][row] != '0') {
				return;
			}
			else {
				//否则就向四周八个方向展开探查
                //八个方向:东、南、西、北、东南、东北、西南、西北
				Open(arr, line - 1, row - 1);
				Open(arr, line - 1, row);
				Open(arr, line - 1, row + 1);
				Open(arr, line, row - 1);
				Open(arr, line, row + 1);
				Open(arr, line + 1, row - 1);
				Open(arr, line + 1, row);
				Open(arr, line + 1, row + 1);
			}
		}
	}
    //不在棋盘范围就返回
	else {
		return;
	}		

}
//插旗
void inFlag(int arr[real_leng][real_wide], int line, int row) {
	//如果此处未被探查,就插个棋
    if ('*' == Chess[line][row]) {
		Chess[line][row] = 'X';
	}
    //如果此处已被探明情况,那就不能插
	else {
		printf("此位置无法插棋\n");
	}
	return;
}
//拔旗
void pullFlag(int arr[real_leng][real_wide], int line, int row) {
    //判断此处有没有旗,有旗就能拔
	if ('X' == Chess[line][row]) {
		Chess[line][row] = '*';
	}
    //没旗那拔了个空气,顺便提醒一下
	else {
		printf("这里没有旗能拔\n");
	}
	return;
}
//检查是否胜利
int isSuccess(int arr[real_leng][real_wide]) {
	int sum = 0;
    //如果除了布雷的地方其他都被探过了,那就直接宣布胜利
	for (int i = 1; i <=leng; i++) {
		for (int j = 1; j <= wide; j++) {
			if ('*' == Chess[i][j] || 'X' == Chess[i][j]) {
				sum++;
			}
		}
	}
	return sum;
}

函数声明类 Lei.h

#pragma once
#include <stdio.h>
//整随机数要用到这两个头文件
#include <time.h>
#include <stdlib.h>
//打印菜单
void menu();
//真正棋盘的长宽
//leng为长,wide为宽
#define real_leng 10
#define real_wide 10
//游玩时棋盘的长宽
#define leng 8
#define wide 8
//默认雷的数量
#define lenNum 10
//分成两个棋盘的原因是:需要一个数组存字符,一个数组存整数
//能使打印时很方便,还能让点击展开函数能通过相加来算出周围的雷数
//实际棋盘
int RealChess[real_leng][real_wide];

//游玩棋盘
int Chess[real_leng][real_wide];
//初始化棋盘
void initChess(int arr[real_leng][real_wide], int line, int row,int index);
//打印棋盘
void printChess(int arr[real_leng][real_wide], int line, int row, int format);
//布雷
void BuLei(int arr[real_leng][real_wide], int line, int row);
//扫雷
int scan(int arr[real_leng][real_wide], int line, int row);
//点击展开
void Open(int arr[real_leng][real_wide], int line, int row);
//插旗
void inFlag(int arr[real_leng][real_wide], int line, int row);
//拔旗
void pullFlag(int arr[real_leng][real_wide], int line, int row);
//检查是否胜利
int isSuccess(int arr[real_leng][real_wide]);

 运行类 test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Lei.h"
int main() {
	srand((unsigned)time(NULL));
	//实际棋盘
	RealChess[real_leng][real_wide];
	
	//游玩棋盘
	Chess[real_leng][real_wide];
	int input = 0;

	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input) {
		case 1:
			//初始化游玩棋盘
			initChess(Chess, real_leng, real_wide, '*');
			//初始化实际棋盘
			initChess(RealChess, real_leng, real_wide,0);
			//给棋盘布雷
            BuLei(RealChess, leng,wide);
			//状态值,判断是否触雷
			int cond = 1;
			//此时剩余的雷数,归零则胜利
			int Len = lenNum;
			//剩余的插旗数量
			int Flag = lenNum;
			//两个坐标
			int line, row;
			while (cond) {
				//打印棋盘
				printChess(Chess, leng, wide, 1);
				printf("===========================\n");
				printf("\n还未排查到的雷的数量:%d\n", Len);
				printf("旗的数量:%d", Flag);

				printf("\n========== 扫雷 =========\n");
				printf("=========(1)排雷=========\n");
				printf("=========(2)插旗=========\n");
				printf("=========(3)拔旗=========\n");
				printf("请输入选择:>");
				scanf("%d", &line);
				//清理缓冲区
				while(getchar()!=EOF){}
				if (2 == line) {
					if (0 == Flag) {
						printf("\n无旗可插\n");
						continue;
					}
					printf("=========插旗=========\n");

					printf("请输入坐标:>");
					scanf("%d %d", &line, &row);
					//清理缓冲区
					while (getchar() != EOF) {}
					//插旗
					inFlag(Chess, line, row);
					Flag--;
					if (1 == RealChess[line][row]) {
						Len--;
					}
				}
				else if (3 == line) {
					printf("=========拔旗=========\n");
					printf("请输入坐标:>");
					scanf("%d %d", &line, &row);
					//清理缓冲区
					while (getchar() != EOF) {}
					//拔旗
					pullFlag(Chess, line, row);
					Flag++;
					if (1 == RealChess[line][row]) {
						Len++;
					}
				}
				else if (1 == line) {
					printf("=========排雷=========\n");

					printf("请输入坐标:>");
					scanf("%d %d", &line, &row);
					//清理缓冲区
					while (getchar() != EOF) {}

					//扫雷
					cond = scan(Chess, line, row);
				}
				else {
					printf("选择错误,请重新输入(1/2/3)\n");
				}
				if (0 == Len) {
					printf("\n========= 你胜利了!=========\n");
					cond = 0;
				}
				else if (Len == isSuccess(Chess)) {
					printf("\n========= 你胜利了!=========\n");
						cond = 0;
				}
			}
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("请重新输入(1/0)\n");
			break;
		}
	} while (input);
	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值