Preparation of simple version of mine sweeping

We need a little preparation before we begin to write the program. We need to create three files under one project, test c,game.c,game.h. (the file name is self-made, and these three are only taken for ease of understanding), test C file is used to store the main function and test code, game C file is used to realize various function functions, game H is used to declare and predetermined functions.

1. Composition of main function

(the main function is put in the test.c file) first of all, since it is a game, we need to print out the menu on the screen first. Here, we can directly use the printf function.

At the same time, a variable is provided to accept the player's choice. The switch function is used to execute different functions according to different choices of players.

In this way, the work of the main function is completed. The next thing to do is to realize the function of the progress and end of the game.

2. Realization of game subject

Because the implementation of game over is relatively simple, let's talk about this first (the game over function is placed in game.c)

File). In the gameover function, we only need to finish the end of the game, and we don't need too many functions. Written as a function alone is just for the convenience of completing the whole game later.

Then the next step is the main part of the game, that is, the implementation of the game function. (put the game function in the test.c file)

First, we need to create an array to be a chessboard. But first, we need to think about several problems: first, suppose we create a two-dimensional array to act as a chessboard. 0 means no thunder and 1 means thunder, then the problem comes. Minesweeping requires players to watch the chessboard. Then, if we print out the chessboard, all the thunder will be exposed. Therefore, we need two chessboards, That is to create two arrays, one for placing thunder and the other for displaying to players. The checkerboard on which thunder is placed uses 0 to indicate that there is no thunder and 1 to indicate that there is thunder; The chessboard displayed to the player is displayed with '*'. (there is no special meaning, just to look better, if you don't like '*', you can also use '#' $'&' and so on.) second, we all know that after we click a grid, a number will appear. This number represents the number of Mines contained in the surrounding eight grids, so we need to design a function, The function of this function is to traverse the eight grids around the grid pointed by the player's selected coordinates, and then return the number of mines. Then another new problem appears.

This is a minesweeping chessboard. As we said above, selecting a coordinate system will automatically traverse the surrounding eight coordinates. When we select several grids on the boundary, we will find that if we continue to check the eight grids, there will be cross-border visits. So we need to make some changes. Because we are doing primary minesweeping, we only need a 9x9 table to act as a chessboard. Then, as long as we expand this chessboard outward by one line, we can solve the problem of cross-border access. That is, we need to create two 11x11 forms, but when printing, only 9x9 parts are printed, and the outermost circle is hidden. In this way, when we select the boundary coordinates, we can successfully solve the problem of cross-border access. With the above foreshadowing, we began to formally write the program.

Predefined on game H file, because it will be used later.

After the chessboard is created, we need to initialize the chessboard first. The shadow array is used to store thunder, so we initialize it to all zeros, and the show array is used to show it to players, so we initialize it to '*'. The following is the function implementation of initializing the array:

Function declaration:

Function definition:

Function call:

The only thing to note is that we need to initialize two checkerboards, but the values used for initialization are different. Therefore, when designing a function, we directly pass the values used for initialization to the function as arguments, so we can avoid writing two functions.

Next, we need to print the two chessboards, because we need to show the chessboard to the player after selecting the coordinates every time, so we also set the printed chessboard as a function.

Function declaration:

Function definition:

Function call:

This will print out the chessboard:

Next, we will lay out thunder in the shadow array, that is, we will assign some values to 1. Random numbers need to be used here, so we need to write the srand function first:

The next step is the implementation of random numbers. Note that the effective coordinates of our array are 1 to 9, so our function:

Here, the range of rand()%row is 0 to 8, and then add 1 to become 1 to 9

Next comes the most troublesome and important part. This time, let's start with the code:

This is the most important part, that is, the implementation and call of demining, marking, unmarking and judging winning and losing functions.

The clear function is a function for demining and prompting. Let's talk about the details of this function first:

In this function, we first judge whether the value of the entered coordinate in the shadow array is 1. If it is 1, we will be struck by a mine. The game ends. If it is not 1, we will enter the exam function, start traversing the surrounding eight grids, and change the value of this coordinate to the number of mines. Of course, there are other ways to write the exam function, that is, it can only return the number of mines, which can have more operation space. However, because this is a simple version, the changes can be directly completed inside the exam function for the time being.

Here's how to judge the number of Mines: This shows the advantage of setting 0 as no mine and 1 as mine. We know that both 0 and 1 here refer to characters. Then, if it is all 0, the sum of ascll codes of eight grids is 32x8, and the ascll code of 1 is 33. Then subtract 8x '0' from the sum of data stored in eight nearby grids. Assuming that there are n '1' in these eight grids, you can get nx'1'+(8-n)x'0'-8x'0'=nx('1'-'0')=nx(33-32) = n, That is, the result is the number of Mines buried around. We have to print the chessboard every time after demining.

Next is the implementation of the marking function. This function is relatively simple. You can directly change the value according to the entered coordinates. The only thing to note is that the marking is the array displayed to the player. Here is the code:

Unmarked functions are much the same, so you can directly use the following code:

Finally, it is the function of judging whether to win or lose. Before we write this function again, we need to know what happens when we select a coordinate.

After we select a coordinate, check whether the value of this coordinate under the shadow array is' 1 '. If it is' 1', the game ends. If we mark all the positions of the thunder, the game wins. If the above two conditions are not met, the game continues.

Therefore, when we select thunder, we can change the value of the corresponding coordinate in the show array to '1', and then write is_ Win function to determine whether to win. is_ In the win function, we judge according to the show array. If the corresponding position of the show array in the shadow array is' 1 'or' # ', if it is all' # ', it proves that all mines are found and the game wins. If it has a position of' 1 ', it proves that the game fails, If there is no '1' and the number of '#' is less than 9, the game continues. In this way, you can write this is_win function:

In this way, a simple version of mine sweeping is completed

Finally, put a few more program execution diagrams:

 

ps: finally, put the game The source code of C file is released for your guidance:

#include"game.h"
void gameover()
{
	printf("Thank you for playing.");
}

void initboard(char arr[COLS][ROWS], int col, int row, char x)
{
	int i = 0;
	for (i = 0; i < col; i++)
	{
		for (int j = 0; j < row; j++)
		{
			arr[i][j] = x;
		}
	}
}

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


void set(char arr[COLS][ROWS], int col, int row)

{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';//Lay thunder
			count--;
		}
	}
}

void exam(char arr[COLS][ROWS], char show[COLS][ROWS], int x, int y)
{
	int n = 0;
	n = arr[x - 1][y - 1] + arr[x - 1][y] + arr[x - 1][y + 1] +
		arr[x][y - 1] + arr[x][y + 1] + arr[x + 1][y - 1] + arr[x + 1][y] + arr[x + 1][y + 1] - 8 * '0';
	switch (n)
	{
	case 1:
		show[x][y] = '1';
		break;
	case 2:
		show[x][y] = '2';
		break;
	case 3:
		show[x][y] = '3';
		break;
	case 4:
		show[x][y] = '4';
		break;
	case 5:
		show[x][y] = '5';
		break;
	case 6:
		show[x][y] = '6';
		break;
	case 7:
		show[x][y] = '7';
		break;
	case 8:
		show[x][y] = '8';
		break;
	default:
		show[x][y] = ' ';
		break;
	}
}



void clear(char arr[COLS][ROWS], char show[COLS][ROWS], int col, int row)
{
	int x = 0;
	int y = 0;
	printf("Please enter the coordinates you want to check:");
	scanf("%d %d", &x, &y);

	if (arr[x][y] == '1')
	{
		printf("I'm sorry you lost.\n");
		show[x][y] = '1';
	}
	else
	{
		exam(arr, show, x, y);
	}

}

void mark(char show[COLS][ROWS], int col, int row)
{
	int x = 0;
	int y = 0;
	printf("Please enter the coordinates you want to mark:");
	scanf("%d %d", &x, &y);
	if (show[x][y] == '*')
	{
		show[x][y] = '#';
	}
}

void un_mark(char show[COLS][ROWS], int col, int row)
{
	int x = 0;
	int y = 0;
	printf("Please enter the coordinates you want to cancel:");
	scanf("%d %d", &x, &y);
	if (show[x][y] == '#')
	{
		show[x][y] = '*';
	}
}

int is_win(char arr[COLS][ROWS], char show[COLS][ROWS], int col, int row)
{
	int flag = 0;
	for (int x = 1; x < col; x++)
	{
		for (int y = 1; y < row; y++)
		{
			if (arr[x][y] == '1')
			{
				if (show[x][y] == '#')
				{
					flag++;
				}
				if (show[x][y] == '1')
				{
					return 0;
				}
			}
		}
	}
	if (flag == 10)
	{
		return 1;
	}
	if (flag < 10)
	{
		return '*';
	}
}

 

 

Keywords: C

Added by israfel on Thu, 27 Jan 2022 17:44:02 +0200