C language game minesweeping [simple implementation]

Posted by peterjoel on Sun, 20 Feb 2022 14:44:04 +0100

preface

Mine sweeping game is to place a certain number of mines in a chessboard. Players can constantly eliminate mines to realize mine sweeping. If there is no mine nearby, they can eliminate a piece of chess pieces without mine nearby. If they encounter mine, the game will fail. If there is only mine left on the chessboard, mine clearing will succeed.

If you haven't played mine sweeping, you can click here to experience it: mine clearance

Achieve goals

The final implementation style is as follows (which can be further improved according to their own needs):

Minesweeping video demonstration

Implementation steps

Print menu

Provides options for players to choose whether to start or exit the game

void menu(void)
{
	printf("***********************\n");
	printf("***** 1,Start the game *****\n");
	printf("***** 0,Exit the game *****\n");
	printf("***********************\n");
}

Initialize chessboard

When arranging the chessboard, we need to create two chessboards, that is, two-dimensional arrays. Because we need to hide the thunder when sweeping the thunder, we can't let the players see it, and we can't change the position of the thunder, so we create two chessboards, one for storing the thunder (Thunder board for short) and the other for displaying it. We can print the chessboard according to the information of the thunder board. First, you need to initialize the chessboard, initialize all thunder boards to the character '0', and initialize all chessboards to '*'.

void init_board(char board[ROWS][COLS], int row, int col, char ch)  //ch is used to control the style of chess pieces
{  
	for (int i = 0; i < row; i++)    
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ch;    //Initializes all elements in a two-dimensional array to
		}
	}
}

Lay thunder

The random number function Rand needs to be used to realize the random arrangement of mines when arranging mines. The function srand needs to be called before using rand function, and the timestamp function time needs to be used when using srand. This with tic-tac-toe Chinese computer chess is the same.

void init_mine(char board[ROWS][COLS], int row, int col)
{
	int count = COUNT_MINE;		//Custom mine number
	do {
		int x = (rand() % 9) + 1;		//Control the generation position of mine
		int y = (rand() % 9) + 1;		
		if (board[x][y] == '0')			//Judge whether the current position is a mine. If it is a mine, arrange a mine
		{
			board[x][y] = '1';
			count--;
		}
	} while (count);
}

Print chessboard

Print out all the checkerboards, and use some symbols to separate them, so as to facilitate the division of branches and columns. This step needs to be carried out after each minesweeping

void print(char board[ROWS][COLS], int row, int col)
{
	for (int i = 0; i <= ROW; i++) 		//Number of print columns
	{
		printf("%d   ", i);
	}
	printf("\n");
	printf("----------\n");		//Split between rows
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);				//Number of print columns
		for (int j = 1; j <= col; j++)
		{
			printf("| %c ", board[i][j]);		//Split between columns
		}
		putchar('|');
		printf("\n");
		printf("----------\n");
	}
}

Determine whether to continue the game

If the current position is Lei, end the game immediately.

char is_continue(char board[ROWS][COLS], int row, int col)
{
	if (board[row][col] == '1')		//Judge whether the current position is mine
		return '1';
	else
		return '0';
}

Calculate the number of nearby mines

If the current position is not mine, the number of nearby mines will be displayed.

char count_mine(char board[ROWS][COLS], int row, int col)
{
	char count = '0';
	for (int i = row - 1; i <= row + 1; i++)
	{
		for (int j = col - 1; j <= col + 1; j++)
		{
			if (board[i][j] == '1')		//Judge whether the current position is thunder
				count++;		//count
		}
	}
	return count;
}

Recursive expansion [key and difficult points]

If there are no mines in the current position and there are no mines in the nearby positions, you can use recursion to expand these positions. When recursing, you should pay attention to: it cannot exceed the boundary of the chessboard, and this position cannot be thunder. When recursing, you need to judge these two conditions first, and then recurse after meeting these two conditions.

void spread_board(char put_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col)
{
	if (row == 0 || col == 0 || row > ROW || col > COL) 	//Judge whether the boundary is exceeded
		return;
	if (show_board[row][col] != '*') 		//Judge whether the current position is thunder
		return;
	char count = count_mine(put_board, row, col);	  //Calculate the number of mines near the current position
	show_board[row][col] = count;		//open
	if (count == '0')
	{
		for (int i = row - 1; i <= row + 1; i++)
		{
			for (int j = col - 1; j <= col + 1; j++)
			{
					spread_board(put_board, show_board, i, j);	 //Recursive expansion
			}
		}
	}
}

Judge whether minesweeping is successful

If the number of unchecked on the chessboard is greater than the number of thunder, then continue the game. If it is equal to the number of thunder, then the minesweeping is successful!!! (this step can also be used to verify the correctness of the code) so at this time, you only need to traverse the chessboard and calculate the number that has not been checked.

int is_discion(char board[ROWS][COLS], int row, int col)
{
	int count = 0;
	for (int i = 1; i <= row; i++)
	{
		for (int j = 1; j <= col; j++)
		{
			if (board[i][j] == '*')			//Judge whether the current location has been checked
			{
				count++;			//count
			}
		}
	}
	return count;
}

source code

If you don't know anything about mine sweeping, you can refer to the code here: mine clearance

Topics: C Back-end