扫雷游戏的简单实现(C语言)

在编辑代码前,我们使用多文件的形式实现,创建三个文件
test.c: 扫雷游戏的测试
game.h :扫雷游戏功能函数的声明
game.c :扫雷游戏功能函数的定义

一、游戏菜单选择

1.首先进入游戏要有菜单作为信息提示(1.进入游戏/0.退出游戏),然后输入选择项并判断。而我们每次玩完游戏时,如果觉得不过瘾,想再来一局,我们希望能够再次出现菜单Menu进行选择,这是就需要使用do-while循环实现此需求。我们使用自定义text函数存放这些信息。

void Menu()
{
	printf("     Menu    \n");
	printf("-------------\n");
	printf("-  1.Play   -\n");
	printf("-------------\n");
	printf("-  0.Exit   -\n");
	printf("-------------\n");
}

void test()
{
	int input = 0;
	printf("欢迎来到扫雷\n");
	do
	{
		Menu();//打印菜单
		printf("请输入>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//进入游戏
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入(1/0)\n");
		}

	} while (input);
}


int main()
{
	srand((unsigned int)time(NULL));//产生随机数用以布置随机雷的坐标
	test();
	return 0;
}

二、创建扫雷棋盘

用两个二维数组实现:
Mine:存放雷和非雷的信息
Show:存放某坐标周围雷的个数
常见的扫雷游戏以9*9棋盘的形式实现,我们可以使用9行(ROW)9列(COL)的二维数组替代棋盘。

#define ROW 9
#define COL 9

在创建数组的数和列数时需要注意,当我们在数组中布置好雷的位置后,需要在某个位置排查周围雷的个数,如果这个位置在最外围,那么在排查雷的时候,会出现溢出的情况
在这里插入图片描述
为避免这种情况,可以创建11行(ROWS)11(COLS)的数组防止排查时溢出。

#define ROWS ROW+2
#define COLS COL+2

我们希望Show数组只用来展示周围雷的个数,初始值全为 '*’ ,所以我们将其初始化为char型数组,在Mine数组中我们定义‘1’表示是雷,‘0’表示非雷,所以我们干脆将其都定义为char,且大小相同,都为11(ROWS)*11(COLS)。

//使用两个字符数组实现两个棋盘
char Mine[ROWS][COLS] = { 0 };//存放显示雷和非雷的信息
char Show[ROWS][COLS] = { 0 };//存放显示非雷坐标周围雷的个数

三、打印棋盘

game.h中声明

void SweepMine(char Mine[ROWS][COLS], char Show[ROWS][COLS]);//打印棋盘

game.c中定义

void PrintBoard(char board[ROWS][COLS])
{
	int i = 0;
	int j = 0;
	printf("--------扫雷--------\n");
	
	for (int n = 0; n <= COL; n++)
	{
		printf("%d ", n);//打印列的坐标
	}
	printf("\n");
	for (i = 1; i <= ROW; i++)
	{
		printf("%d ", i);//打印行的坐标
			for (j = 1; j <= COL; j++)
			{
				printf("%c ", board[i][j]);//打印棋盘
			}
			printf("\n");
	}
}

test.c中调用

//打印棋盘
PrintBoard(Mine);

四、初始化棋盘

game.h中声明

//棋盘初始化
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret);

game.c中定义

void InitBoard(char board[ROWS][COLS],int rows,int cols,char ret)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

test.c中调用

//棋盘初始化
InitBoard(Mine, ROWS, COLS, '0');
InitBoard(Show, ROWS, COLS, '*');

五、随机布置雷

1.随机产生10个不重复的雷的坐标,并放入Mine数组中。
game.h中声明:

void SetMine(char board[ROWS][COLS]);//产生随机10个雷,布置这10个雷

game.c中定义

void SetMine(char board[ROWS][COLS])
{
	int count = 0;//随机雷个数
	while (count != 10)
	{
		int x = rand() % ROW + 1;//产生随机数用以布置随机雷的坐标
		int y = rand() % COL + 1;//横、纵坐标范围1~9
	
		if (board[x][y] != '1')//保证产生10个不重复的随机雷,位置坐标不同
		{
			board[x][y] = '1';
			count++;
		}
	}

}

六、排查雷

game.h中声明

void SweepMine(char Mine[ROWS][COLS], char Show[ROWS][COLS]);//排查雷

game.c中定义

void SweepMine(char Mine[ROWS][COLS], char Show[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int k = 0;
	int count = ROW*COL-10;//非雷的个数
	while (k<count)//直到排查出所有的非雷,循环结束
	{
		scanf("%d %d", &x, &y);//输入坐标
		if (x >= 1 && x <= ROW && y >= 1 && y<= COL)
		{
			if (Mine[x][y] == '1')
			{
				printf("很遗憾,你踩雷了\ngame over\n");
				printf("下方为 雷 的位置图\n");
				PrintBoard(Mine);
				break;
			}
			else
			{
				k++;
				Print(Show,Mine,x,y);//打印周围雷的个数
			}
		}
		else
		{
			printf("输入错误,请重新输入x(1~9),y(1~9)\n");
		}

	}
	if(k==count)//代表排查出了所有雷
	printf("恭喜你,排查出所有雷\n");

	
}

未触雷显示周围雷的个数
打印周围雷个数的函数Print
game.c中Print函数的声明

Print(Show,Mine,x,y);

game.c中Print函数的定义

void Print(char Show[ROWS][COLS], char Mine[ROWS][COLS],int x,int y)
{
	//周围雷的个数 整型整数-'0'变为字符型  字符型+'0'变为整型
	int MineCount = Mine[x-1][y-1]
		+ Mine[x-1][y]
		+ Mine[x-1][y+1]
		+ Mine[x][y-1]        //这些坐标为周围的坐标,包括自身坐标
		+ Mine[x][y]          //因为此时输入坐标对应的数组元素为'0',
		+ Mine[x][y+1]     //所以加上自身的‘0’,并不会影响周围雷个数的计算
		+ Mine[x+1][y-1]
		+ Mine[x+1][y]
		+ Mine[x+1][y+1]-9*'0';
	Show[x][y] = MineCount + '0';
	PrintBoard(Show);
}

七、完整代码

game.h

#pragma once
#include<stdio.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2 
#define COLS COL+2
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ret);
//打印棋盘
void PrintBoard(char board[ROWS][COLS]);
//产生随机10个雷,布置这10个雷
void SetMine(char board[ROWS][COLS]);
//排查雷
void SweepMine(char Mine[ROWS][COLS], char Show[ROWS][COLS]);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void InitBoard(char board[ROWS][COLS],int rows,int cols,char ret)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

void PrintBoard(char board[ROWS][COLS])
{
	int i = 0;
	int j = 0;
	printf("--------扫雷--------\n");
	for (int n = 0; n <= COL; n++)
	{
		printf("%d ", n);
	}
	printf("\n");
	for (i = 1; i <= ROW; i++)
	{
		printf("%d ", i);
			for (j = 1; j <= COL; j++)
			{
				printf("%c ", board[i][j]);
			}
			printf("\n");
	}
}

void SetMine(char board[ROWS][COLS])
{
	int count = 0;
	while (count != 10)
	{
		int x = rand() % ROW + 1;
		int y = rand() % COL + 1;
	
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count++;
		}
	}

}

void Print(char Show[ROWS][COLS], char Mine[ROWS][COLS],int x,int y)
{
	//周围雷的个数 整型整数-'0'变为字符型  字符型+'0'变为整型
	int MineCount = Mine[x-1][y-1]
		+ Mine[x-1][y]
		+ Mine[x-1][y+1]
		+ Mine[x][y-1]
		+ Mine[x][y]
		+ Mine[x][y+1]
		+ Mine[x+1][y-1]
		+ Mine[x+1][y]
		+ Mine[x+1][y+1]-9*'0';
	Show[x][y] = MineCount + '0';
	PrintBoard(Show);
}


void SweepMine(char Mine[ROWS][COLS], char Show[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int k = 0;
	int count = ROW*COL-10;
	while (k<count)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= ROW && y >= 1 && y<= COL)
		{
			if (Mine[x][y] == '1')
			{
				printf("很遗憾,你踩雷了\ngame over\n");
				printf("下方为 雷 的位置图\n");
				PrintBoard(Mine);
				break;
			}
			else
			{
				k++;
				Print(Show,Mine,x,y);
			}
		}
		else
		{
			printf("输入错误,请重新输入x(1~9),y(1~9)\n");
		}

	}
	if(k==count)
	printf("恭喜你,排查出所有雷\n");

	
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"


void Menu()
{
	printf("     Menu    \n");
	printf("-------------\n");
	printf("-  1.Play   -\n");
	printf("-------------\n");
	printf("-  0.Exit   -\n");
	printf("-------------\n");
}



void game()
{
	//使用两个字符数组实现两个棋盘
	char Mine[ROWS][COLS] = { 0 };//存放显示雷和非雷的信息
	char Show[ROWS][COLS] = { 0 };//存放显示非雷坐标周围雷的个数

	//棋盘初始化
	InitBoard(Mine, ROWS, COLS, '0');
	InitBoard(Show, ROWS, COLS, '*');

	//打印棋盘
	PrintBoard(Mine);
	//PrintBoard(Show);

	//产生随机10个雷,布置这10个雷
	SetMine(Mine);

	//排查雷
	SweepMine(Mine,Show);


}



void test()
{
	int input = 0;
	printf("欢迎来到扫雷\n");
	do
	{
		Menu();//打印菜单
		printf("请输入>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			break;
		default:
			printf("输入错误,请重新输入(1/0)\n");
		}

	} while (input);
}




int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}
  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值