Use C language to implement (perfect) minesweeper

Table of contents

1. Game play and design concept

2. Code implementation of various functions

      1. Create a menu (menu --menu)

      2. Implementation of main function

      3. Create a chessboard and initialize it (initialization --initial)

      4. Print the chessboard (print--display)

      5. Arrange the location of the mine (arrangement---deposit)

      6. Check for mines (check---check)

----The identifier names in this article are all in English that express their meaning, making it easier for readers to understand! ------

3. Code summary

        1. test.c file

        2. game.c file

        3. game.h file


1. How to play the game

How to play the minesweeper game: Given a chessboard, we can check it according to the coordinate position we input. We can choose whether to clear the mines. If yes, mark the mines. Otherwise, continue. If there are mines at that position, we have not cleared the mines. Then Being blown up---the game is over; if it is not a mine, the number of surrounding mines will be displayed at the position. If there are no mines around the position, a blank display will be displayed. At the same time, the situation of the surrounding positions will be determined to be the same (here we use recursion to implement it); Continue to investigate-----The game is won when there is only thunder on the board!

   Design ideas:

        1. When creating and defining the chessboard, we print a 9*9 chessboard here, using a two-dimensional array!

        2. We need to create two chessboards, one for storing mines (background information), and one for storing information for detecting mines (displayed chessboard)!

        3. When initializing the chessboard, all chessboards that store thunder will store the character '0' first, and all display chessboards will store the character '*' first!

        4. Arrange thunder: randomly arranged by the computer - use the character '1' to represent thunder!

        5. Check for mines: It is up to the players to judge by themselves - use the character '#' to indicate the mark!

2. Implementation of each function code

 1. Create menu------

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

2. Implementation of main function-----

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择->\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

3. Create a chessboard and initialize----

      Create two two-dimensional arrays when creating:

#define ROW 9
#define COL 9

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

//创建存放雷的棋盘
char depositboard[ROWS][COLS] = { 0 };
//创建排查雷的棋盘
char checkboard[ROWS][COLS] = { 0 };

    Initialization of the chessboard:

//初始化棋盘
initboard(depositboard, ROWS, COLS,'0');
initboard(checkboard, ROWS, COLS, '*');


//初始化棋盘
void initboard(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}

4. Print the chessboard-----

//打印棋盘
displayboard(depositboard, ROW, COL);
printf("\n");
displayboard(checkboard, ROW, COL);

//打印棋盘
void displayboard(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");
	}
}

5. Arrange the location of the mine-----

//布置雷
depositray(depositboard, ROW, COL);
displayboard(depositboard, ROW, COL);

//布置雷
void depositray(char board[ROWS][COLS], int row, int col)
{
	int count = RAY;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

6. Check for mines-----

//排查雷
checkray(depositboard, checkboard, ROW, COL);

//算周围棋子数量
char raysum(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1]
		+ board[x][y - 1] + board[x][y + 1]
		+ board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1])-'0'*7;
}
//递归实现空白
int check(char board1[ROWS][COLS], char board2[ROWS][COLS], int x, int y,int* count)
{
	(*count)--;
	board2[x][y] = raysum(board1, x, y);
	int i = 0;
	int j = 0;
	if (board2[x][y] == '0')
	{
		board2[x][y] = ' ';
		for (i = x - 1; i <= x + 1; i++)
		{
			if (i >= 1 && i <= ROW)
			{
				for (j = y - 1; j <= y + 1; j++)
				{
					if (j >= 1 && j <= COL)
					{
						if (i != x || j != y || (i == x && j != y) || (i != x && j == y))
						{
							if(board2[i][j]=='*')
							check(board1, board2, i, j, count);
						}
					}
				}
			}
		}
	}
	return count;
}
//排查雷
void checkray(char board1[ROWS][COLS],char board2[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请排查->\n");
	int count =row*col- RAY;
	while (count)
	{
		int ray = 0;
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			printf("是否排雷?--1表示排雷--否则不排\n");
			scanf("%d", &ray);
			if (ray == 1)
			{
				system("cls");
				board2[x][y] = '#';
				displayboard(board2, ROW, COL);
			}
			else {
				if (board1[x][y] == '1')
				{
					printf("你已经被雷炸死了\n");
					displayboard(board1, ROW, COL);
					break;
				}
				else
				{
					system("cls");
					check(board1, board2, x, y, &count);
					displayboard(board2, ROW, COL);
				}
			}
		}
		else printf("输入非法,请重新输入->\n");
	}
	if (count == 0)
	{
		printf("恭喜你,扫雷成功!\n");
		displayboard(board1, ROW, COL);
	}
}

 Implementation of a function that counts the number of surrounding rays during this process----raysum()----

//算周围棋子数量
char raysum(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1]
		+ board[x][y - 1] + board[x][y + 1]
		+ board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1])-'0'*7;
}

In this process, a function that recursively extends the area is implemented ---check()---

//递归实现空白
int check(char board1[ROWS][COLS], char board2[ROWS][COLS], int x, int y,int* count)
{
	(*count)--;
	board2[x][y] = raysum(board1, x, y);
	int i = 0;
	int j = 0;
	if (board2[x][y] == '0')
	{
		board2[x][y] = ' ';
		for (i = x - 1; i <= x + 1; i++)
		{
			if (i >= 1 && i <= ROW)
			{
				for (j = y - 1; j <= y + 1; j++)
				{
					if (j >= 1 && j <= COL)
					{
						if (i != x || j != y || (i == x && j != y) || (i != x && j == y))
						{
							if(board2[i][j]=='*')
							check(board1, board2, i, j, count);
						}
					}
				}
			}
		}
	}
	return count;
}

3. Code summary

  1. test.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
	printf("**********************\n");
	printf("***     1.play    ****\n");
	printf("***     0.exit    ****\n");
	printf("**********************\n");
}

void game()
{
	//创建存放雷的棋盘
	char depositboard[ROWS][COLS] = { 0 };
	//创建排查雷的棋盘
	char checkboard[ROWS][COLS] = { 0 };

	//初始化棋盘
	initboard(depositboard, ROWS, COLS,'0');
	initboard(checkboard, ROWS, COLS, '*');
	//打印棋盘
	/*displayboard(depositboard, ROW, COL);
	printf("\n");*/
	displayboard(checkboard, ROW, COL);
	printf("\n");
	//布置雷
	depositray(depositboard, ROW, COL);
	displayboard(depositboard, ROW, COL);
	//排查雷
	checkray(depositboard, checkboard, ROW, COL);
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择->\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

2. game.c file

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
void initboard(char board[ROWS][COLS], int rows, int cols, char ret)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = ret;
		}
	}
}
//打印棋盘
void displayboard(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 depositray(char board[ROWS][COLS], int row, int col)
{
	int count = RAY;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;
		}
	}
}
//算周围棋子数量
char raysum(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1]
		+ board[x][y - 1] + board[x][y + 1]
		+ board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1])-'0'*7;
}
//递归实现空白
int check(char board1[ROWS][COLS], char board2[ROWS][COLS], int x, int y,int* count)
{
	(*count)--;
	board2[x][y] = raysum(board1, x, y);
	int i = 0;
	int j = 0;
	if (board2[x][y] == '0')
	{
		board2[x][y] = ' ';
		for (i = x - 1; i <= x + 1; i++)
		{
			if (i >= 1 && i <= ROW)
			{
				for (j = y - 1; j <= y + 1; j++)
				{
					if (j >= 1 && j <= COL)
					{
						if (i != x || j != y || (i == x && j != y) || (i != x && j == y))
						{
							if(board2[i][j]=='*')
							check(board1, board2, i, j, count);
						}
					}
				}
			}
		}
	}
	return count;
}
//排查雷
void checkray(char board1[ROWS][COLS],char board2[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请排查->\n");
	int count =row*col- RAY;
	while (count)
	{
		int ray = 0;
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			printf("是否排雷?--1表示排雷--否则不排\n");
			scanf("%d", &ray);
			if (ray == 1)
			{
				system("cls");
				board2[x][y] = '#';
				displayboard(board2, ROW, COL);
			}
			else {
				if (board1[x][y] == '1')
				{
					printf("你已经被雷炸死了\n");
					displayboard(board1, ROW, COL);
					break;
				}
				else
				{
					system("cls");
					check(board1, board2, x, y, &count);
					displayboard(board2, ROW, COL);
				}
			}
		}
		else printf("输入非法,请重新输入->\n");
	}
	if (count == 0)
	{
		printf("恭喜你,扫雷成功!\n");
		displayboard(board1, ROW, COL);
	}
}

3. game.h file

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9

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

#define RAY 2
//初始化棋盘
void initboard(char board[ROWS][COLS], int row, int col, char ret);
//打印棋盘
void displayboard(char board[ROWS][COLS], int row, int col);
//布置雷
void depositray(char board[ROWS][COLS], int row, int col);
//排查雷
void checkray(char board1[ROWS][COLS],char board2[ROWS][COLS], int row, int col);

Hehe, take your time, step by step, don’t be anxious, think well, if this article has inspired you, give me a "one-click three-in-one"

Okay, that’s it. Goodbye!

Guess you like

Origin blog.csdn.net/m0_71676870/article/details/130597547