扫雷游戏的的实现机制
扫雷游戏的玩法
左键点开网格,若该网格为雷则失败;
若该网格周边八个网格中有雷,则显示雷数,
直至排查完所有的空地方,则为胜利!!!
扫雷游戏的设计思路
1.我们可以尝试设计两个char类型的二维数组,其一(假设为show数组)是以"*“所覆盖的初始界面;其二(假设为mine数组)是以"0”,"1"所构成的隐藏地雷界面,其中"1"为地雷,"0"为无雷区,因为这样可以让我们方便计算无雷区周围的地雷个数。
2.我们可以利用输入坐标的方式来确定我们所要选择的方块。
3.我们可以在玩家选择方块后,若方块为雷,则游戏失败;若不为雷,则显示周围雷的数量。
代码实现
1,首先,我们先创造一个头文件,以便与多个源文件的运行:
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<Windows.h>
#define row 9
#define col 9
#define rows row+2
#define cols col+2
#define EASY 10
在这里我们创建的头文件以后也可进行扫雷个数与扫雷规模的改变,本文以9X9规格,10个雷举例。
row表示几行,col表示几列,EASY表示几个雷。
2,接下来,我们再创建一个源文件(test.c)用来进行逻辑的表达:
#include "add.h"
void game()
{
char show[rows][cols];
char mine[rows][cols];
now(show, rows, cols, '*');
now(mine, rows, cols, '0');
//初始化表格show用来展现给玩家看,mine用来记录雷的位置,不打印给玩家看
print(show, row, col);
//打印show
joinmine(mine, rows, cols);
//随机存放放雷
judgment(show, mine, row, col);
//玩家输入位置后,进行判断是否正确
}
int main()
{
int choose = 0;
srand((unsigned int)time(NULL));
do
{
menu();
//打印游戏界面菜单
scanf("%d", &choose);
switch (choose)
{
case 1:
game();
//进入到游戏中
break;
case 0:
printf("结束游戏\n");
break;
default:
printf("输入错误\n");
break;
}
//选择开始与否
last();
} while (choose);
return 0;
}
3,现在我们再来对以上逻辑尽心实现:
A,menu菜单的打印:
void menu()
{
printf("**********扫雷游戏**********\n");
printf("********1.play game*********\n");
printf("********2.game over*********\n");
printf("****************************\n");
printf("请输入你的选择-->>");
}
B,now初始化函数:
void now(char show[rows][cols], int n, int m, char set)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
show[i][j] = set;
}
C,print打印函数:
void print(char show[rows][cols], int n, int m)
{
for (int i = 0; i <= m; i++)
printf("%3d ", i);
printf("\n");
for (int i = 1; i <= n; i++)
{
printf("%3d ", i);
for (int j = 1; j <= m; j++)
printf("%3c ", show[i][j]);
printf("\n");
}
printf("-----------------------------\n");
}
//如果布局大于999,请自行更改%后的数字,以便取得最佳体验
D,joinmine随机放置雷的函数:
void joinmine(char mine[rows][cols], int n, int m)
{
int choose = EASY;
while (choose)
{
int i = rand() % row + 1;
int j = rand() % col + 1;
if (mine[i][j] == '0')
{
mine[i][j] = '1';
choose--;
}
}
}
E,judgment输入坐标与判断胜利函数:
void judgment(char show[rows][cols], char mine[rows][cols], int n, int m)
{
int i = 0, j = 0;
while (1)
{
int ture = 0;
int rw = 1, cl = 1;
for (rw = 1; rw <= row; rw++)
for (cl = 1; cl <= col; cl++)
if (show[rw][cl] == '*')
ture++;
if (ture == EASY)
{
voct();//胜利界面
break;
}//判断是否胜利的条件
else
printf("*********你还需查明%d个位置**********\n", ture - 10);
printf("请输入坐标:>>");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j > 0 && j <= col)
{
if (mine[i][j] == '1')
{
fail();
break;
}//失败界面
else
{
plus_count(show, mine, i, j);//坐标无雷时进入
print(show, n, m);
}
}
else
printf("输入错误\n");
}
}
F,plus_count坐标无雷时的向外展开函数(实现扫雷游戏的网络展开):
void plus_count(char show[rows][cols], char mine[rows][cols], int x, int y)
{
int c = 0;
c = count(mine, x, y);
if (c == 0)
{
show[x][y] = ' ';
int i = 0, j = 0;
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
if ((x + i) > 0 && (y + i) > 0 && (x + i < rows) && (y + j < cols) && show[x + i][y + j] == '*')
{
plus_count(show, mine, x + i, y + j);//利用递归进行探究
}
}
}
}
else
{
show[x][y] = c + '0';
}
}
G,count计算周围雷个数的函数:
int count(char mine[rows][cols],int i,int j)
{
return (mine[i - 1][j - 1] +
mine[i][j - 1] +
mine[i + 1][j - 1] +
mine[i + 1][j] +
mine[i + 1][j + 1] +
mine[i - 1][j] +
mine[i - 1][j + 1] +
mine[i][j + 1] - 8 * '0');
}
H,voct胜利界面与fail失败界面:
void voct()
{
printf("*********!!恭喜你!!***********");
printf("\n***********你赢了!!!***********\n");
}
void fail()
{
printf("*************失败!!!************\n");
print(mine, row, col);
//让玩家失败时明白雷的位置
printf("\n\n\n");
}
I,last清屏以便下局游戏:
void last()
{
int ans = 0;
printf("请输入任意数以继续——>>");
scanf("%d", &ans);
system("cls");
}
游戏执行
在VS2022下调试:
1,开始游戏并选择:1
2,输入坐标:5 5
(以下为运气好的情况下)
(以下为失败界面)
(以下为胜利界面)
全部代码呈现
add.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
#include<Windows.h>
#define row 10
#define col 10
#define rows row+2
#define cols col+2
#define EASY 10
test.c
#include "add.h"
void game()
{
char show[rows][cols];
char mine[rows][cols];
now(show, rows, cols, '*');
now(mine, rows, cols, '0');
print(show, row, col);
joinmine(mine, rows, cols);
judgment(show, mine, row, col);
}
void menu()
{
printf("**********扫雷游戏**********\n");
printf("********1.play game*********\n");
printf("********2.game over*********\n");
printf("****************************\n");
printf("请输入你的选择-->>");
}
int main()
{
int choose = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d", &choose);
switch (choose)
{
case 1:
game();
break;
case 2:
printf("结束游戏\n");
break;
default:
printf("输入错误\n");
break;
}
last();
} while (choose);
return 0;
}
game .c
#include"add.h"
void now(char show[rows][cols], int n, int m, char set)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
show[i][j] = set;
}
void print(char show[rows][cols], int n, int m)
{
for (int i = 0; i <= m; i++)
printf("%3d ", i);
printf("\n");
for (int i = 1; i <= n; i++)
{
printf("%3d ", i);
for (int j = 1; j <= m; j++)
{
printf("%3c ", show[i][j]);
}
printf("\n");
}
printf("-----------------------------\n");
}
void joinmine(char mine[rows][cols], int n, int m)
{
int choose = EASY;
while (choose)
{
int i = rand() % row + 1;
int j = rand() % col + 1;
if (mine[i][j] == '0')
{
mine[i][j] = '1';
choose--;
}
}
}
void voct()
{
printf("*********!!恭喜你!!***********");
printf("\n***********你赢了!!!***********\n");
}
void judgment(char show[rows][cols], char mine[rows][cols], int n, int m)
{
int i = 0, j = 0;
while (1)
{
int ture = 0;
int rw = 1, cl = 1;
for (rw = 1; rw <= row; rw++)
for (cl = 1; cl <= col; cl++)
if (show[rw][cl] == '*')
ture++;
if (ture == EASY)
{
voct();
break;
}
else
printf("*********你还需查明%d个位置**********\n", ture - 10);
printf("请输入坐标:>>");
scanf("%d %d", &i, &j);
if (i > 0 && i <= row && j > 0 && j <= col)
{
if (mine[i][j] == '1')
{
printf("*************失败!!!************\n");
print(mine, row, col);
printf("\n\n\n");
break;
}
else
{
plus_count(show, mine, i, j);//周围无雷时进入
print(show, n, m);
}
}
else
printf("输入错误\n");
}
}
int count(char mine[rows][cols],int i,int j)
{
return (mine[i - 1][j - 1] +
mine[i][j - 1] +
mine[i + 1][j - 1] +
mine[i + 1][j] +
mine[i + 1][j + 1] +
mine[i - 1][j] +
mine[i - 1][j + 1] +
mine[i][j + 1] - 8 * '0');
}
void last()
{
int ans = 0;
printf("请输入任意数以继续——>>");
scanf("%d", &ans);
system("cls");
}
plus_count.c
#include"add.h"
void plus_count(char show[rows][cols], char mine[rows][cols], int x, int y)
{
int c = 0;
c = count(mine, x, y);
if (c == 0)
{
show[x][y] = ' ';
int i = 0, j = 0;
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
if ((x + i) > 0 && (y + i) > 0 && (x + i < rows) && (y + j < cols) && show[x + i][y + j] == '*')
{
plus_count(show, mine, x + i, y + j);
}
}
}
}
else
{
show[x][y] = c + '0';
}
}
好了,以上就是本期的全部内容了,感谢观看!!!