【扫雷—C语言实现】

请添加图片描述



前言

个人写的扫雷C语言实现,望交流


一、main函数所在源文件:test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void Meun(void) {
	printf("-------------------------n");
	printf("-------------------------n");
	printf("---------1    开始-------n");
	printf("---------0    结束-------n");
	printf("-------------------------n");
	printf("-------------------------n");
}


void Game() {

	// 创建布置雷棋盘
	char set[ROW][LINE] = { 0 };
	// 创建排查雷棋盘
	char che[ROW][LINE] = { 0 };

	// 初始化棋盘(初始化都为*)
	Init(set);
	Init(che);

	// 布置雷(布置雷为'@')
	// 布置雷的数目见宏定义变量
	LayThu(set);

	// 打印布置好雷的棋盘(只打印有效内圈)(想真正玩游戏可以将其注释)
	Print(set);
	printf("n");

	// 用count指标来记录排雷次数,10次即为获胜(注意:应该放在游戏循环外!!!!!!)
	int count = 0;

	// 用户开始游戏
	while (1) {
		
		// 打印排查棋盘(只打印有效内圈)
		Print(che);
		
		// 用户输入要排查的位置(用户输入直接坐标,后面排查会减去1作为数组下标)
		// 输入范围:x:1~ROW-2  y:1~LINE-2
		int x = 0;
		int y = 0;
		printf("请输入您要排查的坐标(x y)n");
		scanf("%d %d", &x, &y);

		// 判定该位置是否合法,首先应该将用户转化为数组有效(内圈)下标,
		// 用户输入x:1~ROW-2 实际在棋盘中对应:下标x:1~ROW-2(恰好相同,可以自己在纸上试试)
		//(合法位置:在行下标x为1~ROW-2,列下标y为1~LINE-2,即在棋盘内圈中)
		if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= LINE - 2) {
			
			// 判定该位置是否为雷
			// 注意:应该与雷盘相比较!!!!!!
			if ('@' == set[x][y]) {
				printf("很遗憾!您踩到了地雷!游戏结束!n");
				Print(set);
				break;
			}
			// 确定该位置没被排查过
			else if('*' == che[x][y]) {

				// 布置排查雷的棋盘(该位置如果周围有几个雷,就将该位置布置为'几')
				// 注意:应该向函数输入雷盘!!!!!!
				char ret = Judge(set, x, y);
				che[x][y] = ret;
				count++;

				// 每布置一次,就判定count是否达到10次(胜利)(※※※可优化:规则随自己想法改变)
				// 如果是其他规则也可以:比如count==(ROW-2)*(LINE-2)-THUNUM时成功
				// 这样可以将原本开始游戏的死循环条件设置为while(count < (ROW-2)*(LINE-2)-THUNUM)
				// 最后加循环外对应加else来说明胜利
				if (SUCNUM == count) {
					printf("恭喜您!您已胜利!n");
					Print(set);
					break;
				}
				else {
					printf("游戏继续!n");
				}
			}//布置雷结尾
			else {
				printf("该位置已被排查,请重新输入n");
			}
		}//判定位置合法结尾
		else {
			printf("该位置不在排查范围内,请重新输入n");
		}
	}//游戏死循环结尾

}//函数结尾


int main() {

	srand((unsigned int)time(NULL));
	int input = 0;
	do {
		Meun();
		printf("请输入您的选择1开始/0结束n");
		scanf("%d", &input);
		switch (input) {
		case 1:
			Game();
			break;
		case 0:
			printf("已退出n");
			break;
		default:
			printf("输入有误,请重新输入n");
			break;
		}

	} while (input);

	return 0;
}

二、游戏相关函数定义源文件:game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

// (初始化都为*)
void Init(char board[ROW][LINE]) {
	
	int i = ROW;
	int j = LINE;
	for (i = 0; i < ROW; i++) {
		for (j = 0; j < LINE; j++) {
			board[i][j] = '*';
		}
	}

}


// 打印棋盘(仅打印创建棋盘的有效范围(内圈))(※※※可优化:将行列号也对应打印)
void Print(char board[ROW][LINE]) {

	int i = ROW;
	int j = LINE;
	for (i = 1; i < ROW - 1; i++) {
		for (j = 1; j < LINE - 1; j++) {
			if (LINE - 1 == j) {
				printf("| %c |", board[i][j]);
			}
			else {
				printf("| %c ", board[i][j]);
			}
		}// 内层循环结尾
		printf("n");
		for (j = 1; j < LINE - 1; j++) {
			printf("——");
		}
		printf("n");
	}//外层循环结尾

}


// (布置雷为'@')
void LayThu(char board[ROW][LINE]) {

	// 记录放入的雷数
	int n = 0;

	// 循环创建随机位置,直到num个雷都合法布置好
	while (1) {

		// 创建随机数:原本为   x:0 ~ (ROW-2-1)  y:0 ~ (LINE-2-1)
		//           +1后范围:x:0 ~ ROW-2      y:0 ~ LINE-2
		// +1 的原因是因为外层多打印了一圈,雷只布置在里圈
		// 例如 ROW LINE都为11,创建下标为0~8,下标均加1即变为:1~9,即棋盘内圈

		int x = rand() % (ROW - 2) + 1;
		int y = rand() % (LINE - 2) + 1;

		// 判断位置合法性
		if ('*' == board[x][y]) {
			if (n <= THUNUM) {
				board[x][y] = '@';
				n++;
			}
			else {
				printf("雷已布置完毕n");
				break;
			}
		}
		else {
			printf("重新筛查中...n");
		}

	}// 死循环布置雷结尾
	
}


// 排查该位置周围的雷数(周围有几个雷,就返回'几')
// (这里的返回类型int和char都可以,因为在后面以%c打印,
// 内存中的二进制仅会取最低7个比特位来打印对应ASCII码表的字符)
char Judge(char board[ROW][LINE], int x, int y) {

	int sum = 0;
	int i = 0;
	int j = 0;
	for (i = x - 1; i <= x + 1; i++) {	
		for (j = y - 1; j <= y + 1; j++) {
			// 自身肯定不是雷,所以相当多加一个0而已
			if ('@' == board[i][j]) {
				sum++;
			}
		}// 内层循环结尾
	}// 外层循环结尾

	char ret = sum + '0';
	// sum + '0' 在内存中相当于sum加上'0'对应的ASCII码值48,
	// 例如:sum为2,在底层,sum + '0',sum和'0'分别先转为二进制,
	//      在CPU计算后即为50对应的二进制序列,然后写回内存中ret开
	//      辟的char类型空间发生截断,保留最低权值位的8个比特位,
	//      当打印棋盘时,每个元素是以%c打印,所以最后会打印出该二进制
	//      所对应的十进制对应的ASCII码字符,即为'sum'
	return ret;
}
// ※※※可优化:
// 如果将雷布置为'1',而棋盘初始化为'0',则这个可以直接返回:
// 一圈的字符元素之和减去8*'0'即得到一圈的雷数

三、头文件、宏定义、游戏函数等声明头文件:game.h

#define _CRT_SECURE_NO_WARNINGS 1

// 宏定义棋盘行列
#define ROW 7
#define LINE 7
// ※※※可优化,直接再定义两个宏变量分别为ROW-2 LINE-2,之后的使用内外圈可以分开求

//宏定义地雷数和需排雷数
#define THUNUM 10;
#define SUCNUM 10;

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

// 如果要保护某个函数,只在源文件能看到,那么不需要将它放入头文件
extern void Init(char board[ROW][LINE]);

extern void Print(char board[ROW][LINE]);

extern void LayThu(char board[ROW][LINE], int num);

extern char Judge(char board[ROW][LINE], int x, int y);

总结

这里对文章进行总结:
以上就是今天总结的内容,本文包括了所有个人写的扫雷C语言代码,分享给大家。
真?欢迎各位给予我更好的建议,欢迎访问!!!小编创作不易,觉得有用可以一键三连哦,感谢大家。peace
希望大家一起坚持学习,共同进步。梦想一旦被付诸行动,就会变得神圣。

欢迎各位大佬批评建议,分享更好的方法!!!???

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>