目录
游戏思路
游戏展示
代码
文件
mine sweeping.h
mine sweeping.c
初始化
放雷
打印页面
查看坐标附件雷的个数
排雷
text.c
代码优化
展示
mine sweeping.h
mine sweeping.c
查看周围雷数
消除为0雷区
排雷
text.c
总结:
创建两个相同的数组,一个数组为玩家展示,一个数组个位置区别放置和不放置雷,方便统计玩家所选位置周围雷的个数,返回给玩家显示数组中。
数组的大小比实际展示的大两个长度,在不展示的区域放置非雷标志,在统计所选位置周围雷的个数时,可直接确定此位置无雷。
#pragma once
#include
#include
#include
#define Row 11
#define Line 11
void Initgame(char lag[Row][Line],char lag1);//初始化
int Putgame(char thunder[Row][Line]);//放雷
void Printchgame(char ch[Row][Line]);//打印玩家猜测雷区
void Removegame(char ch[Row][Line], char thunder[Row][Line], int n);//排雷
//初始化 ch—展示数组,thunnder—藏雷数组
void Initgame(char lag[Row][Line],char lag1)
{
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Line; j++)
{
lag[i][j] = lag1;
}
}
}
//放雷
int Putgame(char thunder[Row][Line])
{
int n = 0;
printf("请输入藏雷的个数:");
scanf("%d", &n);
int i = 0;
while (i < n)
{
int a = rand() % 10;
int b = rand() % 10;
if (thunder[a][b] == '0' && a != 0 && b != 0)
{
thunder[a][b] = '1';
i++;
}
}
return n;//返回雷的个数,判断雷是否全部排除
}
//打印雷区
void Printchgame(char ch[Row][Line])
{
for (int i = 0; i < Line-1; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i < Row-1; i++)
{
printf("%d ", i );
for (int j = 1; j < Line-1; j++)
{
printf("%c ", ch[i][j]);
}
printf("\n");
}
printf("\n");
}
//查看坐标周围有多少个雷1
//思路1:输入坐标此时一定不是雷,将周围看作一个3*3数组,查看有多少个'1'
int sumth1(char thunder[Row][Line], int a, int b)
{
int count = 0;
for (int i=0;i<3;i++)
{
for (int j = 0; j < 3; j++)
{
if (thunder[a+i][b+j] == '1')
{
count++;
}
}
}
return count;
}
//查看坐标周围有多少个雷2
//思路2:挨个字符相加,相当于把坐标对应的字符Ascll码值相加最终减去'0'倍个相加个数,得到数字'1'的个数
int sumth2(char thunder[Row][Line], int a, int b)
{
return thunder[a][b] + thunder[a][b + 1] + thunder[a][b + 2] + thunder[a + 1][b] + thunder[a + 1][b + 2] +
thunder[a + 2][b] + thunder[a + 2][b + 1] + thunder[a + 2][b + 2] - 8 * '0';
}
//排雷
void Removegame(char ch[Row][Line], char thunder[Row][Line],int n)
{
int a = 0;
int b = 0;
int win = 0;
int num = (Row-2) * (Line-2) - n;
while (win < num)
{
printf("请输入坐标:");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= Row && b >= 1 && b <= Line)
{
if (thunder[a][b] == '1')
{
printf("扫雷失败!\n");
Printchgame(thunder);
return;
}
else
{
int c = sumth1(thunder, a - 1, b - 1 );//查看周围雷个数
ch[a][b] = c + '0';
Printchgame(ch);//打印 ch
//Printchgame(thunder);
}
win++;
}
else
{
printf("坐标非法!\n");
}
}
printf("游戏成功!\n");
Printchgame(thunder);//打印 ch
}
#define _CRT_SECURE_NO_WARNINGS 1
#include "mine sweeping.h"
void menu()
{
printf("*************************\n");
printf(" 1.开始游戏 \n");
printf(" 0.退出游戏 \n");
printf("*************************\n");
}
void game()
{
char ch[Row][Line] = { 0 };//展示数组
char thunder[Row][Line] = { 0 };//藏雷数组
Initgame(ch, '*');//初始化 玩家
Initgame(thunder,'0');//初始化 电脑
int n = Putgame(thunder);//放雷
Printchgame(ch);//打印 ch
//Printchgame(thunder);//打印 thunder
Removegame(ch, thunder,n);//排雷
}
int main()
{
int flag = 1;
srand((unsigned)time(NULL));
while(flag)
{
menu();//菜单
int input = 0;
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戏
break;
case 0:
printf("欢迎下次使用!\n");
flag = 0;
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
system("pause");
system("cls");
}
return 0;
}
若所选位置周围雷数为0,则向四周发散,清楚为0的雷区,直到可以连接的雷区清除干净。
增加和修改代码如下:
#pragma once
#include
#include
#include
#define Row 11
#define Line 11
void Initgame(char lag[Row][Line],char lag1);//初始化
int Putgame(char thunder[Row][Line]);//放雷
void Printchgame(char ch[Row][Line]);//打印玩家猜测雷区
void Removegame(char thunder[Row][Line], char ch[Row][Line],char flag[Row][Line],int n);//排雷//排雷
void Minihunt(char thunder[Row][Line], char ch[Row][Line], int a, int b);//消除周围为0的位置
void JudgeRemove(char thunder[Row][Line], char ch[Row][Line], int a, int b);//判断四周是否有雷
增加了两组函数,用于排查周围为0的雷区
//查看坐标周围有多少个雷1
//思路1:输入坐标此时一定不是雷,将周围看作一个3*3数组,查看有多少个'1'
int sumth1(char thunder[Row][Line], int a, int b)
{
int count = 0;
for (int i=-1;i<2;i++)
{
for (int j = -1; j < 2; j++)
{
if (thunder[a+i][b+j] == '1')
{
count++;
}
}
}
return count;
}
//查看坐标周围有多少个雷2
//思路2:挨个字符相加,相当于把坐标对应的字符Ascll码值相加最终减去'0'倍个相加个数,得到数字'1'的个数
int sumth2(char thunder[Row][Line], int a, int b)
{
return thunder[a-1][b-1] + thunder[a-1][b] + thunder[a-1][b + 1] + thunder[a][b-1] + thunder[a][b + 1] +
thunder[a + 1][b-1] + thunder[a + 1][b ] + thunder[a + 1][b + 1] - 8 * '0';
}
对这两个查雷数的函数做了修改,在使用时之间调用即可,不需要再对输入的数字在函数内部进行修改
//判断所选位置的周围位置
void JudgeRemove(char thunder[Row][Line], char ch[Row][Line], char flag[Row][Line], int a, int b)
{
if (thunder[a][b] != '1')
{
int m = sumth2(thunder, a, b);
if (m == 0 && flag[a][b] != '+')
{
flag[a][b] = '+';
ch[a][b] = ' ';
Minihunt(thunder, ch, flag, a, b);
}
if (m != 0 && flag[a][b] != '+')
{
flag[a][b] = '+';
ch[a][b] = m + '0';
}
}
return;
}
//当所选位置为0时,判断周围位置
void Minihunt(char thunder[Row][Line], char ch[Row][Line], char flag[Row][Line], int a, int b)
{
if (a < 1 || b>Line-2)
{
return;
}
if (a - 1 >= 0 && b + 1 <= 10 && b-1>=0 && a+1<=10)
{
for (int i = -1; i < 2; i++)
{
for (int j = -1; j < 2; j++)
{
JudgeRemove(thunder, ch, flag, a + i, b + j);
}
}
}
return;
}
首先确定所给位置的正确性,不能超出范围
使用循环,以此探查为0的位置周围各位置的雷数,若非0,停止探索,若为0,使用递归继续探查
另外增加了标志数组flag,若此位置已经探查过则不再探查,防止代码进入死循环。(此方法类似于数据结构中的标志变量)
//排雷
void Removegame(char thunder[Row][Line], char ch[Row][Line], char flag[Row][Line], int n)
{
int a = 0;
int b = 0;
int win = 0;
//int num = (Row-2)*(Line-2)-n;
while (win != n)
{
printf("请输入坐标:");
scanf("%d %d", &a, &b);
if (a >= 1 && a <= Row && b >= 1 && b <= Line)
{
if (thunder[a][b] == '1')
{
printf("扫雷失败!\n");
Printchgame(thunder);
return;
}
else
{
int c = sumth1(thunder, a, b );//查看周围雷个数
if (c == 0)//排除周边非雷区
{
ch[a][b] = ' ';
Minihunt(thunder, ch,flag, a, b );
}
else
{
ch[a][b] = c + '0';
}
Printchgame(ch);//打印 ch
//Printchgame(thunder);
}
win = 0;
for (int i = 1; i <= Row - 2; i++)
{
for (int j = 1; j <= Line - 2; j++)
{
if (ch[i][j] == '*')
{
win++;
}
}
}
}
else
{
printf("坐标非法!\n");
}
}
printf("游戏成功!\n");
Printchgame(thunder);//打印 ch
}
修改了对win变量的使用,当win值==n值时,雷全部排出,结束游戏
当所选位置雷数为零时,进入Minihunt函数,判断周围各位置雷数,并打印
void game()
{
char ch[Row][Line] = { 0 };//展示数组
char thunder[Row][Line] = { 0 };//藏雷数组
char flag[Row][Line] = { 0 };//判断此位置是否已经经过判断
Initgame(ch, '*');//初始化 玩家
Initgame(thunder,'0');//初始化 电脑
Initgame(flag, '-');// '-'表示没有被判断 标志数组
int n = Putgame(thunder);//放雷
Printchgame(ch);//打印 ch
//Printchgame(thunder);//打印 thunder
Removegame(thunder,ch,flag,n);//排雷
}
增加了标志数组,判断对应位置是否被探查过