提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
提
示:这里可以添加本文要记录的大概内容:
例如:我们初学C语言时,遇到代码量较大的项目——扫雷,那么如何思路清晰地写出扫雷的代码呢?这里推荐一个靠谱的方法。
本文有:扫雷详解+代码实现。
提示:以下是本篇文章正文内容,下面案例可供参考
一、扫雷代码量比较大,如何写?
答:思维导图帮助我们快速理清编程思路,是一个很好用的工具。
二、扫雷详解
1.扫雷详解
a、设置一个打印菜单,作为游戏提示
样式如下图:
直接让程序打印即可,代码如下:
void menu()
{
printf("*********************\n");
printf("****** 1. PLAY ******\n");
printf("****** 2. EXIT ******\n");
printf("*********************\n");
}
b、输入一个数字,使程序能够进入游戏
创建变量input;
利用scanf输入函数,使得用户能够输入input
switch选择语句:选择是否进入游戏。
case 1:进入游戏。
case 2 :退出游戏。
default:选择错误,请重新输入。(假如用户输入的数据不是1,也不是2,则执行default语句。)
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);//输入一个数字1或者2,表示是否进入游戏
switch (input)
{
case 1://进入
game();
break;
case 2://退出
printf("退出游戏\n");
break;
default://选择错误
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
c、进入游戏代码,难度逐渐提升
(1)、首先,创建一个打印棋盘。
给用户看的棋盘,代码如下:
建立两个循环,打印出一个矩形的*阵。
用于初始化我们的*号棋盘。
void init_printboard(char print_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW - 2; i++)
{
for (j = 1; j <= COL - 2; j++)
{
print_board[i][j] = '*';
}
}
}
(2)、用户输入扫雷的坐标,就把*改为数字。
假设雷为1,非雷为0;
我们想要的效果如下,输入扫雷的坐标,改变对应的位置符号。
改变符号时,我们需要确定该位置以及四周有没有雷。
假设我们选择的坐标为2,3;那么需要排查的坐标如黄线的位置,分别是:(1,2);(1,3);(1,4);(2,2);(2,4);(3,2);(3,3);(3,4).
如果坐标在最边缘的位置,那么我们需要排查的只有五个坐标,如图:
四个角落,需要排查的坐标也各不相同。
我们排查雷的代码又各不一样。
如果建立两个棋盘,可以帮助我们很好的避免边缘排查困难的情况。
左边的代码我们已经写完了,那么右边的代码如何实现?
(3)、初始化数字棋盘,设置时间戳
我们需要创建一个全0的棋盘,然后再把雷布置上去。
我们在初始化时,顺便把0放上去,完成一个棋盘的初始化。
void init_numboard(char num_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
num_board[i][j] = '0';
}
}
}
再者就是布置雷了。
随机出现的雷才更加有趣。说到随机,我们就不得不使用时间戳来使得雷的位置随机出现。
因为时间永远都是变化的,所以利用时间戳来布置雷再好不过了。
srand((unsigned int)time(NULL));
上面这个就是时间戳的创建。
然后,我们再调用它。代码如下:
void Num(char num_board[ROW][COL])
{
int n = 0;
while (n < 10)
{
int row = rand() % (ROW-2) + 1;
int col = rand() % (COL-2) + 1;
if (num_board[row][col] == '0')
{
num_board[row][col] = '1';
n++;
}
}
}
(4)、数字棋盘代码:
void init_numboard(char num_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
num_board[i][j] = '0';
}
}
}
将两个棋盘合并,那么最边缘的棋盘四周也能确定是否有雷,就不需要写好几种不一样的
(5)、 如何排查雷?
根据我们所选择的坐标,判断该坐标是否为1。
如果是,那么直接结束游戏;如果不是,将其置为0。
int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)
{
if (num_board[row][col] != '1')
{
print_board[row][col] = '0';
}
else
{
print_board[row][col] = '1';
return 1;//1表示游戏失败
}
}
排查一圈,查看坐标周围是否有雷。
将四周的坐标遍历,有雷的count++。
排查出的count赋值给打印棋盘。
这样我们就能够看到四周有多少个雷啦。
如下图:
表示该坐标周围有两个雷。
代码实现如下:
char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)//排查该坐标周围有几个雷
{
char count = '0';
int i = 0;
int j = 0;
for (i = row - 1; i <= row + 1; i++)
{
for (j = col - 1; j <= col + 1; j++)
{
if (num_board[i][j] == '1')
{
count++;
}
}
}
if (num_board[row - 1][col - 1] == '1' ||
num_board[row - 1][col] == '1'||
num_board[row - 1][col + 1] == '1'||
num_board[row][col + 1] == '1'||
num_board[row + 1][col + 1] == '1'||
num_board[row + 1][col] == '1' ||
num_board[row + 1][col - 1] == '1' ||
num_board[row][col - 1] == '1' )
{
print_board[row][col] = count;//该坐标周围有几个雷
}
else
{
return '0';//0表示周围没有雷
}
}
三、思完整代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("退出游戏\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//打印菜单
void menu()
{
printf("*********************\n");
printf("****** 1. PLAY ******\n");
printf("****** 2. EXIT ******\n");
printf("*********************\n");
}
//初始化数字棋盘
void init_numboard(char num_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
num_board[i][j] = '0';
}
}
}
//初始化打印棋盘
void init_printboard(char print_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW - 2; i++)
{
for (j = 1; j <= COL - 2; j++)
{
print_board[i][j] = '*';
}
}
}
//实现数字棋盘:布置雷
void Num(char num_board[ROW][COL])
{
int n = 0;
while (n < 10)
{
int row = rand() % (ROW - 2) + 1;
int col = rand() % (COL - 2) + 1;
if (num_board[row][col] != '1')
{
num_board[row][col] = '1';
n++;
}
}
}
//打印数字棋盘
void PrintNum(char num_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW; i++)
{
for (j = 1; j <= COL; j++)
{
printf("%c ", num_board[i][j]);
}
printf("\n");
}
}
//实现打印棋盘
void Print(char print_board[ROW][COL])
{
int i = 0;
int j = 0;
for (i = 1; i <= ROW - 2; i++)
{
for (j = 1; j <= COL - 2; j++)
{
printf("%c ", print_board[i][j]);
}
printf("\n");
}
}
//排查该坐标是否是雷
int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)
{
if (num_board[row][col] != '1')
{
print_board[row][col] = '0';
}
else
{
print_board[row][col] = '1';
return 1;//1表示游戏失败
}
}
//排查该坐标周围有几个雷
char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col)//排查该坐标周围有几个雷
{
char count = '0';
int i = 0;
int j = 0;
for (i = row - 1; i <= row + 1; i++)
{
for (j = col - 1; j <= col + 1; j++)
{
if (num_board[i][j] == '1')
{
count++;
}
}
}
if (num_board[row - 1][col - 1] == '1' ||
num_board[row - 1][col] == '1'||
num_board[row - 1][col + 1] == '1'||
num_board[row][col + 1] == '1'||
num_board[row + 1][col + 1] == '1'||
num_board[row + 1][col] == '1' ||
num_board[row + 1][col - 1] == '1' ||
num_board[row][col - 1] == '1' )
{
print_board[row][col] = count;//该坐标周围有几个雷
}
else
{
return '0';//0表示周围没有雷
}
}
//游戏实现
void game()
{
char print_board[ROW+10][COL+10];
char num_board[ROW+10][COL+10];
int i = 0;
int j = 0;
init_numboard(num_board);//初始化数字棋盘
//PrintNum(num_board);//打印数字棋盘
init_printboard(print_board);//初始化打印棋盘
Print(print_board);//实现打印棋盘
Num(num_board);//实现数字棋盘:布置雷
PrintNum(num_board);//打印数字棋盘
while (1)
{
int row = 0;
int col = 0;
printf("请输入坐标:>");
scanf("%d %d", &row, &col);//选择扫雷坐标
int ret = Findland(num_board, print_board, row, col);//排查该坐标是否是雷
//Print(print_board);//实现打印棋盘
char ret2 = Findaroundland(num_board, print_board, row, col);//排查该坐标周围有几个雷
Print(print_board);//实现打印棋盘
if (ret == '1')
{
printf("游戏结束\n");
break;
}
}
}
#pragma once
#include<stdio.h>
#define ROW 11
#define COL 11
//打印菜单
void menu();
//初始化数字棋盘
void init_numboard(char num_board[ROW][COL]);
//初始化打印棋盘
void init_printboard(char print_board[ROW][COL]);
//实现数字棋盘:布置雷
void Num(char num_board[ROW][COL]);
//打印数字棋盘
void PrintNum(char num_board[ROW][COL]);
//实现打印棋盘
void Print(char print_board[ROW][COL]);
//排查该坐标是否是雷
int Findland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col);
//排查该坐标周围有几个雷
char Findaroundland(char num_board[ROW][COL], char print_board[ROW][COL], int row, int col);
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了扫雷代码的思路,和简单的代码实现。如果有学有余力,也可以自己尝试把四周的*表示为数字,写一个更加复杂的扫雷。