C语言进行扫雷游戏的详细思路和实现

1扫雷游戏的思路

1.1问题1

 这是我们常见的扫雷游戏的画面,这里我们准备一个9*9的棋盘,我们假设用1和0来充满整个棋盘,用1来表示雷,0表示不是雷。当我们揭开一个格子后,得到1个数字来显示周围8个格子的雷的数量。但这样会出现问题,比如我们这里揭开最中间的数字,周围8个格子的雷的数量是1,数字就会从0变成1,显示给玩家,但是这个数字1到底表示是雷,还是周围8个格子雷的数量。就会产生冲突。

001
000
000

这里我们的解决办法是直接准备两个棋盘,一个装满0或1来表示不是雷或是雷。另一个棋盘用来展示给玩家。用*来填充,当玩家揭开一个格子后,反馈给玩家一个数字来表示周围8个格子雷的数量 。

1.2问题2

这里就会遇到一个新的问题,当我们想计算最外围一圈的格子的雷的数量时,因为不满8个格子无法进行计算。

000000000
000000000

这里我们解决问题的办法是直接准备2个11*11的棋盘 ,我们只展示给玩家中间的9*9个格子即可

2代码的初步实现

2.1文件的创建

这里我们创建2个.c文件,1个.h文件。.h用来实现游戏需要的函数名。一个.c文件用来实现游戏所需函数的具体内容,1个. c文件用来实现游戏。用这句代码将源c文件和头文件串起来。

#include"game.h"

 

2.2游戏的主体框架 

我们先来实现函数的主体框架,就是除游戏内容的框架,菜单我们用一个void函数来实现,

void menu() {
    printf("******1.开始游戏******");
    printf("******0.退出游戏******");

 }


 

我们用do while语句上来先打印出来游戏的菜单,在用个switch来选择开始游戏或退出游戏

int main() {int intput;
    do
    {
        menu();
        scanf("%d", &intput);
        switch (intput) {
        case 1:
            break;
        case 0:printf(" 退出游戏\n");
            break;
        default:
            break;
         }
    } while (intput);
}

2.3game函数的实现

2.3.1棋盘的初始化

我们先定义一些常量便于后续代码的使用,比如9展示给玩家的棋盘的长度,11真实棋盘的长度,10雷的数量,代码如下:

#define maxx 10
#define as 9
#define bs 9
#define ass as+2
#define bss bs+2

 

完成游戏的主体框架后,开始写game的主要内容,用void型函数来实现,首先我们建两个char数组用来当作棋盘,并初始化棋盘,一个初始化成*号展示给玩家,一个初始化成0,等会用来布置雷。

void game() {
	char arr1[ass][bss];
	char arr2[ass][bss];
	 initarr(arr1, '*');// 初始化棋盘
     initarr(arr2, '0');//初始化棋盘
}

初始化期棋盘的函数,我们写在game.c里,记得在头文件里先声明。后面的game函数使用每个函数都要先在.h 文件声明,后面就不叙述了。

void initarr(char arr[ass][bss], char x) {
	for (int i = 0; i < ass; i++)
		for (int j = 0; j < bss; j++) {
			arr[i][j] = x;
		}
}

2.3.2棋盘的打印

我们要将棋盘展示给玩家,就要将棋盘打印出来,为了方便玩家揭开格子,我们为棋盘写上行数,列数。代码如下:

void print(char arr[ass][bss], int a, int b) {
	for (int i = 0; i < 10; i++) {
		printf("%d ", i);
	}
	printf("\n");

	for (int i = 1; i <= as; i++) {
		printf("%d ", i);
		for (int j = 1; j <= bs; j++) {
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

 效果如下:

2.3.3雷的布置

 这里我们在while循环里用rand函数,srand函数,和time函数来随机生成横纵坐标,在这些坐标上布置雷,并用一个变量来记录雷的数量,当布置了10个雷后,循环停止,代码如下:

void displaymine(char arr[ass][bss], int a, int b) {
	int count=maxx;
	srand((unsigned)time(NULL));
	
	while (count) {int i = rand()%9+1;
	int j = rand()%9+1;
		if (arr[i][j]!='1') {
			arr[i][j] = '1';
			count--;
		}
	}
}

 2.3.4找雷

当我们布置完雷后,就要开始雷的寻找了,我们设置两个变量i,j给玩家输入想查找的坐标,判断是不是雷,如果是,则踩雷,游戏失败,不是,则返回一个数字,展示周围8个坐标的雷个数,并用while循环重复这一操作,并用一个变量z来进行判断是否循环的条件,这里我们的条件是z=as*bs-maxx,循环一次z--;也就是71次,此时z为0;找到了所有的雷,判断游戏胜利。代码如下:

void foundmine(char arr1[ass][bss], char arr2[ass][bss]) {
	int z =(( as*bs) - maxx);
	int i = 0;
	int j = 0;
	printf("请输入想查看的坐标:x,y");
	while (z ) {

		scanf("%d,%d", &i, &j);
		
			if (arr2[i][j] == '1')
			{
				printf("很遗憾,你踩雷了");
				break;
			}
			else if (arr2[i][j] == '0') {
				arr1[i][j] = count(arr2, i, j) + '0';
				print(arr1, as, bs);

			}
			z--;
		
	}
	if (z == 0)printf("恭喜你,通关了");

}

2.3.5返回雷数量的计算

在玩家输入坐标后,若不是雷,则要返回周围8个格子雷的数量,这个函数也很简单,写一个int型函数来计算要注意的是,我们棋盘里存在的是字符1,我们用周围8个格子里存放的字符数字-字符0,得到的int就是周围8个雷的变量,在将arr1[i][j]=返回的int型数字+字符0,即可转换成字符,并再次打印arr1展示给玩家。代码如下:

int count(char arr2[ass][bss], int i, int j) {

	return arr2[i - 1][j - 1] + arr2[i - 1][j] + arr2[i - 1][j + 1] +
		arr2[i][j - 1] + arr2[i][j + 1] +
		arr2[i + 1][j - 1] + arr2[i + 1][j] + arr2[i + 1][j + 1] - 8 * '0';


}

2.3.6整个扫雷游戏的代码

game.h代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define maxx 10
#define as 9
#define bs 9
#define ass as+2
#define bss bs+2
void initarr(char arr[ass][bss], char x);
void print(char arr[ass][bss], int a, int b); 
void displaymine(char arr[ass][bss], int a, int b);
void foundmine(char arr1[ass][bss], char arr2[ass][bss]);

game.c

#include"game.h"
void initarr(char arr[ass][bss], char x) {
	for (int i = 0; i < ass; i++)
		for (int j = 0; j < bss; j++) {
			arr[i][j] = x;
		}
}
void print(char arr[ass][bss], int a, int b) {
	for (int i = 0; i < 10; i++) {
		printf("%d ", i);
	}
	printf("\n");

	for (int i = 1; i <= as; i++) {
		printf("%d ", i);
		for (int j = 1; j <= bs; j++) {
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}
void displaymine(char arr[ass][bss], int a, int b) {
	int count = maxx;
	srand((unsigned)time(NULL));

	while (count) {
		int i = rand() % 9 + 1;
		int j = rand() % 9 + 1;
		if (arr[i][j] != '1') {
			arr[i][j] = '1';
			count--;
		}
	}
}
int count(char arr2[ass][bss], int i, int j) {

	return arr2[i - 1][j - 1] + arr2[i - 1][j] + arr2[i - 1][j + 1] +
		arr2[i][j - 1] + arr2[i][j + 1] +
		arr2[i + 1][j - 1] + arr2[i + 1][j] + arr2[i + 1][j + 1] - 8 * '0';


}
void foundmine(char arr1[ass][bss], char arr2[ass][bss]) {
	int z =(( as*bs) - maxx);
	int i = 0;
	int j = 0;
	printf("请输入想查看的坐标:x,y");
	while (z ) {

		scanf("%d,%d", &i, &j);
		
			if (arr2[i][j] == '1')
			{
				printf("很遗憾,你踩雷了");
				break;
			}
			else if (arr2[i][j] == '0') {
				arr1[i][j] = count(arr2, i, j) + '0';
				print(arr1, as, bs);

			}
			z--;
		
	}
	if (z == 0)printf("恭喜你,通关了");

}

源.c

#include"game.h"
void game() {
	char arr1[ass][bss];
	char arr2[ass][bss];
	 initarr(arr1, '*');// 初始化棋盘
     initarr(arr2, '0');//初始化棋盘
	 displaymine( arr2,as , bs); //布置雷
	 print(arr1, as, bs);//打印棋盘
	 foundmine(arr1, arr2);//找雷
}


void menu() {
	printf("******1.开始游戏******\n");
	printf("******0.退出游戏******\n");

 }
int main() {int intput;
	do
	{
		menu();
		
		scanf("%d", &intput);
		switch (intput) {
		case 1:game();
			break;
		case 0:printf(" 退出游戏\n");
			break;
		default:
			break;


         }


	} while (intput);
}

 3还可以优化的地方和存在的缺陷

我们都知道平常知道平常我们所玩的扫雷游戏都是有插旗功能的,其次,当我们找寻雷时,若一个地方的雷的个数为0;则这个地方就会出现出现大量的空白,加快游戏速度。这里我们其实可以用递归的方式来实现,其他的地方也会出现一些变动,这里我们先不做介绍,留给下期介绍。希望大家能从这期的扫雷详解中先初步认识和了解扫雷游戏的制作过程。

 

 

  • 33
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言扫雷游戏排行榜是一个用于记录玩家在扫雷游戏中的得分和排名的榜单。在C语言中,我们可以使用数组和结构体来实现这个排行榜。 首先,我们可以创建一个结构体来表示每个玩家的信息,如玩家的姓名和得分。结构体的定义可以像这样: ``` struct Player { char name[20]; int score; }; ``` 然后,我们创建一个数组来存储多个玩家的信息,数组的大小可以根据需要进行调整。例如: ``` struct Player leaderboard[10]; ``` 接下来,我们可以编写函数来实现对排行榜的操作,如添加玩家、更新得分和显示排行榜等。 添加玩家的函数可以接受玩家的姓名和得分,并将其添加到排行榜中。例如: ``` void addPlayer(char name[20], int score) { // 找到排行榜中得分低于当前得分的位置,并将其后的玩家信息依次后移一位 // 将当前玩家信息插入到空出的位置 } ``` 更新得分的函数可以接受玩家的姓名和新得分,并根据姓名找到对应的玩家并更新其得分。例如: ``` void updateScore(char name[20], int newScore) { // 根据姓名找到对应的玩家,并更新其得分 } ``` 最后,我们可以编写显示排行榜的函数,按照得分从高到低的顺序显示玩家信息。例如: ``` void showLeaderboard() { // 对排行榜中的玩家根据得分进行排序,并输出玩家信息 } ``` 以上是用C语言实现扫雷游戏排行榜的基本思路,具体的实现细节可以根据实际需求进行调整和完善。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值