当前位置:网站首页>C language 300 lines of code to achieve mine sweeping (deployable + markable + changeable difficulty level)
C language 300 lines of code to achieve mine sweeping (deployable + markable + changeable difficulty level)
2022-07-29 01:28:00 【Australopithecus northerner】
List of articles
Preface
Minesweeping is a classic game , It is a puzzle game , stay 80、90 The s was all the rage , Of course, it is also very popular now ;
I don't say much nonsense ;
Let's learn how to use C Language to achieve it !!!(*´◡`*)
Running environment :VS2019
One 、 Main idea ?
First implement a preliminary version :
1、 We have to have a 9*9 The chessboard of ;
2、 We set it on the chessboard 10 Thunder ;
3、 Search for thunder around , And check the thunder ;
4、 Judgement of winning or losing ;
This is the main general idea ; Next, let's solve it in turn !!!
Two 、 Generate a chessboard
First, since we want to generate 99 The chessboard of , The two-dimensional array is not running !!!
Although it seems that we are going to generate a 99 The chessboard of , But in fact, if we really generate 99 Is your chessboard really convenient ?
In fact, it is not so convenient ;
Suppose we generate a 99 The chessboard of , Every time we judge the situation of thunder around a position, it is very complicated , It's ok if we want to row closer to the middle , Don't worry about the problem of array out of bounds ; But our position is not close to the center , Instead, it is on the edge , Every time we search for the thunder around it, do we have to judge whether the array has crossed the boundary , Only then do the statistics of Lei , It's quite troublesome . So is there any good way to solve the problem of array cross-border and facilitate Ray's statistics ?
Since you can't really generate one 99 The chessboard of , Then we will generate a pseudo , We make a 1111 How are you ?
We put the real chessboard inside ; Let's keep it outside , It is convenient to count the number of Mines later ;
In this way, we can easily complete the statistics of thunder at the edge and corner , Don't worry about crossing the border , What a beautiful thing ;
Well, now the chessboard has , We have to show it to players ! We directly show the thunder disk to players ? Of course not. ? Let's open another chessboard , Specially for players ; If we don't open a chessboard , What players see must not be thunder plates, right ? Then do we have to put a layer on the chessboard ” lock “ To hide mines, right ? But if we really operate like this , Our thunder will be ours “ lock ” It's gone , There's no thunder, and I'm still sweeping a fart ! In that case , We should open up one that is exactly the same size as Lei pan “ Lock disc ”, To map with the thunder disk , Our lock plate can be used to record “ lock ”, Check the situation of thunder around the location 、 And marking ;
Something like this ;
Let's define two checkerboards :
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
For subsequent convenience, we define rows and columns as macros , It is convenient for later code maintenance and level selection ;
Now that there is a chessboard , It must be initialized ;
mine Array ( Not shown to players ) When there are no mines , Initialize all to spaces , When there is thunder, change the space to # That's it ;
show Array ( Show the player ) The first time you show it to players, it should all be initialized to * To lock the thunder plate ; Later, we will replace it in turn according to the demining situation ;
Initialization function :
void init_board(char a[][COLS], int r, int c, char set)// To be initialized set Initialized characters
{
int i = 1;
int j = 1;
for (i = 1; i <= r; i++)
{
for (j = 1; j <= c; j++)
{
a[i][j] = set;
}
}
}
Now that the initialization is complete : Then we have to print it out :
So we are writing a function to print the chessboard :
void display_board(char a[][COLS], int r, int c)
{
int i = 1;
int j = 1;
printf(" ");
for (j = 0; j <= c; j++)// This time print column labels
{
if(j<10)
printf("%d ",j);
else
{
printf("%c ",'A'+j-10);// exceed 10, Automatic use 16 Hexadecimal said ;
}
}
putchar('\n');
for (j = 0; j <= c; j++)// Print landscape , Separate the chessboard from the column marks ;
{
printf("--");
}
putchar('\n');
for (i = 1; i <= r; i++)// This is when you start printing array elements ;
{
if (i < 10)// Before each print , Print the horizontal mark first ;
printf("%d| ", i);
else
{
printf("%c| ", 'A' + i - 10);
}
for (j = 1; j <= c; j++)//
{
printf("%c ",a[i][j]);
}
printf("\n");
}
}
design sketch :
3、 ... and 、 Lay out mines
Now that the chessboard for players to see and store mines is ready , Then we should go inside the thunder plate to protect against lightning ;
Lightning protection must be random , We don't know : Then you must use rand() To generate random numbers , So our lightning protection function can be written :
void set_mine(char mine[][COLS], int r, int c,int count)
{
int x = 0;
int y = 0;
while (count)
{
x = rand() % r + 1;
y = rand() % c + 1;
if (mine[x][y] == ' ')
{
mine[x][y] = '#';
count--;
}
}
}
Of course, for the convenience of follow-up, we choose to define the number of mines in the form of macros :
Let's run it to see if it really exists 10 A mine :
It's no problem to count , There is no place for the program bug, Then write down ;
Four 、 Mine screening
Now that the mines have been laid out , Then we should check the mines ;
How can we check ?
The legal coordinates of our corresponding points should be entered >
The coordinates we entered should not have been checked >
If all the above are met , Let's decide whether to mark , If we type Y Indicates that we need to mark the coordinates , Entering other characters does not require marking by default >
If we meet all the above , We also marked it , And the next location happens to be a mine , Then the game ends directly ; If this location is not a mine , Then this location will be replaced by the number of mines around the location ( Does not include the location ), Of course, in such cases , The number of mines around this location is 0, Then we can show all around this location , If the surrounding position of the position meets the above conditions , Continue to expand , Until it cannot be expanded ( So we can use recursion to describe the situation like this );( Similar to the following picture )
So our code can be written like this :
void find_mine(char show[][COLS],char mine [][COLS], int r, int c)// See if you can optimize ;
{
int x = 0;
int y = 0;
char ch = 0;
while (1)
{
printf(" Please enter the location you want to check , And choose whether to identify the point (Y\\ Others are not marked by default )>");// Marking the same point multiple times will cancel the marking ;
scanf("%d %d %c", &x, &y,&ch);
if (x >= 1 && x <= r && y >= 1 && y <= c)// Coordinates are legal
{
if (!is_find(show, x, y))// Not checked
{
if (show[x][y] == 'M' && 'Y' == ch)
{
show[x][y] = '*';
printf(" Unmark succeeded \n");
system("cls");
display_board(show,r,c);
break;
}
if ('Y' == ch)// Determine whether you need to mark ;
{
show[x][y] = 'M';
printf(" Mark successful \n");
system("cls");
display_board(show, r, c);
break;
}
else
{
if (is_mine(mine, x, y))// This location is mine
{
printf(" You were killed by thunder \n\a\a\a");
show[x][y] = '#';// Show the return visit of the bombing
flag = 0;
system("cls");
display_board(mine, r, c);
break;
}
else// It's not ray
{
surprise(mine, show, r, c, x, y);// Further judge the number of mines around the location , if 0, Further development
system("cls");
display_board(show, r, c);
break;
}
}
}
else
{
printf(" The coordinates have been checked , Please re-enter :>\n");
}
}
else
printf(" Illegal coordinates , Please re-enter \n");
}
}
int get_mine(char show[][COLS], char mine[][COLS], int x, int y)// return (x,y) Number of mines around the location
{
int count = 0;
if (mine[x - 1][y - 1] == '#')
count++;
if (mine[x - 1][y] == '#')
count++;
if (mine[x - 1][y + 1] == '#')
count++;
if (mine[x ][y - 1] == '#')
count++;
if (mine[x][y + 1] == '#')
count++;
if (mine[x +1][y - 1] == '#')
count++;
if (mine[x + 1][y] == '#')
count++;
if (mine[x + 1][y + 1] == '#')
count++;
return count;// If you still have a better way to count mines , You can do it your own way , Bloggers are stupid , But it's easy to understand
}
bool is_mine(char mine[][COLS], int x, int y)// Judge (x,y) Is the location a mine
{
if (mine[x][y] == ' ')
return false;
return true;
}
bool is_find(char show[][COLS], int x, int y)// Judge (x,y) Whether the location has been checked
{
if (show[x][y] == '*'|| show[x][y] == 'M')
return false;
return true;
}
void surprise(char mine[][COLS], char show[][COLS], int r, int c, int x, int y)
{
if (!(x >= 1 && x <= r && y >= 1 && y <= c))// To prevent cross-border ;
return;
if (is_mine(mine, x, y) ||is_find(show, x, y))// Conditions for expansion :1、 Not checked ;2、 The location of the screening is not thunder
return;
setp--;// If the position is not thunder , Then the maximum number of steps -1;
int count = get_mine(show, mine, x, y);//3、 Check that there is no thunder around the location ;
show[x][y] = count + '0';// Convert numbers to numeric characters
if (count == 0)
{
surprise(mine, show, r, c, x - 1, y - 1);// Eight corners unfold in turn
surprise(mine, show, r, c, x - 1, y);
surprise(mine, show, r, c, x - 1, y + 1);
surprise(mine, show, r, c, x, y - 1);
surprise(mine, show, r, c, x, y + 1);
surprise(mine, show, r, c, x + 1, y - 1);
surprise(mine, show, r, c, x + 1, y);
surprise(mine, show, r, c, x + 1, y + 1);
}
}
5、 ... and 、 Judgement of winning or losing
In order to judge whether I win or lose, I define two global variables to represent :
So we can write the code to judge whether we win or lose :
void game()
{
char mine[ROWS][COLS] = {
0 };
char show[ROWS][COLS] = {
0 };
init_board(mine,ROW,COL,' ');// initialization
init_board(show, ROW, COL, '*');// initialization
set_mine(mine, ROW, COL, MINE_COUNT);// Arrange thunder
//display_board(mine, ROW, COL);// Open perspective
display_board(show, ROW, COL);// Display chessboard ( Show players );
while (setp&&flag)
{
find_mine(show, mine, ROW, COL);
}
if (!setp)
{
system("cls");
printf(" Challenge success \n");
}
else if(!flag)
{
system("cls");
printf(" Challenge failure \n");
}
display_board(show, ROW, COL);// Display chessboard ( Show players );
for (int j = 0; j <= COL; j++)
{
printf("--");
}
putchar('\n');
display_board(mine,ROW,COL);
}
So far, the game has been completed :
Let's finally knock main Function makes the game live :
void menu()
{
printf("********** Minesweeping games ********* "); printf(" Introduction to the game \n");
printf("******** 1. play ******** "); printf("1、 Mark the same point twice , Unmark .\n");
printf("******** 0. exit ******** "); printf("2、 The last input position is mine , Then the position will be marked # To tell the player the cause of death .\n");
printf("********************************* "); printf("3、 If you enter Y Then it means marking the point , Others are not marked by default .\n");
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf(" Please select :>");
scanf("%d", &input);
switch (input)
{
case PLAY:
system("cls");
game(); break;
case EXIT:
system("cls"); printf(" Quit the game \n"); break;
default:
system("cls"); printf(" Incorrect input , Re input :>\n"); break;
}
} while (input);
return 0;
}
6、 ... and 、 The final code
Header files and declarations :
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<stdbool.h>
#define MINE_COUNT 80// Number of Mines
#define ROW 9//
#define COL 9// Change the difficulty of these three transformations ;
#define ROWS ROW+2
#define COLS COL+2
enum CHOOSE
{
EXIT,
PLAY,
};
extern int flag;
extern int setp;
void init_board(char a[][COLS], int r, int c, char set);// Initialize chessboard
void display_board(char a[][COLS], int r, int c);// Print chessboard
void set_mine(char mine[][COLS], int r, int c,int count);// Arrange thunder
void find_mine(char show[][COLS], char mine[][COLS], int r, int c);// Check the thunder ;
int get_mine(char show[][COLS], char mine[][COLS], int r, int c);// Get the number of Mines
bool is_mine(char mine[][COLS], int x, int y);// Judge x,y Is it thunder ;
bool is_find(char show[][COLS], int x, int y);// Judge whether it has been checked
void surprise(char mine[][COLS], char show[][COLS], int r, int c, int x, int y);// Spread out a piece of
Implementation of main functions :
#define _CRT_SECURE_NO_WARNINGS 0
#include "game.h"
#pragma warning (disable:6031)
void init_board(char a[][COLS], int r, int c, char set)
{
int i = 1;
int j = 1;
for (i = 1; i <= r; i++)
{
for (j = 1; j <= c; j++)
{
a[i][j] = set;
}
}
}
void display_board(char a[][COLS], int r, int c)
{
int i = 1;
int j = 1;
printf(" ");
for (j = 0; j <= c; j++)
{
if(j<10)
printf("%d ",j);
else
{
printf("%c ",'A'+j-10);
}
}
putchar('\n');
for (j = 0; j <= c; j++)
{
printf("--");
}
putchar('\n');
for (i = 1; i <= r; i++)
{
if (i < 10)
printf("%d| ", i);
else
{
printf("%c| ", 'A' + i - 10);
}
for (j = 1; j <= c; j++)
{
printf("%c ",a[i][j]);
}
printf("\n");
}
}
void set_mine(char mine[][COLS], int r, int c,int count)
{
int x = 0;
int y = 0;
while (count)
{
x = rand() % r + 1;
y = rand() % c + 1;
if (mine[x][y] == ' ')
{
mine[x][y] = '#';
count--;
}
}
}
void find_mine(char show[][COLS],char mine [][COLS], int r, int c)// See if you can optimize ;
{
int x = 0;
int y = 0;
char ch = 0;
while (1)
{
printf(" Please enter the location you want to check , And choose whether to identify the point (Y\\ Others are not marked by default )>");// Marking the same point multiple times will cancel the marking ;
scanf("%d %d %c", &x, &y,&ch);
if (x >= 1 && x <= r && y >= 1 && y <= c)// Coordinates are legal
{
if (!is_find(show, x, y))// Not checked
{
if (show[x][y] == 'M' && 'Y' == ch)
{
show[x][y] = '*';
printf(" Unmark succeeded \n");
system("cls");
display_board(show,r,c);
break;
}
if ('Y' == ch)// Determine whether you need to mark ;
{
show[x][y] = 'M';
printf(" Mark successful \n");
system("cls");
display_board(show, r, c);
break;
}
else
{
if (is_mine(mine, x, y))// This location is mine
{
printf(" You were killed by thunder \n\a\a\a");
show[x][y] = '#';// Show the return visit of the bombing
flag = 0;
system("cls");
display_board(mine, r, c);
break;
}
else// It's not ray
{
surprise(mine, show, r, c, x, y);// Further judge the number of mines around the location , if 0, Further development
system("cls");
display_board(show, r, c);
break;
}
}
}
else
{
printf(" The coordinates have been checked , Please re-enter :>\n");
}
}
else
printf(" Illegal coordinates , Please re-enter \n");
}
}
int get_mine(char show[][COLS], char mine[][COLS], int x, int y)
{
int count = 0;
if (mine[x - 1][y - 1] == '#')
count++;
if (mine[x - 1][y] == '#')
count++;
if (mine[x - 1][y + 1] == '#')
count++;
if (mine[x ][y - 1] == '#')
count++;
if (mine[x][y + 1] == '#')
count++;
if (mine[x +1][y - 1] == '#')
count++;
if (mine[x + 1][y] == '#')
count++;
if (mine[x + 1][y + 1] == '#')
count++;
return count;
}
bool is_mine(char mine[][COLS], int x, int y)
{
if (mine[x][y] == ' ')
return false;
return true;
}
bool is_find(char show[][COLS], int x, int y)
{
if (show[x][y] == '*'|| show[x][y] == 'M')
return false;
return true;
}
void surprise(char mine[][COLS], char show[][COLS], int r, int c, int x, int y)
{
if (!(x >= 1 && x <= r && y >= 1 && y <= c))// To prevent cross-border ;
return;
if (is_mine(mine, x, y) ||is_find(show, x, y))// Conditions for expansion :1、 Not checked ;2、 The location of the screening is not thunder
return;
setp--;
int count = get_mine(show, mine, x, y);//3、 Check that there is no thunder around the location ;
show[x][y] = count + '0';
if (count == 0)
{
surprise(mine, show, r, c, x - 1, y - 1);
surprise(mine, show, r, c, x - 1, y);
surprise(mine, show, r, c, x - 1, y + 1);
surprise(mine, show, r, c, x, y - 1);
surprise(mine, show, r, c, x, y + 1);
surprise(mine, show, r, c, x + 1, y - 1);
surprise(mine, show, r, c, x + 1, y);
surprise(mine, show, r, c, x + 1, y + 1);
}
}
main function :
#define _CRT_SECURE_NO_WARNINGS 0
#include"game.h"
#pragma warning (disable:6031)
//1、 Leipan , Display panel
//2、 Initialize thunder disk and display disk // Blank space means no thunder # It means ray ;* Initialize the display tray
//3、 Print the chessboard ;
//4、 Arrange thunder ;
//5、 Check the thunder ;( Pay attention to trigger surprise )
int setp = ROW * COL - MINE_COUNT;// Record the maximum number of demining steps ; When setp be equal to 0 It means that the safe position has been arranged , Challenge success
int flag = 1;// It means that the game ends without being killed by a mine , The mine blew up and ended the game flag=0, Challenge failure ;
void game()
{
char mine[ROWS][COLS] = {
0 };
char show[ROWS][COLS] = {
0 };
init_board(mine,ROW,COL,' ');// initialization
init_board(show, ROW, COL, '*');// initialization
set_mine(mine, ROW, COL, MINE_COUNT);// Arrange thunder
//display_board(mine, ROW, COL);// Open perspective
display_board(show, ROW, COL);// Display chessboard ( Show players );
while (setp&&flag)
{
find_mine(show, mine, ROW, COL);
}
if (!setp )
{
system("cls");
printf(" Challenge success \a\a\a\a\n");
}
else if(!flag)
{
system("cls");
printf(" Challenge failure \a\a\a\n");
}
display_board(show, ROW, COL);// Display chessboard ( Show players );
for (int j = 0; j <= COL; j++)
{
printf("--");
}
putchar('\n');
display_board(mine,ROW,COL);
}
void menu()
{
printf("********** Minesweeping games ********* "); printf(" Introduction to the game \n");
printf("******** 1. play ******** "); printf("1、 Mark the same point twice , Unmark .\n");
printf("******** 0. exit ******** "); printf("2、 The last input position is mine , Then the position will be marked # To tell the player the cause of death .\n");
printf("********************************* "); printf("3、 If you enter Y Then it means marking the point , Others are not marked by default .\n");
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf(" Please select :>");
scanf("%d", &input);
switch (input)
{
case PLAY:
system("cls");
game(); break;
case EXIT:
system("cls"); printf(" Quit the game \n"); break;
default:
system("cls"); printf(" Incorrect input , Re input :>\n"); break;
}
} while (input);
return 0;
}
边栏推荐
- 【SQL之降龙十八掌】01——亢龙有悔:入门10题
- Connect with Alipay payment
- (update 20211130) about the download and installation of Jupiter notebook and its own configuration and theme
- Regular checksum time formatting
- Bracket matching test
- 【mysql】多指标历史累计去重问题
- Canal实时解析mysql binlog数据实战
- Y80. Chapter 4 Prometheus big factory monitoring system and practice -- Kube state metrics component introduction and monitoring extension (XI)
- nep 2022 cat
- [MySQL] historical cumulative de duplication of multiple indicators
猜你喜欢

一文读懂Okaleido Tiger近期动态,挖掘背后价值与潜力

J9数字论:什么因素决定NFT的价值?

【idea】查询字段使用位置

Hilbert transform and instantaneous frequency

C语言300行代码实现扫雷(可展开+可标记+可更改困难级别)

How to implement the time impact analysis of the construction project?

【Jenkins笔记】入门,自由空间;持续集成企业微信;allure报告,持续集成电子邮件通知;构建定时任务

地下水、土壤、地质、环境人看过来

教你一文解决 js 数字精度丢失问题

Oozie job scheduling
随机推荐
How to deal with the time, scope and cost constraints in the project?
Common functions and usage of numpy
Beginner's Guide to electronic bidding
一文搞懂ES6基本全部语法
A ten thousand word blog post takes you into the pit. Reptiles are a dead end [ten thousand word pictures]
Introduction to FLV documents
[MySQL] historical cumulative de duplication of multiple indicators
log4j动态加载配置文件
数字孪生轨道交通:“智慧化”监控疏通城市运行痛点
RHCE command practice (II)
Flask reports an error: pymysq1.err OperationalError:(1054, “Unknown column ‘None‘ in ‘field list‘“)
Solid smart contract tutorial (5) -nft auction contract
[ManageEngine] help Harbin Engineering University realize integrated monitoring and management of network traffic
Tupu software appeared at the 2022 Fuzhou digital Expo to jointly create a new digital era
This article enables you to understand the underlying principle of MySQL- Internal structure, index, lock, cluster
DocuWare 移动劳动力解决方案可帮助您构建新的生产力模式:随时随地、任何设备
Flink Postgres CDC
Error installing mysqlclient module on MAC system
Oozie job scheduling
20220728 sorting strings that are not pure numbers