C language minesweeper game detailed explanation

Table of contents

The overall idea of ​​the game

Realization of the main content of the game

1. Store mine location information

2. Initialize minesweeper board information

3. Print the chessboard

4. Lay out mines

5. Check mine

Minesweeper game optimization

Before writing the code, we divide the composition of the game into three parts:
Part 1: Add source files and create test.c for testing game logic.
The second part: add the source file to create game.c, which is used for the realization of the function.
The third part: the header file is added to create game.h, which is used for the declaration of the function.

                                         

When playing a game, the menu interface should be the first thing that catches the eye, so the menu function should be written in our main function, and the menu includes 1.play, 0.exit. When playing a game, you should choose to play the game or quit the game, and use the switch case branch statement to implement it here. The process of playing the game is many times, until you don't want to play and exit the game, use the do while statement here.

Code:  

void menu()
{
	printf("**********************\n");
	printf("******* 1.play *******\n");
	printf("******* 0.exit *******\n");
	printf("**********************\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("please enter options:>\n");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			printf("minesweeper game\n");
			break;
		case 0:
			printf("exit the game\n");
			break;
		default:
			printf("Input errors, please re-enter:>\n");
				break;
		}
	} while (input);
		return 0;
}

The results of the code test run show:

Realization of the main content of the game

1. Store mine location information

Here, we first choose a 9*9 two-dimensional array to store the position information of mine placement. The position of mine is recorded as 1, and the position of no mine is recorded as 0. In addition, a 9*9 two-dimensional array is used to store the information of the detected mines. The positions that have not been checked are all initialized to '*', and the mines detected are recorded as the number of surrounding mines. The rule of our game is generally to check whether there are mines in the remaining 8 squares centered on one square. In order to prevent the array access from crossing the boundary during the investigation, we expand the 9*9 array to an 11*11 array.

2. Initialize minesweeper board information

We hope that all positions of mine's board are initialized to 0; all positions of mine's information are initialized as *. All the two types of chessboards are initialized to the situation of no mine and no mine check.

Code:

void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');

}
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;
		}
	}
}

3. Print the chessboard

In the part of printing the chessboard, it is worth noting that we added two rows and two columns to the rows and columns of the chessboard to avoid array access out of bounds, but when we display the game interface, these two rows and two columns are not used. displayed. More importantly this should represent a 9*9 array on top of the original 11*11 array we initialized earlier.

Code:

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

The results of the code test run show:

One disadvantage of this display chessboard is that if there are more rows and columns, it will be difficult for us to count which row and column we want to scan. Therefore, based on this problem, we have improved the code. The code improvement results are as follows:

Code:

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

The results of the code test run show:

Note: Here we can also add the printing of the chessboard for laying out mine

4. Lay out mines

Arranging mines is carried out on the chessboard where mines are arranged. In principle, we only arrange mines in the 9*9 chessboard, but we still arrange the internal 9*9 mines on the basis of the 11*11 chessboard. This is what we are laying out Ray's process requires attention.

Code :

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	int x = rand() % row + 1;
	int y = rand() % col + 1;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

Code test run results show:

5. Check mine

Same as above, we also check the mines in the 11*11 array, but the mines are stored in the 9*9 chessboard. After that, we will enter the process of mine checking. The process of mine checking is cyclical. We input the coordinates we want to check. If it is a mine, the game will end and jump out of the loop. If it is not a mine, we must continue to count the coordinates. How many mines are there in the surrounding 8 coordinates. In this process, we have to constantly judge whether the coordinates have been checked.

The method of counting the number of mines:

Add the characters represented by the 8 coordinates around x and y and subtract 8 times the character 0, because when we initialize the mine array, the position with mines is placed with character 1, and the position without mines prevents character 0 .

After counting the number of mines, we assign the corresponding characters to the array of information about mines. Afterwards, we have to consider when the thunder has been exhausted? If we set 10 mines in the array, then there are 71 grids that are not mines, so the process of our circular minesweeping is to count the number of mines that are not mines in a loop. When the number of grids that are not mines is equal to 71, minesweeping success!

Code :

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');
}
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 < (col * row) - EASY_COUNT)//not the number of regs
	{
		printf("Please enter the coordinates you want to check:>\n");
		scanf_s("%d", &x);
		scanf_s("%d", &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] == '*')//Coordinates have not been checked
			{
				if (mine[x][y] == '1')
				{
					printf("Game over, you are blown to death!\n");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else if (mine[x][y] == '0')
				{
					//Count the number of mines
					int count = GetMineCount(mine, x, y);
					show[x][y] = count + '0';//Get the character 3 and put it in the demining information array
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("This location has been checked\n");
			}
		}
		else
		{
			printf("Invalid coordinates, please re-enter:>\n");
		}
	}
	if (win == (col * row) - EASY_COUNT)
	{
		printf("Congratulations, successful demining!\n");
		DisplayBoard(mine, ROW, COL);
	}
}

Code test run results show:

Thank you for reading, and welcome everyone to criticize and correct!

Tags: C Algorithm programming language

Posted by phpion on Wed, 18 Jan 2023 23:11:43 +0530