[mine sweeping game] C language version -- Explanation of old maid version

Posted by php2MySQL on Wed, 26 Jan 2022 11:25:42 +0100

Hello, everyone, that is, the latter game of Sanzi chess - mine sweeping. This game is much more playable than Sanzi chess. Correspondingly, an algorithm will be difficult to think of, but it is very similar to the game framework of Sanzi chess. Less nonsense. Next, let's start to analyze how mine clearance is realized.

catalogue

1, Initialization of chessboard

2, Printing of chessboard

3, Stockpile mines.

4, Find ray

Recursive expansion

5, Identify demining status and end demining

The pre preparation and user interaction screen are the same as that of Sanzi chess. I won't copy and paste it. I can go to my last blog and directly talk about the program after these two steps.

1, Initialization of chessboard

We use two chessboards here. One is the chessboard where we place mines and the other is the chessboard used by users for mine clearance. This separate setting is conducive to our design of the game

We want to set the two checkerboards to 11 * 11, but only display the data of 1-10 rows and columns, which is convenient for us to check thunder. The initialization code is as follows:

char mine[ROW][COL];
	char show[ROW][COL];
	//Initialize the chessboard. mine array is fully initialized to 0, and shou array is fully initialized to 0*
	inti_board(mine, '0');
	inti_board(show, '*');

We set the initialization function to assign values to whatever is passed. This is easy to implement. Just attach all the 11 * 11 arrays

//Array initialization
void inti_board(char board[ROW][COL], char c)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < ROW; i++)
	{
        for (j = 0; j < COL; j++)
		{
			board[i][j] = c;
		}
	}
}

2, Printing of chessboard

The chessboard I print here is designed by me, which is easy to correspond to coordinates. In fact, printing is nothing, mainly personal will

However, for this printing, the user interface will be printed if the show array is passed in, and the development page will be printed if the mine array is passed in

Here I put my print function, because this is not the focus of mine clearance.

void print_board(char board[ROW][COL])
{
	printf("***********************************************\n\n");
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		if (i == 1)
			printf("   ");
      printf("  %d ", i);
	}
	printf("\n");
	printf("    ");
	for (i = 1; i <= row; i++)
	{
		if (i<row)
		printf("----");
		if (i == row)
			printf("---");
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf(" %d ", i);
		for (j = 1; j <=col; j++)
		{
			printf("|");
			printf(" %c ", board[i][j]);
			if (j == col)printf("|");
		}
		printf("\n");
		printf("    ");
		for (j = 1; j <= col; j++)
		{
			if (j<col)
			printf("----");
			if (j == col)
				printf("---");
		}
		printf("\n");
	}
	printf("\n");
	printf("***********************************************\n");
	printf("\n");
}

3, Mine storage.

This is similar to the computer running of Sanzi chess. It also uses the rand function to generate 10 pairs of coordinates to insert thunder into the mine array, which is not too difficult

//Emplacement mine
void set_bomb(char board[ROW][COL])
{
	int x;
	int y;
	int count = 10;//count is the number of mines placed
	while (count)
	{
		x = rand() % col;
		y = rand() % row;
		if (x >= 1 && x <= 9 && y >= 1 && y <= 9 && board[x][y] == '0')
		{//The seat is not occupied and is displayed on the chessboard
			count --;
			board[x][y] = '1'; //Put 1 represents thunder
		}
	}
}

4, Find ray

Finding thunder is our focus today. We need to determine the direction and process:

1. User input coordinates (set cycle to judge the legitimacy of coordinates)

2. Judge the coordinates

2.1 check whether the mine array of this coordinate is thunder. If it is thunder, print the chessboard and return directly; game over

2.2 it's not thunder. We judge whether there is thunder around us, return the number of thunder detected, and display it in the position entered by the user in the show array (and expand recursively). The game continues.

(here's a little idea for you. If you want to mark Lei, you can enter 0, enter 0 to enter the marking page, then enter the coordinates to be marked, and change the corresponding coordinates on the show array)

 

1.1 and 2.1 are still very simple. Let's focus on 2.2

Check the number of mines around the mine coordinates

We transfer the coordinates entered by the user into the function of checking statistical thunder. The idea is:

Because we set thunder as 1 and non thunder as 0, we can add up the values of 9 coordinates and subtract the values of 8 '0' to calculate the value to be returned, because the ascii code value of 0 is 48 and the ascii code value of 1 is 49. As long as we return 48, we return '0', indicating that there is no thunder in the surrounding circle, and return 49, we return '1', indicating one thunder, and so on. And you can put the returned value on the coordinates corresponding to the show array, so that it will be displayed next time.

The code implementation is as follows:

int count_mine(char mine[ROW][COL], int x, int y)
{
	int sum = 0;
	for (int i = -1; i <= 1; i++)
		for (int j = -1; j <= 1; j++)
			sum += mine[x - i][y - j];
	return sum - 8 * 48;
}

Recursive expansion

Not a lap of thunder

At this time, we have to think, if the surrounding circle is not thunder, should it be expanded? How can we set the recursive formula of expanding the circle?

Let's take a look at how this recursion should be designed:

return needs to be judged by if. What do these sub coordinates mean? Next, take a look at the figure. These eight sub coordinates represent the expansion of the parent coordinates in eight directions.

In fact, it is the eight small squares around him. The coordinates are also easy to write. The code is as follows:

//Recursive expansion
void spread_board(char mine[ROW][COL], char show[ROW][COL], int x, int y)
{		//After a round of investigation, it is found that there is thunder. Set the number of seats on the show to the number of thunder
	int i = count_mine(mine, x, y);
	if (i != '0')
	{
		show[x][y] = i;
		return;
	}
	//Check the circle, find the starting space and stop
	if (show[x][y] == ' ')
	{
		return;
	}
	//Beyond the boundary
	if (x <= 0 || x > row || y <= 0 || y > col)
		return;
	//Check and find that there is no thunder. Set the position corresponding to show as a space
	show[x][y] = ' ';
	/*print_board(show);*/
	spread_board(mine, show, x + 1, y);
	spread_board(mine, show, x + 1, y - 1);
	spread_board(mine, show, x + 1, y + 1);
	spread_board(mine, show, x, y - 1);
	spread_board(mine, show, x, y + 1);
	spread_board(mine, show, x - 1, y - 1);
	spread_board(mine, show, x - 1, y + 1);
	spread_board(mine, show, x - 1, y);
}

Next is the code of the input function:

//Find ray
void lookup_bomb(char show[ROW][COL], char mine[ROW][COL])
{
	int x;
	int y;
	char count=0;
	while (1)
	{
		printf("Please enter the coordinates or marks of the search:\n");
        scanf("%d %d", &x, &y);
		while (1)
		{
        if (x == y && x == 0)
		{
			printf("Please enter coordinates to mark:\n");
			scanf("%d %d", &x, &y);
			show[x][y] = '@';
			print_board(show);
			printf("Please enter the coordinates or marks of the search:\n");
			scanf("%d %d", &x, &y);
		}
		if (0 != y && x != 0)
			break; 
		}
		
		 if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
		 {
			 if (mine[x][y] == '1')
			 {
				 system("cls");
				 printf("sorry,You were killed\n The distribution of thunder is as follows:\n");
				 print_board(mine);
				 sign = 2;
				 return;
			 }
			 else
			 {
				 //Find out how many mines are around this coordinate
				 count = count_mine(mine, x, y);
				 if (count == '0')
				 {//There is no thunder around the statistics, and start recursive expansion					 
					 spread_board(mine,show, x, y);
				 }
				 if (count != '0')
				 show[x][y] = count;
				 break ;
			 }

		 }
		 else
		 {
           printf("Incorrect input, please re-enter:\n");
		 }
			 
	}
}

5, Identify demining status and end demining

Finally, there is only one finishing work left. My idea is different from everyone's. I stop by checking whether the sum of asterisks (*) and tags (@) on the show array is equal to 10. Because if the player checks 10 of the 81 symbols on the shou array and hasn't stepped on the thunder all the time, it means that the player has ranked the last 10 and can exit safely. Congratulations to the player. I also set a global variable sign, and change the sign to 0 after the player steps on the thunder. In this way, if the sign in the game function is judged to be 0, the game will be interrupted directly and the user steps on the thunder. This is my idea. Of course, my idea is not the best. There may even be a BUG. You can take appropriate reference to my code., The code is as follows:

//Check the end of the game
int inspect_game(char show[ROW][COL])
{
	int i = 0;
	int j = 0;
	int count=0;
	for (i=1;i<=row;i++)
		for (j = 1; j <= col; j++)
		{
			if (show[i][j] == '*'||show[i][j]=='@')
			{
				count++;
			}
		}
	if (count <= 10)
		return 1;
	return 0;
}

In this way, after the design of the minesweeping game, you will find that the overall idea of the game is similar, and the minesweeping will be expanded recursively, which is a little difficult to think of, but more practice of the game design is also conducive to clarifying the programming idea and enhancing the programming ability.

In the next blog, I will put down all the code of three files.

Finally, when you see here, leave a praise~~

Topics: C Game Development