C语言进阶之旅 番外篇(扫雷)
Posted 一个正直的男孩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言进阶之旅 番外篇(扫雷)相关的知识,希望对你有一定的参考价值。
故事背景,你要穿越丹麦海滩汇报敌军情况,那里危机四伏,应为那里埋了许多地雷,
思维导图
菜单==是否要执行任务
void menu()
{
printf("时间:二战 地点:丹麦海滩,任务:去对岸送敌军情报,你想过去必须穿过丹麦海滩\\n");
printf("\\n");
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\n");
printf("@@@@@@@@@@ 1.进入丹麦海滩 @@@@@@@@@@@\\n");
printf("@@@@@@@@@@ 0.逃跑 @@@@@@@@@@@\\n");
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\n");
}
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
paly();
break;
case 0 :
printf("逃跑");
break;
default:
printf("没有退路可言\\n");
break;
}
} while (input);
return 0;
}
初始化雷区
- 为啥要初始化雷区
- 你把它看成,敌军要买雷,是不是要确保海滩没雷,不然炸了就是炸一片
void InitBoard(char board[ROWS][COLS], int rows, int cols,char ret)
{
int i = 0;
int j = 0;
for (i = 0; i <=rows; i++)
{
for ( j = 0; j <cols; j++)
{
board[i][j] = ret;//这里就妙了,一个函数完成了俩个任务
}
}
}
打印雷区
void DisPlayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;//行
int j = 0;//列
int count = 1;
printf("--------丹麦西海岸--------\\n");
for ( i = 0; i <= row; i++)
{
printf("%d ", i);//列
}
printf("\\n");
for (i = 1; i <=row; i++)
{
printf("%d ", count++);//行
for ( j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\\n");
}
}
埋雷
- 敌军不会让你轻易过去所要要埋雷
- 生成随机值%行,列+1,%行列就是8+1,就是9
- 判断这个位置是否埋雷和是否在雷区内
void SetMine(char board[ROWS][COLS], int row, int col)
{
while (Mine_count)//每次下雷就会减一个,到时候是判断(Mine_count=0)0为假跳出
{
int x = rand() % row + 1; //rand取值范围在0~32767 % row范围就在0~8,数组范围9 * 9, + 1,解决
int y = rand() % col + 1;
int i = 0;
if (x >= 1 && x <= row && y >= 1 && x <= col)//判断坐标是否违法
{
if (board[x][y] == '0')//判断坐标是否已经埋雷了
{
board[x][y] = '1';
Mine_count - 1;
}
排雷,判断胜负
- 判断胜负:这里比较本,其实就是排除了除雷以外的,只剩下雷,那么就赢了
- 排雷:如果不是雷就计算他周围8个坐标雷的个数
int get_mine(char mine[ROWS][COLS], int x, int y)//计算坐标周围雷的个数
{
return mine[x - 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y + 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] - 8 * '0';//周围8个格子-去字符0,省下的只有字符1了加起来
}
//排雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win =0;
while (win < row * col - Mine_count)//棋盘个数
{
printf("输入坐标:<");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("gg");
break;
}
else
{
expand(mine, show, x, y);
int count = get_mine(mine, x, y);
show[x][y] = count + '0';//字符数组,count是整形,在字符数组中打印是对应ASIIC表的对应
DisPlayBoard(show, row, col);
win++;
}
}
else
{
printf("坐标违法\\n");
}
}
if (win == col * row - Mine_count)
{
printf("恭喜你走出丹麦海滩\\n");
}
}
优化
- 点击如果这个地方不是雷就展开知道碰到雷停止
- 如果第一次是雷,把它移开,游戏体验感最佳
展开
这里大致的思维导图
void RemoveMine(char mine[ROWS][COLS], char show[ROWS][COLS],int x,int y)
{
int count =get_mine(mine, x, y);
if (count == 0)
{
show[x][y] = ' ';//如果该坐标为0,打印空格在棋盘上
win++;
}
else//该坐标为1,
{
show[x][y] = count + '0';//显示该坐标周围8个坐标雷的个数假设count=1,棋盘是字符类型,上面的数字是对应ASSIC表上对应的数字,所以加上一个字符0
win++;
return;
}
int i = 0;
int j = 0;
for (i = -1; i <= 1; i++)//从x-1这个位置展开
{
for (j = -1; j <= 1; j++)//y-1
{
if (i == j && i == 0)//坐标本身
continue;
//展开条件:该处不是雷,且未被展开,即盘面上仍是'*',同时注意不能越界
if (mine[x + i][y + j] != '1' && show[x + i][y + j] == '*' && x < ROWS - 1 && y < COLS - 1 && x > 0 && y > 0)
{
RemoveMine(mine, show, x + i, y + j);
}
}
}
}
进入先去算这个坐标周围8个坐标返回雷的个数,0就把这个区域赋值成空格,然后判断他是否符合判断条件,满足进入递归。如果8个坐标返回是别的数就返回去该坐标周围雷的坐标
第一次如果是雷把雷转移
int frist = 1;//第一次如果是雷把他移除
printf("输入坐标:<");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
if (frist)
{
mine[x][y] = '0';
while (1)//重新在雷区埋雷
{
int x1 = rand() % row + 1;
int y2 = rand() % col + 1;
if (mine[x1][y2] == '0')
{
mine[x1][y2] = '1';
break;
}
}
}
}
拓展ASSIC表
总结:
- 这里的优化是看了好多博客,和大佬…………
- 还有一些一个功能没有完成如果是雷标记
- 加油吧!!!
本篇文要是那里有错,请大胆指出(评论区或加我QQ(1696912943,给我留面哈哈哈)),博主,钱包不厚,不过脸皮厚,所以不会伤到博主自尊心,你提出错误,博主就涨知识,涨知识钱包就变厚哈哈哈哈
持续跟新中……………………
以上是关于C语言进阶之旅 番外篇(扫雷)的主要内容,如果未能解决你的问题,请参考以下文章
我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段