Detailed explanation of minesweeping C language writing

I believe everyone must be familiar with mine sweeping! But do you believe that you can make a simple minesweeping game only with some basic knowledge of C language? hhh, today, I will lead you into mine sweeping and explore the mystery of its basic algorithm.

1, Basic ideas

First of all, since we are playing games, we should design the corresponding menu.

After entering 1, continue to let players choose the difficulty of the game:

 

Here we design a simple pattern of 6x6 size panels, with 10 Lei buried; The medium mode is 10x10 size panel, with 30 lightning buried; The difficult mode is a 14x14 size panel with 50 mines buried.

In order to facilitate the layout and display of Lei, we designed two panels: show_board[ROW][COL] and mine_board[ROW][COL], where the show panel is responsible for displaying "space", and the mine panel is responsible for recording the number of surrounding mines.

Players conduct Minesweeping Operations by inputting the coordinates corresponding to each grid.

char** show_board = (char**)malloc(sizeof(char*) * (ROW + grade * 4));//Dynamic memory allocation of two-dimensional array

for (int i = 0; i < ROW + grade * 4; i++) {
	show_board[i] = (char*)malloc(sizeof(char) * (COL + grade * 4));
	memset(show_board[i], ' ', (COL + grade * 4));//All arrays are assigned spaces
}

char** mine_board = (char**)malloc(sizeof(char*) * (ROW + grade * 4));

for (int i = 0; i < ROW + grade * 4; i++) {
	mine_board[i] = (char*)malloc(sizeof(char) * (COL + grade * 4));
	memset(mine_board[i], '0', (COL + grade * 4));//All arrays are assigned '0'
}

II. Code implementation

Step1. Draw a picture

If you want to play a minesweeping game, you should first have a minesweeping interface design, as follows:

We set up Showboard function to draw the basic panel:

static void Showboard(char **board,int grade)//Panel fabrication
{
	printf(" ");
	for (int i = 1; i <= ROW-2+4*grade; i++) {
		printf(" %3d", i);
	}
	printf("\n");

	for (int i = 1; i <= ROW-2+4*grade; i++){
		printf("   ");
		for (int k = 1; k <= COL-2+4*grade; k++) {
			printf("----");
		}
		printf("\n");
		printf("%2d|",i);
		for (int j = 1; j <= COL-2+4*grade; j++){
			printf(" %c |",board[i][j]);
		}
		printf("\n");
	}
	printf("   ");
	for (int k = 1; k <= COL-2+4*grade; k++) {
		printf("----");
	}
	printf("\n");
}

The results are as follows:

Step2. Buried mine

The following points shall be achieved for mine burial:

1. Display panel show_board (here, the parameter is replaced by the formal parameter board) is assigned as 1 (BOOM macro is defined as 1);

2. In order to improve the user experience and show the location of thunder after being bombed, we have established another Lei_ The board array is used to display and assign the corresponding position to '*' when burying mines;

3. Mine burying should be random, so rand function is quoted here (the main function should be a random number seed);

static void SetMines(char **board,char **lei_board,int grade)
{
	int i = 1;
	int x, y;
	while (i <= NUM+grade*20) {
		x = rand() % (ROW-2+4*grade) + 1;
		y = rand() % (COL-2+4*grade) + 1;
		if (board[x][y] != BOOM) {
			board[x][y] = BOOM;
			lei_board[x][y] = '*';
			i++;
		}
	}
}

Step3. Calculate the number of surrounding mines

When we count the thunder in the nine palaces, we will naturally count the thunder around us. It's simple if you want to search in the middle of the panel, but what if it's in the following cases, such as vertex lattice or edge lattice? How do you know which grid to count?

In order to avoid the problems caused by this special situation, we might as well set another circle directly outside, and the establishment of various panels (i.e. two-dimensional arrays) is also directly based on the increase, so there is no need to discuss the particularity of edges and corners.

The statistical function is directly realized through a simple function return:

static int CountMine(char **board,int x,int y)
{
	return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \
		board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + \
		board[x + 1][y] + board[x + 1][y + 1] - 8 * '0';
}

III. complete code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>

#define BOOM '1'
#define ROW 8
#define COL 8
#define NUM 10

static void SetMines(char **board,char **lei_board,int grade)//Buried mine
{
	int i = 1;
	int x, y;
	while (i <= NUM+grade*20) {
		x = rand() % (ROW-2+4*grade) + 1;
		y = rand() % (COL-2+4*grade) + 1;
		if (board[x][y] != BOOM) {
			board[x][y] = BOOM;
			lei_board[x][y] = '*';
			i++;
		}
	}
}
static void Showboard(char **board,int grade)//Panel fabrication
{
	printf(" ");
	for (int i = 1; i <= ROW-2+4*grade; i++) {
		printf(" %3d", i);
	}
	printf("\n");

	for (int i = 1; i <= ROW-2+4*grade; i++){
		printf("   ");
		for (int k = 1; k <= COL-2+4*grade; k++) {
			printf("----");
		}
		printf("\n");
		printf("%2d|",i);
		for (int j = 1; j <= COL-2+4*grade; j++){
			printf(" %c |",board[i][j]);
		}
		printf("\n");
	}
	printf("   ");
	for (int k = 1; k <= COL-2+4*grade; k++) {
		printf("----");
	}
	printf("\n");
}
static int CountMine(char **board,int x,int y)//Count the number of surrounding mines
{
	return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + \
		board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + \
		board[x + 1][y] + board[x + 1][y + 1] - 8 * '0';
}

void Game(int grade)//Game function, grade is the difficulty level of the game
{
	
	char** show_board = (char**)malloc(sizeof(char*) * (ROW + grade * 4));
	for (int i = 0; i < ROW + grade * 4; i++) {
		show_board[i] = (char*)malloc(sizeof(char) * (COL + grade * 4));
		memset(show_board[i], ' ', (COL + grade * 4));
	}
	char** mine_board = (char**)malloc(sizeof(char*) * (ROW + grade * 4));
	for (int i = 0; i < ROW + grade * 4; i++) {
		mine_board[i] = (char*)malloc(sizeof(char) * (COL + grade * 4));
		memset(mine_board[i], '0', (COL + grade * 4));
	}
	char** lei_board = (char**)malloc(sizeof(char*) * (ROW + grade * 4));
	for (int i = 0; i < ROW + grade * 4; i++) {
		lei_board[i] = (char*)malloc(sizeof(char) * (COL + grade * 4));
		memset(lei_board[i], ' ', (COL + grade * 4));
	}
	
	SetMines(mine_board,lei_board,grade);
	int x = 0, y = 0;
	int total = 0;
	while (1)
	{
		
		Showboard(show_board, grade);
		printf("Please enter coordinates:");
		//printf("%d", '*');
		scanf("%d %d", &x, &y);
		if (!(x > 0 && x <= ROW + 4 * grade - 2 && y > 0 && y <= COL + 4 * grade - 2)) {
			printf("There's a problem with the minesweeping position!\n");
			continue;
		}
		if (show_board[x][y] != ' ') {
			printf("This position has been swept!\n");
			continue;
		}
		if (mine_board[x][y] == '1') {
			printf("Sorry, you were killed!\n");
			Showboard(lei_board, grade);
			break;
		}
		else {
			int count = CountMine(mine_board, x, y);
			show_board[x][y] = count + '0';
			total++;
			system("cls");
		}
		if ((ROW - 2) * (COL - 2) - total <= NUM) {
			printf("Congratulations, the game passed!\n");
			break;
		}
	}
	for (int i = 0; i < ROW + grade * 4; i++) {
		free(show_board[i]);
	}
	free(show_board);
	for (int i = 0; i < ROW + grade * 4; i++) {
		free(mine_board[i]);
	}
	free(mine_board);
	for (int i = 0; i < ROW + grade * 4; i++) {
		free(lei_board[i]);
	}
	free(lei_board);
}

void Menu()
{
	printf("#########################################\n");
	printf("##                 1.play              ##\n");
	printf("##                 0.exit              ##\n");
	printf("#########################################\n");
}

int main()
{
	srand((unsigned long)time(NULL));
	int quit = 0;
	while (!quit)
	{
		int select;
		Menu();
		printf("Please enter game options:");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			printf("#########################################\n");
			printf("##                 1.easy              ##\n");
			printf("##                 2.middle            ##\n");
			printf("##                 3.difficult         ##\n");
			printf("#########################################\n");
			printf("Please enter the game difficulty:");
			scanf("%d", &select);
			switch (select)
			{
			case 1:
				Game(0);
				break;
			case 2:
				Game(1);
				break;
			case 3:
				Game(2);
				break;
			}
			break;
		case 0:
			quit = 1;
			printf("Thanks for using!");
			break;
		default:
			printf("Error in input, please re-enter!\n");
			break;
		}

	}
	
}

We look forward to adding more innovation and improvement on the basis of this code to write more intelligent and high-end mine sweeping programs with better user experience!!!

 

Keywords: C Back-end

Added by faizulbari on Sat, 12 Feb 2022 05:58:55 +0200