[C language] implementation of mine sweeping

Posted by latvaustin on Wed, 24 Nov 2021 14:47:18 +0100

catalogue

1, Clear up logic

2, Create file

3, Specific steps

1. Print menu

2. Create a two-dimensional array

3. Initialize the two-dimensional array and print the chessboard

4. Lay lightning

  5. Mine investigation (including judgment of victory and defeat)

4, Complete code

5, To be improved

1, Clear up logic

Let's take a look at the basic logic of mine clearance

1. Print game menu

2. Create and initialize a two-dimensional array

3. Lay lightning

4. Demining

2, Create file

I created three files, test.c, game.h, and game.c

test.c file is used to realize the logic of entering the game, exiting the game, judging win or lose, printing menu, etc

game.c is used to write the main implementation method of the game

game.h stores header files and function declarations

3, Specific steps

1. Print menu

void menu() 
{
	printf("**********************************\n");
	printf("***********  1.start    **********\n");
	printf("***********  0. exit    **********\n");
	printf("**********************************\n");

}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please enter:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("The game begins\n");
			game();
			break;
		case 0:
			printf("game over\n");
			break;
		default :
			printf("illegal input,Please re-enter\n");
			break;
		}
	} while (input);
	
}

2. Create a two-dimensional array

Because we want to implement a 9 * 9 minesweeping, considering that the array is out of bounds, we need to create an 11 * 11 two-dimensional array,

Two two-dimensional arrays need to be created at the same time. Mine array is used to view the mine position and show array to show the demining process.

void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
}

3. Initialize the two-dimensional array and print the chessboard

#define _CRT_SECURE_NO_WARNINGS 1
#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


//Initialize 2D array
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//Print chessboard
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//Initialize 2D array
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//Print chessboard
	DisplayBoard(mine, ROW, COL);
	DisplayBoard(show, ROW, COL);
}
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

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

design sketch

4. Lay lightning

//Set mine
void setMine(char mine[ROWS][COLS], int row, int col);
void setMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (mine[x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

design sketch

  5. Mine investigation (including judgment of victory and defeat)

Players enter coordinates. If they step on thunder at this position, the game ends. If they do not step on thunder, the number of surrounding thunder will be displayed.

If all the squares except mine position are full, the game will win.

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

}
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row * col - EASY_COUNT)
	{
	printf("Enter coordinates:>");
	scanf("%d %d", &x, &y);
	if (x >= 1 && x <= row && y >= 1 && y <= col)
	{
	
			
			if (mine[x][y] == '1')
			{
				printf("Hahaha, you were killed!\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;

			}

		}
	else
	{
		printf("The coordinates entered are illegal. Please re-enter:>");
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("Congratulations on your success!\n");
		DisplayBoard(mine, ROW, COL);
	}
	}
	
}

4, Complete code

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#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


//Initialize 2D array
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
//Print chessboard
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//Set mine
void setMine(char mine[ROWS][COLS], int row, int col);
//Check thunder
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);


test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"
void game()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//Initialize 2D array
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//Print chessboard
	//DisplayBoard(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);
	//Set mine
	setMine(mine,ROW,COL);
	DisplayBoard(mine, ROW, COL);
	//DisplayBoard(show, ROW, COL);
	//mine clearance
	FindMine(mine,show, ROW, COL);


}
void menu() 
{
	printf("**********************************\n");
	printf("***********  1.start    **********\n");
	printf("***********  0. exit    **********\n");
	printf("**********************************\n");

}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("Please enter:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("The game begins\n");
			game();
			break;
		case 0:
			printf("game over\n");
			break;
		default :
			printf("illegal input,Please re-enter\n");
			break;
		}
	} while (input);
	
}

int main()
{
	test();
	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

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

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

}

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

}
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row * col - EASY_COUNT)
	{
	printf("Enter coordinates:>");
	scanf("%d %d", &x, &y);
	if (x >= 1 && x <= row && y >= 1 && y <= col)
	{
	
			
			if (mine[x][y] == '1')
			{
				printf("Hahaha, you were killed!\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;

			}

		}
	else
	{
		printf("The coordinates entered are illegal. Please re-enter:>");
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("Congratulations on your success!\n");
		DisplayBoard(mine, ROW, COL);
	}
	}
	
}

5, To be improved

When judging whether there is thunder around, the number of thunder around can be displayed in show, but in the above writing method, it can only be judged one by one. If the surrounding positions are all 0, it will be a waste of time to check them one by one.

We can quickly check through a method. First judge whether the coordinate has thunder. If not, first set the coordinate as a space, and then scan the surrounding conditions in the same way.

//Recursive demining
void count(char Show[ROWS][COLS], char Mine[ROWS][COLS], int x, int y)
{
	int i = 0;
	int j = 0;
	if (get_mine_count(Mine, x, y) == 0)
	{
		Show[x][y] = ' ';
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if (i > 0 && i <= ROW && j > 0 && j <= COL && Mine[i][j] != '1' && Show[i][j] == '*')
				{
					count(Show, Mine, i, j);
				}
			}
		}
	}
	else
		Show[x][y] = '0' + get_mine_count(Mine, x, y);
}

Topics: C