c语言扫雷游戏

介绍

这两天写了很久的扫雷游戏,总代码超过350行
放在了我的gitte上→ 仓库 - 李俊伟 (lijunwei5980) - Gitee.com 
已实现的功能:
选择游戏难度(使用malloc动态规划数组)
扫雷中"0"的地方一扫一大片(递归调用)
四种操作:
排雷,标记疑似雷,取消标记,返回菜单
想想还差一个计时的才算是完善,等之后有空补上

代码

1.主函数部分(游戏主体)

//***
//File Name : mine_sweeping						
//Author : Winter_snow
//Version : ver0_2
//Created : 2023 / 12 / 10
//Description : Main Function :实现扫雷游戏
//History:
//<author>           <version>       <time>                 <Changes>
//Winter_snow         ver0_1         2023 / 12 / 09         实现基础扫雷功能:
//															一整片消除,选择三种难度
//Winter_snow         ver0_2         2023 / 12 / 10			实现标记雷,增加控制选项
//*******************************************************************************

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

//扫雷游戏
int main() {
	//打印游戏规则
	printRule();
	fflush(stdin);
	system("cls");
	//游戏主体
	do {//游戏可以来好多遍
		//打印菜单
		menu();

		//玩游戏
		int play;
		scanf("%1d", &play);
		fflush(stdin);//清空输入缓冲区,提高代码健壮性
		system("cls");
		if (!play) {//挽留
			printf("******************\n");
			printf("****0.狠心离开****\n");
			printf("****1.我再想想****\n");
			printf("******************\n");
			int exit;
			scanf("%d", &exit);
			fflush(stdin);
			system("cls");
			if (exit) continue;
			else
				break;
		}

		//选择难度
		int difficulty;

		do {//一直到选对为止
			printf("请输入游戏难度:\n");
			printf("1:9*9棋盘,10个雷\n");
			printf("2:16*16棋盘,40个雷\n");
			printf("3:30*16棋盘,99个雷\n");
			scanf("%1d", &difficulty);
			fflush(stdin);
			system("cls");
			if (difficulty == 1 || difficulty == 2 || difficulty == 3)
				break;
			else
				printf("输入有误,请重新选择难度:\n");
		} while (1);

		//定义不同难度的大小
		int row, col, mine_number;
		if (difficulty == 1) { row = 9; col = 9; mine_number = 10; }
		else if (difficulty == 2) { row = 16; col = 16; mine_number = 40; }
		else { row = 16; col = 30; mine_number = 99; }

		//动态分配三个“数组”
		char** mine = (char**)malloc(sizeof(char*) * (row + 2));
		for (int i = 0; i < row + 2; i++)
			mine[i] = (char*)malloc(sizeof(char) * (col + 2));

		char** show = (char**)malloc(sizeof(char*) * (row + 2));
		for (int i = 0; i < row + 2; i++)
			show[i] = (char*)malloc(sizeof(char) * (col + 2));

		char** showm = (char**)malloc(sizeof(char*) * (row + 2));
		for (int i = 0; i < row + 2; i++)
			showm[i] = (char*)malloc(sizeof(char) * (col + 2));

		//初始化
		init(mine, row + 2, col + 2, '0');
		init(show, row + 2, col + 2, '*');

		//布置雷
		minePlacement(mine, row, col, mine_number);
		for (int i = 0; i < row + 2; i++) {//赋予mark版的show以非mark版的show同样值
			for (int j = 0; j < col + 2; j++) {
				showm[i][j] = show[i][j];
			}
		}

		//打印棋盘
		system("cls");
		//print(mine, row, col);
		print(show, row, col);

		int count[2] = { 0 };//记录排除了多少位置
		do {
			//选操作
			int controls;
			printf("******************\n");
			printf("******1.排雷******\n");
			printf("***2.标记疑似雷***\n");
			printf("****3.删除标记****\n");
			printf("****4.返回菜单****\n");
			printf("******************\n");
			scanf("%1d", &controls);
			fflush(stdin);
			if (controls == 1)
				//排雷
				mineClearance(mine, show, showm, count, row, col, mine_number);
			else if (controls == 2)
				//标记疑似雷
				mark(showm, row, col);
			else if (controls == 3)
				//取消标记
				markCancel(show, showm, row, col);
			else if (controls == 4) {
				system("cls");
				printf("确定返回菜单?\n\n");
				printf("******************\n");
				printf("******0.确定******\n");
				printf("****1.我点错了****\n");
				printf("******************\n");
				int exit;
				scanf("%d", &exit);
				fflush(stdin);
				if (exit) {
					system("cls");
					print(showm, row, col);
					continue;
				}
				else
					break;//退出游戏
			}
			else
				printf("输入有误,请重新选择:\n");
		} while (count[0] < row * col - mine_number);
		if (count[0] >= row * col - mine_number) printf("\a恭喜!游戏成功!\n");


		//释放内存空间
		free(mine); mine = NULL;
		free(show); show = NULL;

	} while (1);
	return 0;
}

2.game.cpp文件(游戏主要功能的实现)

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

//打印游戏规则
void printRule() {
	printf("欢迎!以下是游戏规则:\n");
	printf("棋盘样式为:\n");
	printf("--------扫雷--------\n");
	printf("0 1 2 3 4 5 6 7 8 9\n");
	printf("1 * * * * * * * * *\n");
	printf("2 * * * * * * * * *\n");
	printf("3 * * * * * * * * *\n");
	printf("4 * * * * * * * * *\n");
	printf("5 * * * * * * * * *\n");
	printf("6 * * * * * * * * *\n");
	printf("7 * * * * * * * * *\n");
	printf("8 * * * * * * * * *\n");
	printf("9 * * * * * * * * *\n\n");
	printf("回车查看下一页\n");
	getchar();
	system("cls");
	printf("开始界面为:\n");
	printf("******************\n");
	printf("****0.退出游戏****\n");
	printf("****1.选择难度****\n");
	printf("******************\n\n");
	printf("输入选项前的数字选择开始游戏或结束游戏\n");
	printf("例如:要选择开始,则输入:1(回车)\n\n");
	printf("回车查看下一页\n");
	getchar();
	system("cls");
	printf("操作界面为:\n");
	printf("******************\n");
	printf("******1.排雷******\n");
	printf("***2.标记疑似雷***\n");
	printf("****3.删除标记****\n");
	printf("****4.返回菜单****\n");
	printf("******************\n\n");
	printf("输入选项前的数字选择操作\n");
	printf("例如:要选择排雷,则输入:1(回车)\n\n");
	printf("回车查看下一页\n");
	getchar();
	system("cls");
	printf("坐标输入规则为:x y(回车)\n\n");
	printf("例如:要排查第4列第3行的位置,则输入:4 3(回车)\n");
	printf("然后便会显示该位置周围(3*3)所有的雷的数量,例如:\n");
	printf("--------扫雷--------\n");
	printf("0 1 2 3 4 5 6 7 8 9\n");
	printf("1 * * * * * * * * *\n");
	printf("2 * * * * * * * * *\n");
	printf("3 * * * * * * * * *\n");
	printf("4 * * 2 * * * * * *\n");
	printf("5 * * * * * * * * *\n");
	printf("6 * * * * * * * * *\n");
	printf("7 * * * * * * * * *\n");
	printf("8 * * * * * * * * *\n");
	printf("9 * * * * * * * * *\n\n");
	printf("以上便是所有规则,阅读完毕请回车,祝您游戏愉快!:)\n");
	getchar();
}
//菜单
void menu() {
	printf("******************\n");
	printf("****0.退出游戏****\n");
	printf("****1.选择难度****\n");
	printf("******************\n");
}
//初始化
void init(char** arr, int rows, int cols, char fill) {
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			arr[i][j] = fill;
		}
	}
}
//打印棋盘
void print(char** arr, int row, int col) {
	printf("--------扫雷--------\n");
	for (int i = 0; i < col + 1; i++)
		printf("%-3d", i);
	printf("\n");
	for (int i = 0; i < row; i++) {
		printf("%2d ", i + 1);
		for (int j = 0; j < col; j++) {
			printf("%c  ", arr[i + 1][j + 1]);
		}
		printf("\n");
	}
}
//布置雷
void minePlacement(char** arr, int row, int col, int mine_number) {
	srand(time(NULL));
	int count = mine_number;
	while (count) {
		int x = rand() % row;
		int y = rand() % row;
		if (arr[x + 1][y + 1] == '0') {
			arr[x + 1][y + 1] = 'M';
			count--;
		}
	}
}
//排雷
char mineCount(char** mine, int x, int y) {
	int count = 0;
	for (int i = x - 1; i <= x + 1; i++) {
		for (int j = y - 1; j <= y + 1; j++) {
			if (mine[i][j] == 'M') count++;
		}
	}
	return count + '0';
}
void inspect(char** mine, char** show, char** showm, int row, int col, int x, int y, int count[]) {
	if (x > 0 && x <= row && y > 0 && y <= col) {
		if (mine[x][y] == 'M')//踩雷
			count[1] = 0;
		else if (mine[x][y] == '0') {//未踩雷
			if (show[x][y] == '*') {//未排查过
				show[x][y] = mineCount(mine, x, y);
				showm[x][y] = show[x][y];
				if (show[x][y] == '0') {//递归展开一片
					inspect(mine, show, showm, row, col, x, y + 1, count);
					inspect(mine, show, showm, row, col, x, y - 1, count);
					inspect(mine, show, showm, row, col, x + 1, y, count);
					inspect(mine, show, showm, row, col, x - 1, y, count);
				}
				count[0] = count[0] + 1;
				count[1] = 2;
			}
			else//排查过
				count[1] = 1;
		}
	}
	else count[1] = 3;//输入错误
}
void mineClearance(char** mine, char** show, char** showm, int count[], int row, int col, int mine_number) {
	int x, y;
	printf("请输入要排查的坐标:");
	scanf("%d %d", &x, &y);
	fflush(stdin);
	system("cls");
	inspect(mine, show, showm, row, col, x, y, count);
	if (count[1] == 0) {
		printf("\a\a\a踩雷,游戏失败\n");
		showm[x][y] = 'M';
		print(showm, row, col);
	}
	else if (count[1] == 1) {
		print(showm, row, col);
		//print(mine, row, col);
		printf("该位置已排查过!\n");
	}
	else if (count[1] == 3) {
		printf("输入有误,请输入棋盘范围内坐标!\n");
		print(showm, row, col);
		//print(mine, row, col);
	}
	else {
		system("cls");
		print(showm, row, col);
		//print(mine, row, col);
	}

}
//标记疑似雷
void mark(char** showm, int row, int col) {
	printf("请输入要标记的坐标:");
	int x, y;
	do {
		scanf("%d %d", &x, &y);
		fflush(stdin);
		if (x > 0 && x <= row && y > 0 && y <= col) {
			showm[x][y] = '#';
			break;
		}
		else printf("输入有误,请输入棋盘范围内坐标:\n");
	} while (1);
	system("cls");
	print(showm, row, col);
}
//取消标记
void markCancel(char** show, char** showm, int row, int col) {
	printf("请输入要取消标记的坐标:");
	int x, y;
	do {
		scanf("%d %d", &x, &y);
		fflush(stdin);
		if (showm[x][y] != '#') {
			printf("该位置未标记!\n");
			break;
		}
		else if (x > 0 && x <= row && y > 0 && y <= col) {
			showm[x][y] = show[x][y];
			break;
		}
		else printf("输入有误,请输入棋盘范围内坐标:\n");
	} while (1);
	system("cls");
	print(showm, row, col);
}

3.game.h统合的头文件

#pragma once

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


//打印游戏规则
void printRule();
//菜单
void menu();
//初始化
void init(char** arr, int rows, int cols, char fill);
//打印棋盘
void print(char** arr, int row, int col);
//布置雷
void minePlacement(char** arr, int row, int col, int mine_number);
//排雷
void mineClearance(char** mine, char** show, char** showm, int count[], int row, int col, int mine_number);
//标记疑似雷
void mark(char** showm, int row, int col);
//取消标记
void markCancel(char** show, char** showm, int row, int col);

感谢观看~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬有雪的学习之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值