当前位置:网站首页>Can recursion still play like this? Recursive implementation of minesweeping game
Can recursion still play like this? Recursive implementation of minesweeping game
2022-07-24 07:06:00 【Bubble milk】
🥳🥳🥳 Hello, everyone , Must be C In language learning , I always want to realize some small projects by myself , that , Today, I will lead you to realize a Minesweeping games Well .
If you are interested in other games, you can have a look C Language implementation of the three Gobang ? gobang ? No , yes n Ziqi
If you want to know more C Small knowledge of language is also ok Focus on My blog φ(゜▽゜)**
Let's take a look at today's content
The main realization of the function :
We can judge the number of mines near a coordinate
Markers can be used to record the location of Mines
Select a coordinate , You can expand an invalid area ( Recursive implementation )
design sketch :
List of articles
The header file mine_clear.h
#pragma once
#ifndef MINE_CLEAR_H
#define MINE_CLEAR_H
// Determine the size of the chessboard
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
// Determine the number of Mines
#define MINE 10
// Included header file
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Declaration of arrays
void mine_clear();
void InitBoard(char board[ROWS][COLS], char ch);
void DisplayBoard(char board[ROWS][COLS]);
void Setmine(char mine[ROWS][COLS]);
void ChectMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
void ShowMark(char show[ROWS][COLS], int x, int y, char set);
int IsWin(char show[ROWS][COLS]);
int IsMine(char mine[ROWS][COLS], int x, int y);
#endif
A careful partner must have found , When I determine the size of the thunder disk , There is one ROWS And a COLS What's the use of this ?

Suppose this is a 9*9 Mine sweeping plate , When we use Array When you visit the border , It may produce A cross-border visit , To avoid such a situation , We can choose to put the array Expand a circle , This can prevent the array from crossing the boundary when searching , As long as the redundant hidden edges are not displayed when displaying

The specific implementation of the game
In that case , How should we achieve it ? Just follow me and look down 🧐🧐
Main process test.c
#include "mine_clear.h"
void mine_clear()
{
int input = 0;
int x = 0;
int y = 0;
int mx = 0;// Mark with abscissa
int my = 0;// Mark with ordinate
char show[ROWS][COLS] = {
0 };// Display plate
char mine[ROWS][COLS] = {
0 };// Record Lei's disk
// Initialize chessboard
InitBoard(show, '*');
InitBoard(mine, '0');
// Set ray
Setmine(mine);
while (1)
{
system("cls");
DisplayBoard(show);
again:
printf("************************\n");
printf("* 1 -> Demining *\n");
printf("* 2 -> Mark *\n");
printf("* 3 -> Cancel mark *\n");
printf("************************\n");
printf("\t\t Please select >:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &x, &y);
ChectMine(mine, show, x, y);
break;
case 2:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &mx, &my);
ShowMark(show, mx, my, '#');
break;
case 3:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &mx, &my);
ShowMark(show, mx, my, '*');
break;
default:
printf(" Input error , Please input again \n");
goto again;
break;
}
DisplayBoard(show);
// Step on the thunder and exit directly
if (IsMine(mine, x, y))
{
printf(" Did you lose \n");
printf(" Retto \n");
DisplayBoard(mine);
break;
}
// Win and exit directly
if (IsWin(show))
{
printf(" You win \n");
DisplayBoard(mine);
break;
}
}
}
void menu()
{
printf("************************\n");
printf("**** 0. Quit the game *******\n");
printf("**** 1. Start the game *******\n");
printf("************************\n");
printf("\t\t Please select >:");
}
void Start()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 0:
break;
case 1:
mine_clear();
break;
default:
printf(" Input error , Please input again \n");
break;
}
} while (input);
}
int main()
{
Start();
return 0;
}
Be careful : Display with array and , The array size of the thunder disk should be the same ( The main purpose is to operate two arrays with one function )
Main function realization mine_clear.c
Initialize chessboard
// Initialize chessboard
void InitBoard(char board[ROWS][COLS], char set)
{
int i = 0;
for (i = 0; i < ROWS; i++)
{
int j = 0;
for (j = 0; j < COLS; j++)
{
board[i][j] = set;
}
}
}
Be careful : In order to achieve what kind of chessboard you want to initialize, you can initialize it into what kind of chessboard , We need a set To facilitate us to specify the appearance of the chessboard
The effect is as shown in the picture :
The printing of chessboard
You may be curious , How do I print the chessboard on it ( I don't care , You're curious )

// Print chessboard
void DisplayBoard(char board[ROWS][COLS])
{
int i = 0;
int j = 0;
printf("\n");
for (j = 0; j < COL+1; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i < ROW+1; i++)
{
printf("%d ", i);
for (j = 1; j < COL+1; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
** In order to make the selection of coordinates more Easy to watch , We can print the chessboard with Horizontal ordinate **
Setting of Mines
Single chessboard , No ray , That can also be called minesweeping ? So I need to generate some thunder , To demine people
The specific implementation is as follows :
// Set ray
void Setmine(char mine[ROWS][COLS])
{
srand((unsigned int)time(NULL));
for (int i = 0; i < MINE; i++)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
if (mine[y][x] == '0')
{
mine[y][x] = '1';
}
else if (mine[y][x] == '1')
{
i--;
}
}
}
We use the position of Lei character '1' Express , It can facilitate our subsequent programming
Recursive demining
// Check the number of Mines
static int get_mine_num(char mine[ROWS][COLS], int x, int y)
{
return mine[y - 1][x - 1] + mine[y - 1][x] + mine[y - 1][x + 1]
+ mine[y][x - 1] + mine[y][x + 1]
+ mine[y + 1][x - 1] + mine[y + 1][x] + mine[y + 1][x + 1] - 8*'0';
}
Used to check the number of Mines
thought :
Because we use character type when initializing , So we will be around 8 The numeric character corresponding to a dot ASCII value Add up , subtracting 8 * ‘ 0 ’, The result is equivalent to 8 The sum of integers
void ChectMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
char minenum = get_mine_num(mine, x, y) + '0';
if (show[y][x] == '*')
{
// If all 0 Just continue recursion
if (minenum == '0')
{
show[y][x] = '0';
ChectMine(mine, show, x-1, y-1);
ChectMine(mine, show, x, y-1);
ChectMine(mine, show, x+1, y-1);
ChectMine(mine, show, x-1, y);
ChectMine(mine, show, x+1, y);
ChectMine(mine, show, x-1, y+1);
ChectMine(mine, show, x, y+1);
ChectMine(mine, show, x+1, y+1);
}
// If one is greater than 0, will * become The number of mines
if (minenum > '0')
{
show[y][x] = minenum;
}
}
}
reflection :
- Go to 8 We can Recursion and show Array
- Expand outward when there is no thunder around
- If you want to implement recursion, you must first have Limiting conditions
- Recursion is bound to produce Duplicate query
Solution :
- Current detection location (show Array ) by
'*'when , To replace- When the number of surrounding mines detected is
0when , To continue to expand- If the number of surrounding mines is not
0, Then the number of mines is displayed in show Array On ( It mainly prevents one click minesweeping )
Be careful :
Don't make a mistake when expanding the input coordinates
Tag function
Marking can be said to be a less prominent role in the minesweeping game , Its main function is to prevent players touch by mistake or Wrong choice And exist , When recursive demining is carried out, it will also actively avoid the mark , It is very clear to design our marking function from this
// Mark
void ShowMark(char show[ROWS][COLS], int x, int y, char set)
{
if (set == '#')// Mark
{
if (show[y][x] == '*')
{
show[y][x] = '#';
}
else
{
printf(" Cannot mark here \n");
}
}
if (set == '*')// Cancel mark
{
if (show[y][x] == '#')
{
show[y][x] = '*';
}
else
{
printf(" Cannot unmark here \n");
}
}
}
When show Array Current position on by
'*'Only when marked ( Prevent invalid tags from causing BUG)When show Array Current position on by
'#'Only when Cancel mark ( Prevent invalid unmarking from causing BUG)
To judge whether to win
// To judge whether to win , Win and return 1 , No return 0
int IsWin(char show[ROWS][COLS])
{
int i = 0;
int j = 0;
int count = 0;
for (i = 1; i < ROW + 1; i++)
{
for (j = 1; j < COL + 1; j++)
{
if (show[i][j] == '*' || show[i][j] == '#')
{
count++;
}
}
}
if (count == MINE)
{
return 1;
}
else
{
return 0;
}
}
Judging to win, as long as the area not shown on our chessboard is equal to the number of mines, it can be said to win
Judge whether the current position is Lei
int IsMine(char mine[ROWS][COLS], int x, int y)
{
return mine[y][x] - '0';
}
Because we set Lei to character '1', So go straight back Subtract... From the current position '0' The value of can be used to judge whether it is true or false
Overall preview of the code
mine_clear.h
#pragma once
#ifndef MINE_CLEAR_H
#define MINE_CLEAR_H
// Determine the size of the chessboard
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
// Determine the number of Mines
#define MINE 10
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void mine_clear();
void InitBoard(char board[ROWS][COLS], char ch);
void DisplayBoard(char board[ROWS][COLS]);
void Setmine(char mine[ROWS][COLS]);
void ChectMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
void ShowMark(char show[ROWS][COLS], int x, int y, char set);
int IsWin(char show[ROWS][COLS]);
int IsMine(char mine[ROWS][COLS], int x, int y);
#endif
test.c
#include "mine_clear.h"
void mine_clear()
{
int input = 0;
int x = 0;
int y = 0;
int mx = 0;
int my = 0;
char show[ROWS][COLS] = {
0 };// Display plate
char mine[ROWS][COLS] = {
0 };// Record Lei's disk
// Initialize chessboard
InitBoard(show, '*');
InitBoard(mine, '0');
// Set ray
Setmine(mine);
while (1)
{
system("cls");
DisplayBoard(show);
again:
printf("************************\n");
printf("* 1 -> Demining *\n");
printf("* 2 -> Mark *\n");
printf("* 3 -> Cancel mark *\n");
printf("************************\n");
printf("\t\t Please select >:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &x, &y);
ChectMine(mine, show, x, y);
break;
case 2:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &mx, &my);
ShowMark(show, mx, my, '#');
break;
case 3:
printf("\t Please enter the coordinates (x, y)>:");
scanf("%d,%d", &mx, &my);
ShowMark(show, mx, my, '*');
break;
default:
printf(" Input error , Please input again \n");
goto again;
break;
}
DisplayBoard(show);
// Step on the thunder and exit directly
if (IsMine(mine, x, y))
{
printf(" Did you lose \n");
printf(" Retto \n");
DisplayBoard(mine);
break;
}
// Win and exit directly
if (IsWin(show))
{
printf(" You win \n");
DisplayBoard(mine);
break;
}
}
}
void menu()
{
printf("************************\n");
printf("**** 0. Quit the game *******\n");
printf("**** 1. Start the game *******\n");
printf("************************\n");
printf("\t\t Please select >:");
}
void Start()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 0:
break;
case 1:
mine_clear();
break;
default:
printf(" Input error , Please input again \n");
break;
}
} while (input);
}
int main()
{
Start();
return 0;
}
mine_clear.c
#include "mine_clear.h"
// Initialize chessboard
void InitBoard(char board[ROWS][COLS], char set)
{
int i = 0;
for (i = 0; i < ROWS; i++)
{
int j = 0;
for (j = 0; j < COLS; j++)
{
board[i][j] = set;
}
}
}
// Print chessboard
void DisplayBoard(char board[ROWS][COLS])
{
int i = 0;
int j = 0;
printf("\n");
for (j = 0; j < COL+1; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i < ROW+1; i++)
{
printf("%d ", i);
for (j = 1; j < COL+1; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
// Set ray
void Setmine(char mine[ROWS][COLS])
{
srand((unsigned int)time(NULL));
for (int i = 0; i < MINE; i++)
{
int x = rand() % COL + 1;
int y = rand() % ROW + 1;
if (mine[y][x] == '0')
{
mine[y][x] = '1';
}
else if (mine[y][x] == '1')
{
i--;
}
}
}
// Check the number of Mines
static int get_mine_num(char mine[ROWS][COLS], int x, int y)
{
return mine[y - 1][x - 1] + mine[y - 1][x] + mine[y - 1][x + 1]
+ mine[y][x - 1] + mine[y][x + 1]
+ mine[y + 1][x - 1] + mine[y + 1][x] + mine[y + 1][x + 1] - 8*'0';
}
void ChectMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
char minenum = get_mine_num(mine, x, y) + '0';
if (show[y][x] == '*')
{
// If all 0 Just continue recursion
if (minenum == '0')
{
show[y][x] = '0';
ChectMine(mine, show, x-1, y-1);
ChectMine(mine, show, x, y-1);
ChectMine(mine, show, x+1, y-1);
ChectMine(mine, show, x-1, y);
ChectMine(mine, show, x+1, y);
ChectMine(mine, show, x-1, y+1);
ChectMine(mine, show, x, y+1);
ChectMine(mine, show, x+1, y+1);
}
// If one is greater than 0, will * become The number of mines
if (minenum > '0')
{
show[y][x] = minenum;
}
}
}
// Mark
void ShowMark(char show[ROWS][COLS], int x, int y, char set)
{
if (set == '#')// Mark
{
if (show[y][x] == '*')
{
show[y][x] = '#';
}
else
{
printf(" Cannot mark here \n");
}
}
if (set == '*')// Cancel mark
{
if (show[y][x] == '#')
{
show[y][x] = '*';
}
else
{
printf(" Cannot unmark here \n");
}
}
}
// To judge whether to win , Win and return 1 , No return 0
int IsWin(char show[ROWS][COLS])
{
int i = 0;
int j = 0;
int count = 0;
for (i = 1; i < ROW + 1; i++)
{
for (j = 1; j < COL + 1; j++)
{
if (show[i][j] == '*' || show[i][j] == '#')
{
count++;
}
}
}
if (count == MINE)
{
return 1;
}
else
{
return 0;
}
}
int IsMine(char mine[ROWS][COLS], int x, int y)
{
return mine[y][x] - '0';
}
Be sure to look here
Now that you have seen here , I'm not going to Give a three company Do you ?
Even if there is no three consecutive , Give me a compliment , Leave your voice , Let me know how you are
The following is the author's illness , Minors please watch with adults
I want three company , Give me three straight , I can't bear it , There are no three companies , I'm going to be … ah … That won't be possible , It's going to break … fast … Give me three straight …
边栏推荐
- SparkSQL核心使用,220724,
- GE口:SGMII模式和serdes模式
- avaScript的流程控制语句
- UE4/5 无法打开文件“xxx.generated.h”(Cannot open file xxx.generated.h)的解决方法总结
- reflex
- 上传excel文件
- Jsonobject is sorted in A-Z order of key
- Record the pits encountered in the deserialization of phpserializer tool class
- [learning notes] see the difference between a+++a and a+a++ from the compilation
- 找工作备忘
猜你喜欢

重磅直播 | ORB-SLAM3系列代码讲解地图点(专题二)

SPI——发送16位和8位数据
![[learning notes] possible reasons and optimization methods for white screen on Web pages](/img/80/152a2827b0e653ebf2365c16ce3b40.png)
[learning notes] possible reasons and optimization methods for white screen on Web pages

Practice of online problem feedback module (12): realize image deletion function

10分钟就能写出来的——25~30K的国外企业招聘面试考题,这不是轻轻松松吗~

Redis.conf details
![(note sorting is not completed) [graph theory: find the shortest path of single source]](/img/58/e61aea3c4d0a33d3615144763160f7.png)
(note sorting is not completed) [graph theory: find the shortest path of single source]

xavier_ normal_ Initialization test

Sparksql core usage, 220724,

Upload excel file
随机推荐
Ge port: sgmii mode and SerDes mode
SparkSQL核心使用,220724,
[essays: discretization]
【学习笔记】从汇编看 a+++a与 a+a++的区别
使用root用户为创建新用户并设置密码
Penetration learning - SQL injection - shooting range - installation and bypass experiment of safety dog (it will be updated later)
一首伟大的赞歌
(note sorting is not completed) [graph theory: find the shortest path of single source]
Prompt for garbled code when CHM file is opened
[USB voltmeter and ammeter] Based on stm32f103c8t6 for Arduino
【学习笔记】网页出现白屏可能的原因与优化方法
Job search memo
Redis 哨兵机制
tensorflow boolean_mask函数
Nodejs enables multi process and inter process communication
先爱自己,再爱别人。
Requirements already satisfied: and read timed out. problem solving methods appear during the installation of snownlp package
OSS authorizes a single bucket permission
STM32H750VBT6驱动程控增益放大模块PGA113——基于CubeMX的Hal库
Redis special data type hyperloglog




