C实现简单扫雷

目录

  • 前言
  • 分模块
  • 总结


前言

扫雷很经典的游戏了,具体玩法就不在赘述,本篇是简易实现一下扫雷游戏。


分模块

为了方便增删查改需要把代码分模块管理。

1.game.h \\头文件,游戏代码的声明(函数声明、符号定义)
2.game.c \\游戏代码的实现
3.test.c \\测试游戏逻辑


还是把最基本的逻辑写一下,首先至少玩一把,上来就需要打印个菜单(1玩0退出),用do while循环,并且做相应的提示(菜单)让玩家选择,仔根据做出的选择做出响应,这时可以使用switch语句来实现:

void menu()
{
	puts("************************");
	puts("******   1.play   ******");
	puts("******   0.exit   ******");
	puts("************************");
}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		menu();
		printf("请输入选项:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:		
			game();
			break;
		case 0:
			puts("Exit the game!");
			break;
		default:
			puts("input again!");
		}
	} while (input);
	return 0;
}

效果无误,在case 1中封装game()函数来实现游戏功能:

void game()
{
	char mine[ROWS][COLS] = { 0 }; 
	//布置雷的数组
	char show[ROWS][COLS] = { 0 };
	//存放排查出雷的信息

	//初始化两个数组为指定的内容
	//mine数组在没有布置雷使初始化为'0'
	initBoard(mine, '0');

	//show数组在没有排查雷的时候初始化为*
	initBoard(show, '*');
	
	//打印雷盘信息
	//displayboard(mine);
	//打印展示给玩家的信息
	displayboard(show);
}

扫雷需要两个数组,一个是用来存放雷,另一个是把雷隐藏起来的页面,把第二个数组输出来供玩家使用:

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

C实现简单扫雷_第1张图片
上面只是测试代码有没有问题,实际上是不需要打印雷盘信息的,只需要打印给玩家第二个看就可以了。

紧接着需要在面板上设置雷了:
随机生成雷的坐标,只要对应的坐标是空,就设置。

void mineSet(char board[ROWS][COLS], int row, int col)
{
	int mines = MINES;
	while (mines)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			mines--;
		}
	}
}

生成雷图:
C实现简单扫雷_第2张图片

ps:别忘了把雷隐藏,只打印玩家信息图

雷布置好后,接下来就是排查九宫格中雷的数量,并显示在当前坐标上,如何计算当前坐标雷的数量呢?

只需要找到周围八个坐标的下标,判断是否等于’1’
,如果相等就+1,最后把结果返回去,就是雷的数量:
C实现简单扫雷_第3张图片

//把页面和排查的坐标作为参数
int countMine(char mine[ROWS][COLS], int i, int j)
{
	int sum = 0;
	for (int x = -1; x <= 1; x++)
	{
		for (int y = -1; y <= 1; y++)
		{
			if (mine[x+i][y+j] == '1')
			{
				sum++;
			}
		}
	}
	return sum;
}

因为是输出的是字符,所以加上’0’的ASCII码值的结果就是那个数字字符了。

void searchMines(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 - MINES)
	{
		printf("请输入坐标:");											 
		scanf("%d %d", &x, &y);
		if (x > 0 && x < 10 && y>0 && y < 10)
		{
			if (show[x][y] != '*')
			{
				puts("此坐标已被排查!");
			}
			else
			{
				if (mine[x][y] == '1')
				{

					puts("\n你被炸死了!");
					displayboard(mine);
					break;
				}
				else
				{
					//只要成功下棋就增加一步
					win++;
					//统计mine数组中xy坐标周围八个格子里有几个雷
					show[x][y] = countMine(mine, x, y) + '0';
					displayboard(show);
				}
			}
			
		}
		else
		{
			puts("非法坐标,重新输入!");
		}
	}
	if (win == row * col - MINES)
	{
		puts("\n游戏胜利!");
		displayboard(mine);
	}
}

C实现简单扫雷_第4张图片
这样循环就一次次的走起来了。

游戏结束的条件是,那这个9*9的格子来说,当走的次数等于row乘以col-雷的数量时,说明已经雷已经被排查完,游戏结束,因此循环判断条件是row * col - MINES。

test.c:

#include "game.h"

void menu()
{
	puts("************************");
	puts("******   1.play   ******");
	puts("******   0.exit   ******");
	puts("************************");
}

void game()
{
	char mine[ROWS][COLS] = { 0 }; 
	//布置雷的数组
	char show[ROWS][COLS] = { 0 };
	//存放排查出雷的信息

	//初始化两个数组为指定的内容
	//mine数组在没有布置雷使初始化为'0'
	initBoard(mine, '0');

	//show数组在没有排查雷的时候初始化为*
	initBoard(show, '*');

	//设置雷
	mineSet(mine, ROW, COL);

	//打印雷盘信息
	displayboard(mine);
	//打印展示给玩家的信息				    
	displayboard(show);

	//排查雷数
	searchMines(mine, show, ROW, COL);

}

int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do
	{
		menu();
		printf("请输入选项:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:		
			game();
			break;
		case 0:
			puts("Exit the game!");
			break;
		default:
			puts("input again!");
		}
	} while (input);
	return 0;
}

game.c:

#include "game.h"

//初始化
void initBoard(char board[ROWS][COLS], char set)
{
	for (int i = 0; i < ROWS; i++)
	{
		for (int j = 0; j < COLS; j++)
		{
			board[i][j] = set;
		}
	}	
}

//打印数据
void displayboard(char board[ROWS][COLS])
{
	puts("---------扫雷--------");
	printf("   ");
	for (int i = 1; i < 10; i++)
	{		
		printf("%d ", i);
	}										   
	printf("\n");
	puts("   -----------------");
	for (int i = 1; i <= ROW; i++)
	{
		printf("%d ", i);
		printf("|");
		for (int j = 1; j <= COL; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
     }
	puts("\n---------扫雷--------");
}
	
//设置雷
void mineSet(char board[ROWS][COLS], int row, int col)
{
	int mines = MINES;
	while (mines)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			mines--;
		}
	}
}


void boom(char show[ROWS][COLS], int i, int j)
{
	for (int x = -1; x <= 1; x++)
	{
		for (int y = -1; y <= 1; y++)
		{
			show[x + i][y + j] = ' ';
		}
	}
}

int countMine(char mine[ROWS][COLS], int i, int j)
{
	int sum = 0;
	for (int x = -1; x <= 1; x++)
	{
		for (int y = -1; y <= 1; y++)
		{
			if (mine[x+i][y+j] == '1')
			{
				sum++;
			}
		}
	}
	return sum;
}
//排查雷
void searchMines(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 - MINES)
	{
		printf("请输入坐标:");											 
		scanf("%d %d", &x, &y);
		if (x > 0 && x < 10 && y>0 && y < 10)
		{
			if (show[x][y] != '*')
			{
				puts("此坐标已被排查!");
			}
			else
			{
				if (mine[x][y] == '1')
				{

					puts("\n你被炸死了!");
					displayboard(mine);
					break;
				}
				else
				{
					win++;
					//统计mine数组中xy坐标周围八个格子里有几个雷	
					char c = countMine(mine, x, y) + '0';
					if (c == '0')
					{
						void boom(show, x, y);
					}
					show[x][y] = c;

					displayboard(show);
				}
			}
			
		}
		else
		{
			puts("非法坐标,重新输入!");
		}
	}
	if (win == row * col - MINES)
	{
		puts("\n游戏胜利!");
		displayboard(mine);
	

game.h:

#include 
#include 
#include 

#define ROWS 11
#define COLS 11

#define ROW ROWS-2
#define COL COLS-2

#define MINES 10

//初始化数组
void initBoard(char board[ROWS][COLS], char set);

//显示数组
void displayboard(char board[ROWS][COLS]);

//布置雷
void mineSet(char board[ROWS][COLS], int row, int col);

//排查雷
void searchMines(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

总结

以上就是扫雷的简易实现,很多功能待完善,待我在研究研究!

你可能感兴趣的:(c语言,c语言,c++)