【c语言】函数 + 数组 = 扫雷游戏

game.h(头文件):

//.h文件通常存放:函数声明,定义的常量

#include <time.h>//要用到随机数
#include <stdlib.h>//要用到随机数
#include <windows.h>//要清理屏幕

//定义常量避免到处修改
#define ROW 9
#define COL 9
#define ROWS ROW+2//避免越界
#define COLS COL+2//避免越界

//菜单函数
void menu();

//初始化棋盘函数
void set(char a[ROWS][COLS], int rows, int cols, char b);

//布置地雷函数
void setMine(char a[ROWS][COLS], int rows, int cols);

//打印棋盘函数
void showBoard(char a[ROWS][COLS], int row, int col);

//计算地雷个数函数
int count(char a[ROWS][COLS],int m,int n);

game.c(函数实现文件):


#include "game.h"//包含函数声明,定义的常量
#include <stdio.h>

//菜单函数
void menu()
{
	printf("**********************************\n");
	printf("*******      1 play        *******\n");
	printf("*******      0 exit        *******\n");
	printf("**********************************\n");
}

//实现扫雷游戏的主要逻辑在这个函数
void game()
{
	
	char Board[ROWS][COLS];//玩家看到的雷区
	char Mine[ROWS][COLS];//布好的地雷放在这个数组

	//初始化棋盘
	set(Board, ROWS, COLS, '*');

	//初始化地雷
	set(Mine, ROWS, COLS, '0');

	//布置地雷
	setMine(Mine, ROW, COL);

	printf("------扫雷游戏-------\n");

	//展示棋盘
	showBoard(Board, ROW, COL);

	//可以边写边测,不要把所有代码写完再调试,“coding一时爽,调试火葬场”
	//可以对照生成的地雷来测试
	//showBoard(Mine, ROW, COL);

	//让玩家先输入一维(纵),再输入二维(横)
	printf("请输入要排查的坐标:(先纵后横)");


	int m = 0;
	int n = 0;
	while (1)//死循环的排查,直到踩雷
	{
		scanf("%d %d", &m, &n);//m 横 n 纵

		//玩家万一输错坐标
		if (m < 1 || m>ROW || n < 1 || n>ROW)
		{
			printf("坐标有误,请重新输入:");
			continue;
		}

		//玩家输入已排查的坐标
		if (Board[m][n] != '*')
		{
			printf("这个位置已经排查过了,请重新输入坐标:");
			continue;
		}

		//玩家踩雷了
		if (Mine[m][n] == '1')
		{
			system("cls");
			printf("你被炸死了,地雷排布如下(1是地雷):\n");
			//把地雷展示给玩家
			showBoard(Mine, ROW, COL);
			break;
		}

		//玩家没踩雷,要显示玩家输入的坐标附近的地雷数量
		else
		{
			system("cls");
			int r;

			//count函数:计算排查的坐标附近的地雷数量,并赋值给r
			r = count(Mine, m, n);
			
			//棋盘数组是字符型数组,比如要显示字符‘3’,'0'+r可以表示3的ASCII值
			Board[m][n] = '0'+r;

			//把排查后的棋盘展示给玩家,供玩家决策
			printf("------扫雷游戏-------\n");
			showBoard(Board, ROW, COL);
			printf("请输入要排查的坐标:(先纵后横)");
		}
	}
	
}

//初始化棋盘函数
void set(char a[ROWS][COLS], int rows, int cols, char b)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			 a[i][j] = b;
		}
	}
}

//布置地雷函数
void setMine(char a[ROWS][COLS], int row, int col)
{
	//一共布置10个地雷
	int count = 10;

	do {
		int m = rand() % row + 1;//棋盘是9*9大小,所以要生成1-9的随机数
		int n = rand() % row + 1;
		
		//生成的随机数可能会重复
		if (a[m][n] == '1')
		{
			continue;
		}

		//用‘1’表示地雷
		a[m][n] = '1';

		//成功布雷后使count减一
		count--;

	} while (count);//直到count==0,就不再布雷
}

//打印棋盘函数
void showBoard(char a[ROWS][COLS], int row, int col)
{

	//提醒玩家
	printf("  横");

	//打印横坐标
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
	}

	printf("\n"); //横坐标与棋盘有一定距离(为了美观)
	printf("\n");
	printf("纵");
	printf("\n");

	for (int i = 1; i <= row; i++)
	{
		//每次打印一行棋盘前,打印纵坐标
		printf("%d", i);

		//纵坐标与棋盘有一定距离(为了美观)
		printf("   ");

		for (int j = 1; j <= col; j++)
		{
			printf("%c ", a[i][j]);
		}

		//打印一行棋盘后,注意换行
		printf("\n");
	}
}

//计算地雷个数函数
int count(char a[ROWS][COLS],int m,int n)
{

	//返回值是地雷个数的ASCII码值,用%c打印
	return a[m - 1][n - 1] +
		   a[m - 1][n] + 
		   a[m - 1][n + 1] + 
		   a[m][n - 1] + 
		   a[m][n + 1] + 
		   a[m + 1][n - 1] + 
		   a[m + 1][n] + 
		   a[m + 1][n + 1] - 8 * '0';
}

test.c(主函数):

#include <stdio.h>
#include "game.h"
int main()
{
	int input;
	srand((unsigned int)time(NULL));//随机生成随机数的种子,
	                                //放在主函数的原因是:不能
	                                //短时间多次生成,否则随机性
	                                //会降低
	do
	{
		menu();//调用菜单函数,打印菜单
		printf("请选择---->");
		scanf("%d", &input);
		system("cls");
		switch (input)
		{
		case 0:printf("已退出游戏\n"); break;
		
		case 1:game(); break;
		
		default:printf("输入错误,请重新输入\n"); break;
		}
	} while (input);
		return 0;
}

运行示例:

 

待改进的地方:

1、用函数递归实现连片排查

2、难度选择

3、地雷标记

4、胜利条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值