扫雷(C语言,命令行)

本文介绍了如何用C语言实现一个简单的命令行扫雷游戏,包括头文件的准备,函数的抽象,游戏菜单的设计,以及游戏主体的逻辑控制,展示了如何使用数组、逻辑判断和循环来完成扫雷游戏的各个部分。
摘要由CSDN通过智能技术生成

 大家龙年快乐啊!这个春节过的怎么样,是好好的睡了一觉,还是到处走亲戚呢。不过不管如何,假期已经临近结束,还是得打起精神迎接新一年的机遇和挑战了。

        话回正题,今天我们要实现的是一个简单命令行窗口的扫雷程序。

     一.头文件准备

#pragma once
#define ROW 9
#define COL 9
//防止越界
#define ROWS ROW+2
#define COLS COL+2
#define MINENUM 10

//启动游戏
void game();
//布雷
void SetMine();
//将a数组中全部填充val值
void initBoard(char a[ROWS][COLS], char val);
//探测周围有几个雷
int detect(int x, int y);
//打印棋盘
void DisplayBoard(char arr[ROWS][COLS]);
//根据探测结果修改展示数组
void modify(int x, int y, int& win);

        我们需要首先准备一个头文件,在其中定义一些宏和抽象函数以便后续的编辑。这样做的好处有三:1.如果想要修改扫雷的数据只需要在头文件中修改即可        2.首先定义抽象方法有便于结构清晰明了,如果第一次无法考虑完善,也可以后续再抽象出函数添加。        3.C语言中还是分函数先后的,如果先在头文件中声明就可以避免一些先后顺序带来的麻烦。

     二.游戏菜单的完成

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
extern void game();//引用外部函数
void menu() {
	printf("****************************\n");
	printf("******0.exit   1.play*******\n");
	printf("****************************\n");
}
int main() {
	
	int input = 0;
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;

		case 0:
			printf("退出游戏");
			break;
		default:printf("输入错误!请重新输入:");
			break;
		}
	} while (input);
	return 0;
}

编写一些漂亮的界面,为用户提供进入和退出游戏的选择:

 三.游戏主体的完成

        这一部分涉及到逻辑控制部分,只需要使用数组,逻辑判断,循环和分支;总体而言是比较简单的。

        3.1 设计思路

        我们首先需要两个11行11列的坐标分别用于存放地雷和显示画板。

//我这里设置为全局变量,但也可以设置为game()内局部变量
//定义为静态类型防止外部访问
//雷
static char mine[ROWS][COLS] = { 0 };
//显示的矩阵
static char show[ROWS][COLS] = { 0 };

        之所以是11行11列是因为我这里没有对detect()做特殊处理,所有数组元素统一都是探测周围8格元素相加,而如图所示,探测1行1列时,则会访问到0行1列(绿色框)位置。因此需要多出两行置零,防止越界。

        然后需要对mine和show两个数组进行初始化。接着进行布雷,展示初始show数组。接着在存活条件下不断循环,判断输入条件(这里只做了点击的功能)是否满足获胜条件。直至获胜或死亡。

        

        3.2 game()函数实现

void game() {
	int win = 0;
	printf("---------扫雷----------\n");
	initBoard(mine,'0');
	initBoard(show,'*');
	SetMine();
	DisplayBoard(show);
	DisplayBoard(mine);
	int x, y;
	//这里只做了
	while(win<ROW*COL-MINENUM){
		printf("请分别输入要点击的位置的x轴和y轴坐标:\n");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= ROW && y > 0 && y <= COL) {
			if (mine[y][x] == '1') {
				printf("你死了!\n");
				DisplayBoard(mine);
				system("pause");
				system("cls");
				return;
			}
			else {
				modify(x,y,win);
				system("cls");
				DisplayBoard(show);
				
			}
		}
		else {
			printf("输入范围错误!请重新输入:\n");
		}
	} 
	printf("恭喜你!你赢了!");
	system("pause");
	system("cls");
}

        3.3 抽象函数实现

        剩下就是一些抽象函数的实现了。

void SetMine() {
	srand((unsigned int)time(NULL));
	for (int i = 0; i < MINENUM; i++) {
		int a = rand() % ROW+1;
		int b = rand() % COL+1;
		if (mine[a][b] == '0') {
			mine[a][b] = '1';
		}
		else {
			i--;
		}
	}
}
void initBoard(char a[ROWS][COLS],char val) {
	for (int i = 0; i < ROWS ; i++)
		for (int j = 0; j < COLS ; j++)
			a[i][j] = val;
}
void DisplayBoard(char arr[ROWS][COLS]) {
	for (int i = 0; i <= ROW;i++) {
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <=ROW; i++) {
		printf("%d ", i);
		for (int j = 1; j <= COL; j++) {
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}

}
int detect(int x, int y) {
	return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y + 1] + mine[x + 1][y] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x + 1][y - 1]-(int)8*'0';
}
void modify(int x,int y,int& win) {
	win++;
	int count = detect(x, y);
	if (count != 0) {
		show[y][x] = char('0'+count);
	
	}
	else {
		show[y][x] = ' ';
		//防止探测已经探测过的地方进入死循环
		if(x>1&&show[y][x-1]=='*')modify(x - 1, y, win);
		if(y>1 && show[y-1][x] == '*')modify(x, y - 1, win);
		if(x<ROW && show[y][x+1] == '*')modify(x + 1, y, win);
		if(y<COL && show[y+1][x] == '*')modify(x, y + 1, win);
	}

}

完整代码放到了我的gitee仓库:小游戏: 一些小游戏(gitee.com) ,可自取。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值