C语言通过控制台实现扫雷游戏

学习了这么久c语言,相信你已经掌握了很多c语言的知识,今天我们就来试一试用c语言代码,实现一个很简略的扫雷游戏吧!

1.实现一个控制台菜单

首先我们希望用户能够在屏幕上看到一个简略的菜单界面,于是就可以采用最简单基础的printf语句,这样就可以在屏幕上看到一个简单的菜单啦

	void menu(){
	printf("请选择:  1---开始游戏, 0---退出游戏\n");
	printf("******************\n");
	printf("******************\n");
	printf("*****扫雷游戏*****\n");
	printf("******0.Exit******\n");
	printf("******1.Play******\n");
	printf("******************\n");
	printf("******************\n");

此时,用户进行数据输入,我们希望代码作出相应反应:如果用户输入1,则开始扫雷游戏;若输入0,则显示退出;同时,如果用户输入了除1和0之外的数据,这时候我们希望程序能够对用户作出提示,然后让用户重新输入数据。这部分功能我们选择在main函数中实现,于是代码如下:

int main() {
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input) {
		case 1: {
			printf("扫雷游戏开始!\n");
			printf("提示:共有10个雷\n");
            game();//扫雷游戏具体实现,此时还未定义函数
            break;
			
		}
		case 0: {
			printf("退出游戏!\n");
			break;
		}
		default: {
			printf("你输入的值有误,请重新输入!\n");
		}
		}
	} while (input);

	
	return 0;
}

于是,通过简单的switch语句和do-while语句,我们就完成了扫雷游戏的第一步!

接下来,我们进一步分析game函数的具体实现:

在这之前,我们需要先对扫雷游戏的底层逻辑做一个详细的分析:

2.分析扫雷游戏

这是一个基础难度的扫雷游戏,思考一下背后需要哪些内容呢?

(1)棋盘呈现----点开扫雷游戏,首先展示给我们的是一个棋盘,如何实现这个棋盘?我们该如何存储“雷”与“非雷”的信息?

(2)第二步,用户“点击”某个位置,然后棋盘上显示出该位置“雷”的数量----如何在控制台上实现一个等价的“点击”操作?以及如何显示出某位置“雷”的数量?如何计算?

(3)每一局雷的出现位置是随机的,我们如何产生雷?

接下来,我们一步步解决上述问题:

(1)扫雷棋盘的实现:对于棋盘,我们使用数组来进行存储;同时为了保持神秘,我们用一个默认字符数组来向用户展示,以下称为Empty_board;而棋盘则用board数组,同样是字符数组;而“雷”,我们使用字符‘1’,“非雷”,我们使用字符‘0’,空白棋盘使用‘*’表示

(2)在控制台上替换等价的点击操作,我们则选择让用户输入坐标,同时,为了方便用户,打印出棋盘各位置的坐标;而“雷”的数量的计算,我们则需要遍历一个元素周围的其余八个位置

要注意,在边界上的元素在计算雷的个数时,可能会出现越界的情况,于是我们选择将数组空间扩大一圈,方便我们处理边角位置的元素,即9x9的棋盘,但是我们定义11x11的数组,这样就避免了越界访问,同时也尽可能采用的简单的方式应对越界行为

(3)设置雷的时候,我们可以使用rand函数,并且使用srand函数更新种子,用time时间戳

3.代码实现

于是我们将代码分装:

test.c

game.h

game.c

3.1 test.c

#define _CRT_SECURE_NO_WARNINGS 1		
#include<stdio.h>
#include"game.h"
#include<time.h>
//#include"game.c"
//创建棋盘,用于存放雷
//扫雷游戏的实现
int game() {
	char board[cow][line] = { '0'};
	char empty_board[cow][line] = { '0'};
	//初始化棋盘
	Init_board(board, cow, line,'0');
	Init_board(empty_board, cow, line,'*');
	打印棋盘
	//Print_board(board, cow-2, line-2);
	Print_board(empty_board, cow-2, line-2);
	//布置雷
	Set_bomb(board, cow, line);
	//Print_board(board, cow - 2, line - 2);
	//排查雷
	int set = Search_bomb(board, empty_board, cow, line);
	if (set)
	{
		Print_board(board, cow - 2, line - 2);
		return 1;
	}
	else
		return 0;


	}
	void menu(){
	printf("请选择:  1---开始游戏, 0---退出游戏\n");
	printf("******************\n");
	printf("******************\n");
	printf("*****扫雷游戏*****\n");
	printf("******0.Exit******\n");
	printf("******1.Play******\n");
	printf("******************\n");
	printf("******************\n");
}
int main() {
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input) {
		case 1: {
			printf("扫雷游戏开始!\n");
			printf("提示:共有10个雷\n");
			int a = game();
			if (a)
				break;
			else break;
			
		}
		case 0: {
			printf("退出游戏!\n");
			break;
		}
		default: {
			printf("你输入的值有误,请重新输入!\n");
		}
		}
	} while (input);

	
	return 0;
}

3.2 game.h

#pragma once
#define cow 11
#define line 11
#include<stdlib.h>
//初始化棋盘
void Init_board(char arr[cow][line], int n, int m,char set);
//打印棋盘
void Print_board(char arr[cow][line], int n, int m);
//布置雷
void Set_bomb(char arr[cow][line], int n, int m);
//排查雷
int Search_bomb(char arr[cow][line], char arr2[cow][line], int m, int n);
int Count_bomb(char arr[cow][line], int m, int n);

3.3 game.c

#define _CRT_SECURE_NO_WARNINGS 1	
#pragma once
#include<stdio.h>
#include"game.h"
//计数
int Count_bomb(char arr[cow][line],int m,int n) {
	int count = 0;
	for (int i = m - 1; i <= m + 1; i++) {
		for (int j = n - 1; j <= n + 1; j++) {
			if (arr[i][j] == '1') {
				count++;
			}
		}
	}
	return count;
}
//排查雷
int Search_bomb(char arr[cow][line],char arr2[cow][line],int x,int y) {
	int n = 0, m = 0;
	int number = 0;
	while(number<71)
	{
	again:
		printf("请输入要排查的坐标:(m,n)\n");
		scanf("%d,%d", &m, &n);
		if (arr[m][n] == '1') {
			printf("你排到雷了!游戏结束!\n");
			return 1;
		}
		else if(arr2[m][n] != '*')
		{
			printf("你输入的是重复坐标,请重新输入!\n");
			goto again;
		}
		else
		{
			number++;
			int count = Count_bomb(arr,m,n);
			arr2[m][n] = (char)(count + 48);
			Print_board(arr2, x-2, y-2);
			goto again;
		}
	}
	printf("恭喜你,扫雷成功!\n");
	Print_board(arr2, x - 2, y - 2);
	return 0;
}
//设置雷
void Set_bomb(char arr[cow][line], int n, int m) {
	int i = rand() % 9 + 1;
	int j = rand() % 9 + 1;
	int count = 0;
	{
		while(count<10)
		{
			 i = rand() % 9 + 1;
			 j = rand() % 9 + 1;
				if (arr[i][j] == '0') {
					arr[i][j] = '1';
					count++;
				}
		}
			
	}
	//printf("%d %d\n", i, j);
}
//初始化棋盘
void Init_board(char arr[cow][line], int n, int m, char set) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			arr[i][j] = set;//棋子默认状态  
		}
	}
}
//打印棋盘
void Print_board(char arr[cow][line], int n, int m) {
	
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= m; j++) {
			if (i == 0)
				printf("%d ", j);

			else
				if (j == 0)
					printf("%d ", i);
				else printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值