[C language] Minesweeper game (super detailed)


foreword

I wrote a mini-game of backgammon based on a two-dimensional array before, and now I can complete another mini-game - Minesweeper (level 9).
The general idea is as follows:

1. First create a menu option, select '1' to enter the game, select '0' to exit the game;
2. Initialize two identical boards, one for mine and one for show (both boards have eleven rows and eleven column); the mine board is the board related to mines, the position with mines is initialized to '1', the position without mines is initialized to '0', and the player is invisible; the show board belongs to the print board, initially all are initialized to '*', in The number on the show board printed out during the demining process indicates the total number of mines around the point.
3. Arrange mines on the mine board, obtain random numbers through the srand function, and use (x = rand() % row + 1 ; y = rand() % col + 1) to generate nine mine layout positions, and then arrange them On the nine rows and nine columns in the middle of the mine board (isn’t the chessboard with eleven rows and eleven columns initialized? At this time, the reason for choosing nine rows and nine columns is because there is a better calculation for the border of the board when checking mines. Otherwise, there is a possibility of out-of-bounds access) .
4. After the mine layout is completed, the minesweeping stage begins. Whenever a safe point is selected, the total number of mines will be counted on the eight positions around the point on the mine board, and the total number of mines will be assigned to the show board and the mine board In the corresponding position, it will be displayed to the player. If you step on the mine, the distribution of the mine on the first board will be displayed to the player.

1. Overall framework analysis of minesweeping

After entering the main function, first execute the menu print, and choose whether to play the game or exit according to the menu option. After selecting the game option, the first step is to initialize two chessboards, the second step is to arrange mines on the chessboard, and the third step is to To start demining, of course there is a function of printing a chessboard in the middle.

1. Overall framework construction

int main()
{
    
    
	system("color 5E");
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
    
    
		menu();
		printf("\t\t\t请选择:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case 1:
			game();
			break;
		case 0:
			printf("\n\n\t\t\t退出成功!\n");
			break;
		default:
			printf("\n\n\t\t\t选择错误,请重新输入!\n");
			Sleep(2000);
			system("cls");
		}

	} while (input);
	return 0;
}

It contains a srand function and a time timestamp function, which converts the return value of the time function into an unsigned int type and generates a random number through the srand function for subsequent mine layout.

2. Menu implementation

void menu()
{
    
    
	printf("\n\n\t\t\t-------------欢迎使用------------\n\n");
	printf("\t\t\t☆☆           扫雷          ☆☆\n\n");
	printf("\t\t\t☆☆          1.play         ☆☆\n\n");
	printf("\t\t\t☆☆          0.exit         ☆☆\n\n");
	printf("\t\t\t---------------------------------\n\n");
}

According to the prompt of the menu, the player can choose whether to continue playing the game or exit the game. After choosing 1, the player will enter the game interface.

3. Game implementation

#define ROWS 11  //初始化的行列
#define COLS 11
#define ROW 9  //打印的行列
#define COL 9
#define easy_count 9 //雷的数量

1. Board initialization

First, two chessboards have to be initialized. The distribution of mines inside the mine board is invisible to the player. The mine board will count the number of mines in the eight places around the non-mines and then assign them to the show board for the player to print, which is visible to the player.

char mine[ROWS][COLS] = {
    
     0 };
char show[ROWS][COLS] = {
    
     0 };
Init_board(mine, ROWS, COLS, '0');
Init_board(show, ROWS, COLS, '*');
void Init_board(char board[ROWS][ROWS], int rows, int cols, char s)
{
    
    
	for (int i = 0; i < rows; i++)
	{
    
    
		for (int j = 0; j < cols; j++)
		{
    
    
			board[i][j] = s;
		}
	}
}

This function initializes the chessboard with eleven rows and eleven columns through the parameter 's', and initializes all the first chessboard to 0, and initializes all the second chessboard to *.

2. Checkerboard printing

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

This function is to print out the middle nine rows and nine columns of the chessboard with eleven rows and eleven columns.

3. Arrange mines

Set_mine(mine, ROW, COL);
void Set_mine(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] != '1')
		{
    
    
			mine[x][y] = '1';
			count --;
		}
		
	}
}

This function is only for the mine board, and 9 mines are placed on the entire board.

4. Minesweeper

Find_mine(mine, show, ROW, COL);
//获取mine棋盘中非雷处的周围八处有多少个雷
int get_mine_num(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 Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    
    
	Display_board(show, ROW, COL);
	int x, y = 0;
	int win = 0;
	while (win < (row*col-easy_count))//已获取非雷处的数量
	{
    
    
		printf("\n\t\t\t请输入选择的位置:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
    
    
			if (show[x][y] == '*')//表示此处是否已经被排过 *代表还未排过
			{
    
    
				if (mine[x][y] != '1')//判断此处是否是雷 1代表雷
				{
    
    
					int num = get_mine_num(mine, x, y);
					show[x][y] = num + '0';
					win++;
				}
				else //踩中雷
				{
    
    
					system("cls");
					printf("\n\n\t\t\t--- Game Over! ---\n");
					Sleep(1000);
					Display_board(mine, ROW, COL);
					break;
				}
			}
			else
			{
    
    
				printf("\n\n\t\t\t该坐标已被排查过,请重新选择!\n");
				Sleep(1000);
			}
		}
		else
		{
    
    
			printf("\n\n\t\t\t输入错误,请重新选择!\n");
			Sleep(1000);
		}
		system("cls");
		Display_board(show, ROW, COL);
	}
	if (win == (row*col - easy_count))//当所有的非雷处都被您找出
	{
    
    
		printf("\t\t\t恭喜您,排雷成功!\n");
	}
	printf("\t\t\t3秒后自动退出至主页面\n");
	Sleep(3000);
	system("cls");
}

2. Source code display

1.test.c

#include "game.h"

void menu()
{
    
    
	printf("\n\n\t\t\t-------------欢迎使用------------\n\n");
	printf("\t\t\t☆☆           扫雷          ☆☆\n\n");
	printf("\t\t\t☆☆          1.play         ☆☆\n\n");
	printf("\t\t\t☆☆          0.exit         ☆☆\n\n");
	printf("\t\t\t---------------------------------\n\n");
}

void game()
{
    
    
	//初始化棋盘
	char mine[ROWS][COLS] = {
    
     0 };
	char show[ROWS][COLS] = {
    
     0 };
	//初始化棋盘
	Init_board(mine, ROWS, COLS, '0');
	Init_board(show, ROWS, COLS, '*');
	printf("\n\n\t\t\t2秒后进入游戏界面!\n");
	Sleep(2000);
	system("cls");
	//打印棋盘
	//Display_board(mine, ROW, COL);
	//Display_board(show, ROW, COL);
	//布置雷
	Set_mine(mine, ROW, COL);
	//Display_board(mine, ROW, COL);
	//排查雷
	Find_mine(mine, show, ROW, COL);
}



int main()
{
    
    
	system("color 5E");
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
    
    
		menu();
		printf("\t\t\t请选择:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case 1:
			game();
			break;
		case 0:
			printf("\n\n\t\t\t退出成功!\n");
			break;
		default:
			printf("\n\n\t\t\t选择错误,请重新输入!\n");
			Sleep(2000);
			system("cls");
		}

	} while (input);
	return 0;
}

2.game.c

#include "game.h"


void Init_board(char board[ROWS][ROWS], int rows, int cols, char s)
{
    
    
	for (int i = 0; i < rows; i++)
	{
    
    
		for (int j = 0; j < cols; j++)
		{
    
    
			board[i][j] = s;
		}
	}
}


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


void Set_mine(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] != '1')
		{
    
    
			mine[x][y] = '1';
			count --;
		}
		
	}
}

int get_mine_num(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 Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    
    
	Display_board(show, ROW, COL);
	int x, y = 0;
	int win = 0;
	while (win < (row*col-easy_count))
	{
    
    
		printf("\n\t\t\t请输入选择的位置:");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
    
    
			if (show[x][y] == '*')
			{
    
    
				if (mine[x][y] != '1')
				{
    
    
					int num = get_mine_num(mine, x, y);
					show[x][y] = num + '0';
					//Display_board(show, ROW, COL);
					win++;
				}
				else
				{
    
    
					system("cls");
					printf("\n\n\t\t\t--- Game Over! ---\n");
					Sleep(1000);
					Display_board(mine, ROW, COL);
					break;
				}
			}
			else
			{
    
    
				printf("\n\n\t\t\t该坐标已被排查过,请重新选择!\n");
				Sleep(1000);
			}
		}
		else
		{
    
    
			printf("\n\n\t\t\t输入错误,请重新选择!\n");
			Sleep(1000);
		}
		system("cls");
		Display_board(show, ROW, COL);
	}
	if (win == (row*col - easy_count))
	{
    
    
		printf("\t\t\t恭喜您,排雷成功!\n");
	}
	printf("\t\t\t3秒后自动退出至主页面\n");
	Sleep(3000);
	system("cls");
}

3.game.h

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

#define ROWS 11
#define COLS 11
#define ROW 9
#define COL 9
#define easy_count 9


void Init_board(char board[ROWS][ROWS], int rows, int cols, char s);

void Display_board(char board[ROWS][COLS], int row, int col);

void Set_mine(char mine[ROWS][COLS], int row, int col);

void Find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

Guess you like

Origin blog.csdn.net/weixin_47648037/article/details/127154195