当前位置:网站首页>C language to achieve mine sweeping game (full version)

C language to achieve mine sweeping game (full version)

2022-07-06 13:26:00 It's Wang Jiujiu

and Sanzi equally , The core idea of mine sweeping is also the use of two-dimensional arrays .

The minesweeping game also uses : Loop statement Branch statement Recursion of a function And pointer and other knowledge , Specific knowledge has been explained in previous articles .

utilize C Language realizes the minesweeping game in the command window :

1、 Input mode : Players enter coordinates , If it wasn't ray , The game goes on ; If it's ray , Game over .

2、 Determination of coordinates : If there is thunder around this coordinate , Then display the information of surrounding mines ; If there is no thunder around this coordinate , Then expand multiple items at a time , Until it spreads out near the thunder .

3、 The game is over : When players touch thunder , Or all non mine areas on the chessboard are found by players . 

                

Catalog

The main menu

Game part

1. Set the chessboard and initialize

2. Bure

3. Print chessboard

4.Cue Prompt Lei's information

5.Unfold Expand functions

6.Guess screening

demo

The overall code

( One )game.h

( Two )game.c

( 3、 ... and )text.c


The main menu

The main menu uses do while Loop structure , It's not fun to play the game once , You can also continue to play .(do while The cycle can ensure that the whole cycle runs at least once )

//text.c
#include "game.h"
void menu()// menu 
{
	printf("********************\n");
	printf("*****  1.paly  *****\n");
	printf("*****  0.exit  *****\n");
	printf("********************\n");
}
int main()
{
	int input = 0;
	do 
	{
		menu();
		printf(" Please select (1/0):>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf(" Start the game \n");
			break;
		case 0:
			printf(" Quit the game \n");
			break;
		default:
			printf(" Input error , Please re-enter \n");
		}
	} while (input);
	return 0;
}

In order to find out exactly after the test bug Location , We should cultivate that every time we finish writing a part of the code , Just test your good habits . Here we test whether the code of the main menu can work normally .

Game part

1. Set the chessboard and initialize

( One ) Set the chessboard

Planning of chessboard :

mine The board : Store mine information ( Don't show players )

show The board : The chess board of the player's game .( Show players )

The rows and columns of the chessboard :

1、 adopt #define Define constants to set , Convenient for future code updates .

2、 In order not to cross the boundary when accessing the two-dimensional array later , When setting the chessboard , Both rows and columns should +2.( If you want to play 9×9 The chessboard of , Then set the chessboard to 11×11)

//game.h
// Set the rows and columns of the chessboard 
#define ROW 11
#define COL 11

//text.c
void game()
{
	// Store mine information in mine in 
	char mine[ROW][COL] = { 0 };
	// Store the displayed information in show in 
	char show[ROW][COL] = { 0 };
}

( Two ) initialization

Initboard: utilize for Loop through every element of the two-dimensional array , Initialize the chessboard .

initialization mine The board : Bray's chessboard is initialized to ’0‘.( there 0 Character 0)

initialization show The board : The displayed chessboard is initialized to ’*‘.

//game.h
// initialization 
void Initboard(char board[ROW][COL], int row, int col, char set);
//game.c
// Initialize chessboard 
void Initboard(char board[ROW][COL], int row,int col,char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
	}
}
//text.c
void game()
{
	// Store mine information in mine in 
	char mine[ROW][COL] = { 0 };
	// Store the displayed information in show in 
	char show[ROW][COL] = { 0 };
	// Bray's chessboard is initialized to 0
	Initboard(mine, ROW, COL, '0');
	// The displayed chessboard is initialized to *
	Initboard(show, ROW, COL, '*');
}

After defining the chessboard , Enter debugging mode , Monitor whether our two checkerboards are correct through the monitoring window .

2. Bure

The number of thunder is also used define Definition , Convenient for later modification .

Setting: adopt rand Randomly generated mine coordinates , Each time you generate coordinates, you need to judge whether the coordinates are legal . And pay attention to , The range of coordinates is the range of the board game , Instead of the range originally set .

( If you want to use rand function , You need to set the rand Function :srand((unsigned int)time(NULL));, Otherwise, the random values generated each time will be the same )

//game.h
// Mine and print lines 、 Column 
#define ROWS ROW-2
#define COLS COL-2
// The number of Mines 
#define Easy 10

//game.c
// Bure 
void Setting(char board[ROW][COL], int rows, int cols)
{
	int count = Easy;
	while (count)
	{
		int x = rand() % rows + 1;
		int y = rand() % rows + 1;
		if (board[x][y] != 1)
		{
			board[x][y] = '1';
			count--;
		}
	}
}
//text.c
void game()
{
	// Store mine information in mine in 
	char mine[ROW][COL] = { 0 };
	// Store the displayed information in show in 
	char show[ROW][COL] = { 0 };
	// Bray's chessboard is initialized to 0
	Initboard(mine, ROW, COL, '0');
	// The displayed chessboard is initialized to *
	Initboard(show, ROW, COL, '*');
	// Bure 
	Setting(mine, ROWS, COLS);
}
//main function 
srand((unsigned int)time(NULL));

After arranging the thunder , It is also to enter debugging mode to check whether the code is running correctly .

3. Print chessboard

Dispaly: Just print show Just a chessboard , Define that the printing chessboard here is consistent with the initialization method , It's all used for Loop through each element . The only difference is that for the convenience of entering coordinates , Here, the row and column numbers are printed in the first row and the first column .( After printing the line number, you need to wrap , Print column numbers without )

//game.h
// Print chessboard 
void Display(char board[ROW][COL], int rows, int cols);
//text.c
// Print chessboard 
void Display(char board[ROW][COL], int rows, int cols)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= rows; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= rows; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= cols; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

4.Cue Prompt Lei's information

In the Minesweeper game , If the coordinate is not ray , And when there is thunder around , It will prompt the number of thunder around .

 Cue: Input the player x、y Parameters to Cue function , use for Loop through the coordinates of the surrounding circle , Use temporary variables count To record the number of thunder around . Set the coordinates of the deployed mine to ’1‘.

// Tips 
int Cue(char mine[ROW][COL], int x, int y)
{
	int i = 0;;
	int j = 0;
	int count = 0;
	for (i = -1; i <= 1; i++)
	{
		for (j = -1; j <= 1; j++)
		{
			if (mine[x + i][y + j] == '1')
			{
				count++;
			}
		}
	}
	return count;
}

5.Unfold Expand functions

In the Minesweeper game , If there is thunder around this coordinate , Then display the information of surrounding mines ; If there is no thunder around this coordinate , Then expand multiple items at a time , Until it spreads out near the thunder .

The main use here is Unfold Recursion of a function , Match the definition Cue Function to implement .

Recursion needs to meet the following two points :

1、 Set the end condition of recursion .

  • Coordinate overrun
  • This coordinate is ray
  • This coordinate has been found
  • This coordinate has been marked with mine information

2、 The coordinates that have been searched cannot be searched repeatedly , Otherwise, it will fall into dead recursion .

  • mine[x][y] = '2'
  • Mark the found coordinates as non 0, Not 1 The number of

Besides , It also needs to be defined outside the function count,count Is the total number of pieces - The number of Mines , To judge the end of the game .

External transmission count You need to get the address when parameters , Internal function recursion ,count It's already the address , Don't take the address again .

// Multiple expansions 
void Unfold(char mine[ROW][COL], char show[ROW][COL], int x, int y,int* count)
{
	int i = 0;
	int j = 0;
	// End flag :
	//1、 Coordinate overrun 
	//2、 This coordinate is ray 
	//3、 This coordinate has been found 
	if (1 <= x && x <= 9 && 1 <= y && y <= 9 && mine[x][y] == '0' && show[x][y] == '*')
	{
		mine[x][y] = '2';// The coordinates searched are mine Mark in 

		if (Cue(mine, x, y))// There are thunder around, indicating the number of thunder 
		{
			show[x][y] = '0' + Cue(mine, x, y);// Convert integers to characters 
			(*count)--;
		}
		else
		{
			show[x][y] = ' ';// If there is no thunder, the space will be displayed 
			(*count)--;
			for (i = -1; i <= 1; i++)// in the light of (x,y) Search around eight grids 
			{
				for (j = -1; j <= 1; j++)
				{
				  Unfold(mine, show, x + i, y + j,count);// Recursion , there count It's already the address , Don't take the address again 
				}
			}
		}
	}
}

6.Guess screening

After the player enters the coordinates , This coordinate needs to be judged :

  • Illegal coordinates , Re input
  • Coordinates are legal , Get into Unfold function , Check whether it is expanded , And prompt Lei's information
  • Coordinates are bombs , Game over

The basis of circulation here is count, When count by 0 when , Out of the loop , Announce the result of the game .

//game.h
// screening 
void Guess(char mine[ROW][COL], char show[ROW][COL], int rows, int cols);

//game.c
// screening 
void Guess(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
{
	int x = 0;
	int y = 0;
	// Record the number of troubleshooting 
	int count = rows * cols - Easy;
	while (count)
	{
		scanf("%d %d", &x, &y);
		// Determine whether the coordinates are correct 
		//1、 The coordinates are in range 
		//2、 Coordinates are not used 
		if (1 <= x && x <= 9 && 1 <= y && y <= 9 && show[x][y] == '*')
		{
			if (mine[x][y] != '1')
			{
				printf("Continue......\n");// If it's not ray, continue 
				show[x][y] = ' ';
				Display(show, ROWS, COLS);
				count--;
			}
			else
			{
				printf(" unfortunately , Make persistent efforts \n");
				DisplayEnd(mine,show, ROWS, COLS);// Print out the situation of mine laying .
				break;
			}	
		}
		else
			printf(" Illegal coordinates , Please re-enter \n");
	}
	if (count == 0)
	{
		printf(" congratulations \n");
		Display(show, ROWS, COLS);
	}
}

After the game , You also need to print out the results of the game and the situation of mine laying , Here is more than just printing mine The board , Need to put mine and show Combine the chessboard .

// Print the ending 
void DisplayEnd(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
{
	{
		int i = 0;
		int j = 0;
		for (i = 0; i <= rows; i++)
		{
			printf("%d ", i);
		}
		printf("\n");
		for (i = 1; i <= rows; i++)
		{
			printf("%d ", i);
			for (j = 1; j <= cols; j++)
			{
				if (mine[i][j] == '1')// If it's ray, print it out 
				{
					printf("%c ",mine[i][j]);// The only difference from printing chessboard 
				}
				else
				{
					printf("%c ", show[i][j]);
				}
			}
			printf("\n");
		}
		printf("\n");
	}
}

demo

Looks like bad luck , There is no area to expand , Try changing the coordinates .

Try entering the wrong coordinates , Check whether the system can detect .

 (4,5) It's obviously a thunder , Let's see if the result is as we expected .

By changing define Defined constant , To change the difficulty of the game . Of course, minesweeping can also be made into an interface , Concrete UI The design is also very simple , Here we only talk about basic algorithm knowledge ,UI You can learn your own design .

The overall code

The overall code is as follows , Of course, there are many things worth optimizing , You can communicate with each other if you have any ideas .

( One )game.h

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

// Set the line of the chessboard 、 Column 
#define ROW 11
#define COL 11
// Mine and print lines 、 Column 
#define ROWS ROW-2
#define COLS COL-2
// The number of Mines 
#define Easy 10

// initialization 
void Initboard(char board[ROW][COL], int row, int col, char set);
// Bure 
void Setting(char board[ROW][COL], int rows, int cols);
// Print chessboard 
void Display(char board[ROW][COL], int rows, int cols);
// Print the ending 
void DisplayEnd(char mine[ROW][COL], char show[ROW][COL], int rows, int cols);
// screening 
void Guess(char mine[ROW][COL], char show[ROW][COL], int rows, int cols);

( Two )game.c

#define _CRT_SECURE_NO_WARNINGS

#include "game.h"

// Initialize chessboard 
void Initboard(char board[ROW][COL], int row, int col, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = set;
		}
	}
}
// Bure 
void Setting(char board[ROW][COL], int rows, int cols)
{
	int count = Easy;
	while (count)
	{
		int x = rand() % rows + 1;
		int y = rand() % rows + 1;
		if (board[x][y] != 1)
		{
			board[x][y] = '1';
			count--;
		}
	}
}
// Print chessboard 
void Display(char board[ROW][COL], int rows, int cols)
{
	int i = 0;
	int j = 0;
	for (i = 0; i <= rows; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= rows; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= cols; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
// Print the ending 
void DisplayEnd(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
{
	{
		int i = 0;
		int j = 0;
		for (i = 0; i <= rows; i++)
		{
			printf("%d ", i);
		}
		printf("\n");
		for (i = 1; i <= rows; i++)
		{
			printf("%d ", i);
			for (j = 1; j <= cols; j++)
			{
				if (mine[i][j] == '1')
				{
					printf("@ ");
				}
				else
				{
					printf("%c ", show[i][j]);
				}
			}
			printf("\n");
		}
		printf("\n");
	}
}
// Prompt the information of thunder around 
int Cue(char mine[ROW][COL], int x, int y)
{
	int i = 0;;
	int j = 0;
	int count = 0;
	for (i = -1; i <= 1; i++)
	{
		for (j = -1; j <= 1; j++)
		{
			if (mine[x + i][y + j] == '1')
			{
				count++;
			}
		}
	}
	return count;
}
// Multiple expansions 
void Unfold(char mine[ROW][COL], char show[ROW][COL], int x, int y,int* count)
{
	int i = 0;
	int j = 0;
	// End flag :
	//1、 Coordinate overrun 
	//2、 This coordinate is ray 
	//3、 This coordinate has been found 
	if (1 <= x && x <= 9 && 1 <= y && y <= 9 && mine[x][y] == '0' && show[x][y] == '*')
	{
		mine[x][y] = '2';// The coordinates searched are mine Mark in 

		if (Cue(mine, x, y))// There are thunder around, indicating the number of thunder 
		{
			show[x][y] = '0' + Cue(mine, x, y);// Convert integers to characters 
			(*count)--;
		}
		else
		{
			show[x][y] = ' ';// If there is no thunder, the space will be displayed 
			(*count)--;
			for (i = -1; i <= 1; i++)// in the light of (x,y) Search around eight grids 
			{
				for (j = -1; j <= 1; j++)
				{
				  Unfold(mine, show, x + i, y + j,count);// Recursion , there count It's already the address , Don't take the address again 
				}
			}
		}
	}
}
	// screening 
	void Guess(char mine[ROW][COL], char show[ROW][COL], int rows, int cols)
	{
		int x = 0;
		int y = 0;
		// Record the number of troubleshooting 
		int count = rows * cols - Easy;
		while (count)
		{
			printf(" Please enter the coordinates :>\n");
			scanf("%d %d", &x, &y);
			// Determine whether the coordinates are correct 
			//1、 The coordinates are in range 
			//2、 Coordinates are not used 
			if (1 <= x && x <= 9 && 1 <= y && y <= 9 && show[x][y] == '*')
			{
				if (mine[x][y] == '1')
				{
					printf(" unfortunately , Make persistent efforts \n");
					DisplayEnd(mine, show, ROWS, COLS);// Print out the situation of mine laying .
					break;
				}
				else
				{
					// If it's not ray, continue 
					Unfold(mine, show, x, y,&count);
					Display(show, ROWS, COLS);
					printf("Continue......\n");
				}
			}
			else
				printf(" Illegal coordinates , Please re-enter \n");
		}
		if (count == 0)
		{
			printf(" congratulations \n");
			Display(show, ROWS, COLS);
		}
	}

( 3、 ... and )text.c

#define _CRT_SECURE_NO_WARNINGS

// Mine clearance 
#include "game.h"
void menu()
{
	printf("********************\n");
	printf("*****  1.paly  *****\n");
	printf("*****  0.exit  *****\n");
	printf("********************\n");
}

void game()
{
	// Store mine information in mine in 
	char mine[ROW][COL] = { 0 };
	// Store the displayed information in show in 
	char show[ROW][COL] = { 0 };
	// Bray's chessboard is initialized to 0
	Initboard(mine, ROW, COL, '0');
	// The displayed chessboard is initialized to *
	Initboard(show, ROW, COL, '*');
	// Bure 
	Setting(mine, ROWS, COLS);
	// Print chessboard 
	Display(show, ROWS, COLS);
	// screening 
	Guess(mine, show, ROWS, COLS);
}



int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf(" Please select (1/0):>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf(" Start the game \n");
			game();
			break;
		case 0:
			printf(" Quit the game \n");
			break;
		default:
			printf(" Input error , Please re-enter \n");
		}
	} while (input);
	return 0;
}

原网站

版权声明
本文为[It's Wang Jiujiu]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207060916176622.html