C language minesweeper analysis

Minesweeper function description

• Use the console to realize the classic minesweeper game
• The game can continue to play or exit the game through the menu
• The minesweeper board is a 9*9 grid
• 10 mines are randomly arranged by default
• Mines can be checked
• If the location is not a mine, the surroundings will be displayed How many mines are there
? If the location is a mine, blow it up and the game will end.
• Find all the mines except 10 mines. If the mines are cleared successfully, the game will end.

game interface

insert image description here

Game analysis and design

Analysis of data structures

During the process of mine clearing, the information of the mines laid out and the mines detected need to be stored, so we need a certain data structure to store this information, so we need an array. Since we are designing a 9*9 chessboard, so First of all, we will think of the two-dimensional array arr[9][9] of type char
. When arranging mines, we add the arrangement to store 1, and if not arranged, store 2.
insert image description here
After we arrange the mines, we need to clear the mines. If we When the input coordinates are (6, 3), we need to count whether there are mines around. If there are mines, we need to display the number of mines.
But there is a problem. If we set the input to arr[9][9] , we need to judge that when the array position is near (7,9), the array will go out of bounds ( unless you write out all those situations, which is a bit troublesome )
, so we need to expand the range of the array, that is, the array is set is arr[9+2][9+2]. As shown in the figure below,
insert image description here
we have arranged mines on the chessboard. The information about mines and non-mines on the chessboard. Assume that after we check a certain position, this coordinate is not a mine. This There is 1 mine around the coordinates, then we need to record and store the number of mines detected and print them out as important reference information for mine clearance.
So where is the information about the number of mines stored? If stored in an array where mines are arranged, the mine information and the mine number information may be confused or cause printing difficulties.
Therefore, do not use numbers for the information about mines and non-mines. Just use certain characters. This will avoid conflicts. However, if there is information about mines and non-mines on the chessboard, as well as the information about the number of mines found, it will be more confusing. , not convenient enough.
thenWe specifically give a chessboard (corresponding to an array mine) to store the arranged mine information, and then give another chessboard (corresponding to another array show) to store the detected mine information. In this way, they will not interfere with each other. Arrange mines in the mine array, check for mines in the mine array, store the detected data in the show array, and print the information of the show array for later troubleshooting reference .
At the same time, in order to maintain mystery, the show array is initialized to the character '*' at the beginning. In order to keep the types of the two arrays consistent, the same set of functions can be used. The mine array is also initially initialized to the character '0', and the layout is changed to '1'. '.

char mine[11][11] = {
    
    0};//⽤来存放布置好的雷的信息
char show[11][11] = {
    
    0};//⽤来存放排查出的雷的个数信息

File structure design

test.c //⽂件中写游戏的测试逻辑
game.c //⽂件中写游戏中函数的实现等
game.h //⽂件中写游戏需要的数据类型和函数声明等

Implementation of minesweeper game code

game.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define EASY_COUNT 10
#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 set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

game.c

Initialize the array

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

Print chessboard

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    
    
	int i = 0;
	printf("********* 扫雷游戏 *********\n");
	for (i = 0; i <= col; i++)
	{
    
    
		if (0 < i && i <= col - 1)
			printf("——");
		else if (i == 0)
			printf(" ");
		else
			printf("——>x轴");
	}
	printf("\n");
	for (i = 0; i <= col; i++)
	{
    
    
		if (i == 0)
			printf("  0 ");
		else
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row+3; i++)
	{
    
    
		if (i <= row - 1)
			printf("|");
		else if (i == row)
			printf("|");
		else if (i == row + 1)
			printf("V\n");
		else if (i == row + 2)
			printf("y");
		else
			printf("轴\n");
		if (i <= row)
		{
    
    
			printf(" %d ", i);
			int j = 0;
			for (j = 1; j <= col; j++)
			{
    
    
				printf("%c ", board[i][j]);
			}
			printf("\n");
		}
	}
}

Lay out mines

void SetMine(char board[ROWS][COLS], int row, int col)
{
    
    
	//布置10个雷
	//⽣成随机的坐标,布置雷
	int count = EASY_COUNT;
	while (count)
	{
    
    
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
    
    
			board[x][y] = '1';
			count--;
		}
	}
}

Count the number of mines around you

int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
    
    
	return (mine[x-1][y-1] + mine[x - 1][y ] + mine[x - 1][y +1] + mine[x ][y - 1] + mine[x ][y +1] + mine[x + 1][y - 1] + mine[x + 1][y ] +mine[x+1][y+1] - 8 * '0');
}

Determination of investigation results

void FindMine(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 - EASY_COUNT)
	{
    
    
		printf("请输入要排查的坐标:>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
    
    
			if (mine[y][x] == '1')
			{
    
    
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
    
    
				//该位置不是雷,就统计这个坐标周围有⼏个雷
				int count = GetMineCount(mine, x, y);
				show[y][x] = '0' + count;
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
    
    
			printf("坐标非法,重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
    
    
		printf("恭喜你,排雷成功\n");
		DisplayBoard(mine, ROW, COL);
	}
}

test.c

void menu()
{
    
    
	printf("***********************\n");
	printf("******* 1. play *******\n");
	printf("******* 0. exit *******\n");
	printf("***********************\n");
}
void game()
{
    
    
	char mine[ROWS][COLS];//存放布置好的雷
	char show[ROWS][COLS];//存放排查出的雷的信息
	//初始化棋盘
	//1. mine数组最开始是全'0'
	//2. show数组最开始是全'*'
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//打印棋盘
	//DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
	//1. 布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);
	//2. 排查雷
	FindMine(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;
}

Guess you like

Origin blog.csdn.net/2301_79178723/article/details/132596545