[C language / entry game / 10000 character long text] mine sweeping Full Version (including marking, security protection and deployment)

g. knowledge summary (knowledge required for independently writing games):

1. Basic implementation of function;

2. Two dimensional array;

catalogue

mine clearance

1. Implementation of basic interface

2. Initialize the chessboard (two-dimensional array)

3. Printing of chessboard

4. Lay lightning

5. Safety protection

6. Mine number display

7. Mine detection

8. Marking mine

9. Deployment

10. Difficulty setting

11. Global code

mine clearance

design sketch:

 

  As can be seen from the above renderings, the functions we need to realize are:

1. Random mine burial

2. Display mine number

3. Deployment

4. Marking

5. Determine the winner or loser

It is unrealistic to put thunder, numbers and * in an array at the same time, because if thunder has been placed in a grid, it is impossible to turn it into an asterisk display, so we get a general idea that we should use two arrays, one buried thunder and one display.

As usual, create three files

game.h first references and defines the necessary data

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

This time we use '*' as unknown quantity, '#' as mark, '1' as thunder and '0' as non thunder (here is a foreshadowing)

1. Implementation of basic interface

This part is relatively simple, so just mention it briefly

void menu()
{
	printf("*********************************\n");
	printf("*********    1. Play    *********\n");
	printf("*********    0. Exit    *********\n");
	printf("*********************************\n");
	
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//Store mine information
	char show[ROWS][COLS] = { 0 };//A chessboard displayed to players
	intialize(mine,ROWS ,COLS,'0');
	intialize(show,ROWS ,COLS,'*');
	//Display chessboard
	print(show, ROW, COL);
	
	//Lay thunder
	setmine(mine, ROW, COL);
	
	//Check
	search(mine, show, ROW, COL,0);



}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please select>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("game start\n");
			game();
			break;
		case 0:
			printf("Quit the game\n");
			break;
		default:
			printf("Selection error, please re select\n");
			break;
		}

	} while (input);
	return 0;
}

Here someone may ask, why create an 11 * 11 array?

If we want to find the number of mines in the 9 * 9 chessboard, we have to find the surrounding 8 elements, but if we want to find the number of lattice attachment mines in the corners, it involves the problem of array crossing, which is not easy to do. So we make the array bigger to ensure that the array access will not cross the boundary

 

2. Initialize the chessboard (two-dimensional array)

Now we have to consider a problem. This time we have two two two-dimensional arrays to initialize, and the contents are different. What should we do?

In fact, it is also relatively simple. You only need to let the initialization function accept an additional amount that needs to be initialized

void intialize(char board[ROWS][COLS], int row, int col, char target)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = target;

		}
	}

}

In this way, different initialization can be completed

3. Printing of chessboard

As the checkerboard required for mine clearance is relatively large, in order to facilitate play, the row and column number needs to be printed this time

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

design sketch:

4. Lay lightning

The arrangement of Mines involves the problem of random numbers. It is necessary to ensure that mines will not be arranged repeatedly and will only be arranged in a 9 * 9 chessboard

void setmine(char board[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int count = 0;
	while (1)//Cycle without full arrangement
	{
		x = rand() % row + 1;//Make x and y between 1 and 9 to ensure that the array does not cross the boundary
		y = rand() % col + 1;
		if (board[x][y] != '1')//Ensure that the arranged lightning is not repeated
		{
			board[x][y] = '1';
			count++;
		}
		if (count == EASY_COUNT)//Jump out of the cycle only after all non repeating mines are arranged
			break;
	}

}

5. Safety protection

In order to prevent sudden death in the first investigation and improve the game experience, we need to design it so that if players step on Thunder for the first time, the chessboard will reset until there is no thunder here

first_die++;
if (first_die == 1 && mine[x][y] == '1')//first_die is created in test, and 0 is passed in by default
		{
			while (mine[x][y] == '1')
			{
				intialize(mine, ROWS, COLS, '0');//The chessboard must be initialized first, otherwise the original thunder will still be there
				setmine(mine, ROW, COL);
			}
			
		}

6. Mine number display

int search_show(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x][y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');
}

The ASCII value of '0' is 48. We design the mine as' 1 'to facilitate adding and subtracting 8' 0 'to directly obtain the number of mines

7. Mine detection

The following is one of the key points of this article. In fact, the implementation idea of Lei's investigation is relatively simple. If you step on Lei, the game ends; If not, continue the game and display the number of nearby mines

	int x = 0;
	int y = 0;
	

	

	while (1)
	{
		printf("Please enter the coordinates to be checked, such as: 1\n");
		scanf("%d%d", &x, &y);
		first_die++;

		

		if (x >= 1 && x <= row && y >= 1 && y <= col)//Judge whether the input line number is within the specified range
		{
			if (mine[x][y] == '1')
			{
				printf("You're dead. Please keep up your efforts\n");
				print(mine, ROW, COL);
				break;
			}
			else
			{
				show[x][y] = search_show(mine, ROW, COL)+'0';//Displays the number of mines around
				open(mine,show, x, y,row,col);
				print(show, ROW, COL);
				

			}
		}
		else
		{
			printf("Input error, please re-enter\n");
		}

8. Marking mine

We can add a marking function after troubleshooting. We specify to mark with '#' and only unknown quantities can be marked at the same time

//Mark mine
		int input1 = 0;
		int input2 = 0;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{

			do//Run at least once
			{
				printf("Please enter the marker coordinates,Enter 0 to exit the tag\n");
				scanf("%d%d", &input1, &input2);

				if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col)
				{
					if (show[input1][input2] == '*')//Mark only unknowns
					{
						show[input1][input2] = '#';
						print(show, ROW, COL);
					}
					else
					{
						printf("Marking failed, please mark again\n");
					}
				}
				else if (input1 == 0 && input2 == 0)//Enter 0 to exit the tag
					break;
				else
				{
					printf("Marking error, please mark again\n");
				}

			} while (input1&&input2);
			printf("Tag exited\n");
		}

9. Deployment

This should be the hardest part to implement. Here we use the idea of recursion

void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col)
{
	int ret = 0;
	ret =search_show(mine,x,y);
	
	if (ret == 0)//If there is no thunder around, judge to expand
	{
		show[x][y] = ' ';//Prevent dead recursion. If show[x][y] is not changed to '', the next detection may be *. Enter recursion again until it is stuck.
		if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'|| show[x - 1][y] == '#')
			open(mine, show, x - 1, y, row, col);
		if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == '*'|| show[x - 1][y + 1] == '#')
			open(mine, show, x - 1, y + 1, row, col);
		if (x > 0 && y + 1 <= col && show[x][y + 1] == '*'|| show[x][y + 1] == '#')
			open(mine, show, x, y + 1, row, col);
		if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == '*'|| show[x + 1][y + 1] == '#')
			open(mine, show, x + 1, y + 1, row, col);
		if (x + 1 <= row && y > 0 && show[x + 1][y] == '*'|| show[x + 1][y] == '#')
			open(mine, show, x + 1, y, row, col);
		if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == '*'|| show[x + 1][y - 1] == '#')
			open(mine, show, x + 1, y - 1, row, col);
		if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'|| show[x][y - 1] == '#')
			open(mine, show, x, y - 1, row, col);
		if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'|| show[x - 1][y - 1] == '#')
			open(mine, show, x - 1, y - 1, row, col);
		
	}
	else//If there is thunder, the number of thunder is returned
	{
		return show[x][y]=search_show(mine, x, y)+'0';
	}

}

10. Difficulty setting

In fact, the implementation idea is relatively simple. You can set middle again_ Count and HARD_COUNT.

When transferring parameters, you can also pass in the difficulty number

It's not difficult to leave it to everyone to realize it by themselves

11. Global code

game.h

# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 9
#define COL 9

#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10

//initialization
void intialize(char board[ROWS][COLS], int row, int col, char target);

//Print chessboard
void print(char board[ROWS][COLS], int row, int col);

//Lay thunder
void setmine(char board[ROWS][COLS], int row, int col);

//Check thunder
void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int


game.c

# define _CRT_SECURE_NO_WARNINGS
# include "game.h"

void intialize(char board[ROWS][COLS], int row, int col, char target)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			board[i][j] = target;

		}
	}

}

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

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

}



int search_show(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y] +
		mine[x - 1][y - 1] +
		mine[x][y - 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] +
		mine[x][y + 1] +
		mine[x - 1][y + 1] - 8 * '0');
}

void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col)
{
	int ret = 0;
	ret =search_show(mine,x,y);
	
	if (ret == 0)//If there is no thunder around, judge to expand
	{
		show[x][y] = ' ';//Prevent dead recursion. If show[x][y] is not changed to '', the next detection may be *. Enter recursion again until it is stuck.
		if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'|| show[x - 1][y] == '#')
			open(mine, show, x - 1, y, row, col);
		if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == '*'|| show[x - 1][y + 1] == '#')
			open(mine, show, x - 1, y + 1, row, col);
		if (x > 0 && y + 1 <= col && show[x][y + 1] == '*'|| show[x][y + 1] == '#')
			open(mine, show, x, y + 1, row, col);
		if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == '*'|| show[x + 1][y + 1] == '#')
			open(mine, show, x + 1, y + 1, row, col);
		if (x + 1 <= row && y > 0 && show[x + 1][y] == '*'|| show[x + 1][y] == '#')
			open(mine, show, x + 1, y, row, col);
		if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == '*'|| show[x + 1][y - 1] == '#')
			open(mine, show, x + 1, y - 1, row, col);
		if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'|| show[x][y - 1] == '#')
			open(mine, show, x, y - 1, row, col);
		if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'|| show[x - 1][y - 1] == '#')
			open(mine, show, x - 1, y - 1, row, col);
		
	}
	else
	{
		return show[x][y]=search_show(mine, x, y)+'0';
	}

}

int win(char show[ROWS][COLS], int row, int 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 == EASY_COUNT)
		return 1;
	else
		return 0;
}

void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int first_die)
{
	int x = 0;
	int y = 0;
	

	

	while (1)
	{
		printf("Please enter the coordinates to be checked, such as: 1\n");
		scanf("%d%d", &x, &y);
		first_die++;

		
		//Prevent the first sudden death
		if (first_die == 1 && mine[x][y] == '1')
		{
			while (mine[x][y] == '1')
			{
				intialize(mine, ROWS, COLS, '0');
				setmine(mine, ROW, COL);
			}
			
		}

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("You're dead. Please keep up your efforts\n");
				print(mine, ROW, COL);
				break;
			}
			else
			{
				show[x][y] = search_show(mine, ROW, COL)+'0';//Displays the number of mines around
				open(mine,show, x, y,row,col);
				print(show, ROW, COL);
				

			}
		}
		else
		{
			printf("Input error, please re-enter\n");
		}
		
		//Judge whether to win or lose
		int Win = win(show, row, col);
		if (Win == 1)
		{
			printf("Congratulations, victory\n");
			break;
		}

		//Mark mine
		int input1 = 0;
		int input2 = 0;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{

			do
			{
				printf("Please enter the marker coordinates,Enter 0 to exit the tag\n");
				scanf("%d%d", &input1, &input2);

				if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col)
				{
					if (show[input1][input2] == '*')
					{
						show[input1][input2] = '#';
						print(show, ROW, COL);
					}
					else
					{
						printf("Marking failed, please mark again\n");
					}
				}
				else if (input1 == 0 && input2 == 0)
					break;
				else
				{
					printf("Marking error, please mark again\n");
				}

			} while (input1&&input2);
			printf("Tag exited\n");
		}
	}
}


test.c

# define _CRT_SECURE_NO_WARNINGS
# include "game.h"

void menu()
{
	printf("*********************************\n");
	printf("*********    1. Play    *********\n");
	printf("*********    0. Exit    *********\n");
	printf("*********************************\n");
	
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//Store mine information
	char show[ROWS][COLS] = { 0 };//Store the information of the detected mine
	intialize(mine,ROWS ,COLS,'0');
	intialize(show,ROWS ,COLS,'*');
	//Display chessboard
	print(show, ROW, COL);
	
	//Lay thunder
	setmine(mine, ROW, COL);
	
	//Check
	search(mine, show, ROW, COL,0);



}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please select>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("game start\n");
			game();
			break;
		case 0:
			printf("Quit the game\n");
			break;
		default:
			printf("Selection error, please re select\n");
			break;
		}

	} while (input);
	return 0;
}

The above is the content of this sharing. If you like my sharing, don't forget to praise and pay attention!

If you have any comments on my article, please comment below or send me a private letter!

I'm Bai Chen. I'll see you next time!!

Tags: Java C C++ C#

Posted on Wed, 06 Oct 2021 23:59:33 -0400 by csxpcm