void meun() //菜单选项
{
printf("************************n");
printf("****1.play 0.exit****n");
printf("************************n");
}
void test()
{
int input = 0;
do
{
meun();
printf("请选择!");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("退出游戏n");
break;
default:
printf("重新选择n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
2,game函数
为了方便我们随时修改棋盘大小,这里我们直接定义两个变量(ROW, COL) 来表示横纵行大小, 而为了防止我们判断时发生数组越界访问的情况,我们需要在原来棋盘大小的基础上横竖各增加2(上下左右各一行)所以我们要定义ROWS和COLS两个变量,但我们设置雷和使用的棋盘大小依旧是ROW, COL,多出来部分仅作为旁白。
#define ROW 9 #define COL 9 #define COLS COL+2 #define ROWS ROW+2 #include//srand函数头文件 #include //time函数头文件 void game() { srand((unsigned)time(NULL)); //生成随机数,随机设置雷 char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息 char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息 //初始化雷盘 memset(mine, '0', sizeof(mine)); memset(show, '*', sizeof(show)); //打印雷盘 DisplayBoard(show, ROWS, COLS); Setmine(mine, ROWS, COLS);//埋雷 Findmine(show,mine, ROWS, COLS);//扫雷 }
初始化雷盘时需要创建两个数组,数组mine存放布置好的雷的信息(雷的数量,设置的位置都存 放在其中,对玩家不可见),而数组show则为玩家使用的雷盘存放排查出的雷的信息(不展示 雷的数量,位置等信息,只存储展示排出雷的信息)下面打印雷盘时会进行对比展示
二,打印雷盘void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
printf(" ");
for (y = 1; y <= col; y++)
{
//打印列号
printf(" %d ", y);
}
printf("n");
printf("----------------------------------------n");
for (x = 1; x <= row; x++)
{
//打印行号
printf(" %d |", x);
for (y = 1; y <= col; y++)
{
printf(" %c |", board[x][y]);
}
printf("n");
printf("----------------------------------------n");
}
}
我们两组初始化的雷盘就打印好了
我们来看下效果:
1,show数组
2,mine数组(该雷盘仅在此作展示不对外开放)
三,埋雷设置雷时位置范围在1~9内,rand() % row得到的值为1~8,这里需要 +1,才可得到1~9,
#include//rand函数头文件 void Setmine(char mine[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { //随机生成放雷坐标 int x = rand() % row + 1; int y = rand() % col + 1; if (mine[x][y] == '0') { //'1'表示雷 mine[x][y] = '1'; count--; } } }
注:使用rand函数前,要先使用srand函数,srand函数参数又需传个time函数,大概就是这样:srand((unsigned)time(NULL)),详细可以查看库函数
四,扫雷void Swap(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;//设置成功条件
while (winn");
scanf("%d %d", &x, &y);
//判断坐标合法
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//判断是否踩雷
if (mine[row][col] == '1')
{
printf("恭喜你,你被炸死了n");
//参数为mine数组,游戏结束后向玩家展示所有雷的信息
DisplayBoard(mine, ROW, COL);
break;
}
else
{
bomb(mine, show, x, y);
DisplayBoard(show, row, col);
win++;
}
}
else
{
printf("输入坐标非法n");
}
}
//win的值等于棋盘大小减去雷的数量时,扫雷成功
if (win == row * col - EASY_COUNT)
{
printf("游戏获胜!!!");
}
}
五,递归炸弹
一个个排也太麻烦了!!!
void bomb(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
//判断坐标是否合法
if (x >= 1 && x <= ROWS-2 && y >= 1 && y <= COLS-2)
{
//判断是否已经被排除
if (show[x][y] != '*')
{
return;
}
//计算x,y坐标周围雷数量
int count = get_mine_count(mine, x, y);
if (count > 0)
{
//x,y坐标赋值周围雷的数量
return show[x][y] = count + '0';
}
else if (count == 0)
{
show[x][y] = ' ';
bomb(mine, show, x - 1, y - 1);
bomb(mine, show, x, y - 1);
bomb(mine, show, x + 1, y - 1);
bomb(mine, show, x - 1, y);
bomb(mine, show, x + 1, y);
bomb(mine, show, x - 1, y + 1);
bomb(mine, show, x, y + 1);
bomb(mine, show, x + 1, y + 1);
}
}
}
效果如下:
这样就有意思多了(还是写这样的代码比较有意思)
六,计算周围八个位置雷的数量将周围雷的数量计算出来,个数打印在(x,y)坐标的位置上
int calculate(char mine[ROWS][COLS], int x, int y)
{
return (mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y - 1] +
mine[x + 1][y - 1] +
mine[x - 1][y] +
mine[x - 1][y + 1] +
mine[x][y - 1] - 8 * '0');
}
由于我们在mine数组中放置都是字符 ‘0’ 和 字符 ‘1’ ,字符数字减去 ‘0’ 刚好为整形数字,所以这里我们需要减8个 ’ 0 ‘ 得到整形数字
-END-
第一次写博客,写的蛮煎熬,本人也才刚学习代码,写此博客的目的只为加深自己的理解,写完之后理解确实更深刻了些,欢迎指教!!! 教学相长,望能共勉



