c语言扫雷游戏运行思路及源代码

ps

本次文章代码采用的多文件函数的声明和定义的形式,即函数的声明、类型的声明放在头文件中(.h)中,函数的实现放在(.c)文件中

扫雷游戏的分析和设计

1.扫雷游戏功能说明
*玩家可以通过菜单实现继续玩或者退出游戏
扫雷的棋盘是99的格子**随机布置10个雷
排查雷
**如果排查的位置不是雷,显示周围雷的个数
**如果位置是雷,游戏结束
**把所有非雷的位置找出来,排雷成功,游戏结束
该游戏的界面
在这里插入图片描述
2.扫雷的过程中,布置雷和存储雷的信息都需要存放在棋盘上,假设布置雷的符号为 1,没有布置雷的位置存放 0,当我们排查最外层的雷时,按理说会访问该位置周围一圈的位置,但是会造成数组越界,怎么办呢?这是我们把布置雷的棋盘扩大一圈,这样就解决了数组越界的问题,所以把棋盘创建成11
11的数组。

3.上面我们说到把雷的位置设为 1,不是雷的位置设为 0,但如果我们排查的位置周围有1个雷,这样在棋盘上不也显示1,就会分不清楚1是雷还是表示周围雷,怎么办呢?我们创建两个棋盘,一个专门存放布置雷的信息,一个专门用来排查雷和显示雷周围的信息。这样避免在一个棋盘上的实现功能相互冲突的问题。

文件结构设计

test.c // 该文件是写游戏的逻辑
game.h //该文件是写游戏中函数的声明,头文件等
game.c //该文件是写游戏需要的函数具体的实现

test.c

首先主函数里面先打印菜单,供玩家选择,选择 1 开始游戏,0 退出游戏,选择其他 重新输入。要实现这样的功能应选择do-while语句,不管三七二十一先打印菜单,再选择。

int main()
{
 int input = 0;//在这里创建input的原因是do-while中条件设为input选择1和其他数
 时就又跳到上面重新选择,选择 0 时条件为假,退出循环
 do
 {
 	menu();
 	printf("请选择:- >");
 	scanf("%d",&input);
 	switch(input)
 	{
 		case 1:
 		
 			game();
			break;
		
		case 0:
		
			printf("退出游戏\n");
			break;
		
		default :
		
			printf("选择错误,请重新输入\n");
			break;
	} 		
}while(input);
return 0;
}

接下来写menu()和game()的函数
在这里插入图片描述

game.c

创建两个11*11的棋盘,一个初始化全是0,用来存放雷和布置雷,一个全是 * 供玩家排查雷。
其中棋盘为啥用ROWS和COLS呢?,这是为了方便以后可以修改棋盘的大小,已经在头文件game.h中声明了
实现初始化棋盘
在这里插入图片描述

在这里插入图片描述
要想看看实现效果如何,接下来打印棋盘
在这里插入图片描述
在这里插入图片描述
第一个for循环是用来打印标号,方便玩家快速定位,第二个for循环打印每一行的开头标号,然后再打印数组。
接下来布置雷
在这里插入图片描述
在这里插入图片描述
这里布置的雷是随机布置10个雷,所以用到库函数rand()//生成随机数,不过要先调用srand(),ps:已经在主函数处调用。%row 随机生成0~ 8的随机数,再加1随机生成1~ 9的数。
然后再实现排雷函数
在这里插入图片描述
在这里插入图片描述
这里得到周围雷的个数还可以用循环来遍历,具体用法如下:
在这里插入图片描述
这里为啥要减 ’ 0 '呢?,这里我们在二维数组中布置的全是字符0和字符1,是char类型,而要统计周围雷的个数是int类型,所以要转换,字符0的ASCII是48,而字符1的ASCII码值是49,两者相减就得到了数字1.

结尾

这样一个基本的扫雷游戏就完成了,如果大家有不理解的或者有更精进的方法可以在评论区和我讨论哈。

源代码

//game.h
#pragma once
# include <stdio.h>
# define ROW 9
# define COL 9
# define ROWS ROW + 2
# define COLS COL + 2
# define bomb 10
# include <time.h>
# include <stdlib.h>
void init_board(char mine[ROWS][COLS], int rows, int cols, char set);
void print_board(char mine[ROWS][COLS], int rows, int cols);
void set_mine(char mine[ROWS][COLS], int row, int col);
void find_show(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

//game.c
#define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void init_board(char mine[ROWS][COLS], int rows, int cols, char set)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			mine[i][j] = set;
		}
		printf("\n");
	}
}
void print_board(char mine[ROWS][COLS], int row, int col)
{
	printf("--------扫雷游戏-------\n");
	for (int i = 0; i <= col; 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 ", mine[i][j]);
		}
		printf("\n");
	}
}
void set_mine(char mine[ROWS][COLS], int row, int col)
{
	int count = bomb;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

int get_bomb(char mine[ROWS][COLS], 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 + 1] + 
		mine[x][y + 1] + 
		mine[x - 1][y + 1] +
		mine[x + 1][y]- 8 * '0');
}
void find_show(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row * col - bomb)
	{
		printf("请输入要排查雷的坐标:->");
			scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("被炸死了,你个废物\n");
				print_board(mine, ROW, COL);
				break;
			}
			else
			{
				int count = 0;
				count = get_bomb(mine, x, y);
				show[x][y] = count + '0';
				print_board(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标不对,你个废物,重新输入\n");
		}
	}
	if (win == row * col - bomb)
	{
		printf("排雷成功\n");
		print_board(mine, ROW, COL);
	}
}
//test.c
#define _CRT_SECURE_NO_WARNINGS
# include "game.h"
void menu()
{
	printf("****************\n");
	printf("*****1.play*****\n");
	printf("*****0.exit*****\n");
	printf("****************\n");
}
void game()
{
	//创建棋盘
	char mine[ROWS][COLS];//布置雷
	char show[ROWS][COLS];//排查雷
	//初始化棋盘
	init_board(mine, ROWS, COLS, '0');
	init_board(show, ROWS, COLS, '*');
	//打印棋盘
	//print_board(mine, ROW, COL);
	print_board(show, ROW, COL);
	//布置雷
	set_mine(mine, ROW, COL);
	//排查雷
	find_show(mine, show, ROW, COL);
}
int main()
{
	//打印界面
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default :
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Filex;

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

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

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

打赏作者

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

抵扣说明:

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

余额充值