扫雷是一个非常经典的小游戏,玩家通过选定棋盘上的坐标来排查系统埋的地雷,如果选定的坐标没有,就在该坐标上显示坐标周围有几颗雷。
设计小游戏,我们可以先设置一个简易的菜单,让玩家选择玩游戏或者退出,如果玩家选择错误,就让玩家重新选择。
要设计扫雷,首先要有一个棋盘,根据需要来设置棋盘大小,我设置的是9 x 9的棋盘,为了防止排查最外围坐标时,周围一圈的坐标需要反复判定是否超出棋盘范围,可以给棋盘加上两行两列。这样9 x 9的棋盘就需要初始化一个11行11列的二维数组。棋盘准备两个,一个用来存储随机生成的雷的位置,有雷的位置初始化为字符‘1’,没有雷就初始化为‘0’,另一个可以初始化成 ‘ * ’ 来展示给玩家。
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROWS ROW + 2
#define COLS COL + 2
#define ROW 9
#define COL 9
#define EASY 10
void menu();
void init(char set[ROWS][COLS], int rows, int cols, char s);
void set(char hide[ROWS][COLS], int row, int col);
void show_me(char show[ROWS][COLS], int row, int col);
void find(char hide[ROWS][COLS], char show[ROWS][COLS],int row, int col);
void menu()
{
printf("*******************\n");
printf("****1. play *******\n");
printf("****0. exit *******\n");
printf("*******************\n");
printf("请选择:> \n");
}
do
{
menu();
scanf("%d", &n);
switch(n)
{
case 1:
init(hide, ROWS, COLS, '0');
init(show, ROWS, COLS, '*');
set(hide, ROW, COL);
show_me(show, ROW, COL);
find(hide, show, ROW, COL);
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错入,请重新输入\n");
break;
}
}
while (n);
void init(char qipan[ROWS][COLS], int rows, int cols, char s)
{
int i = 0;
int j = 0;
int n = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
qipan[i][j] = s;
}
}
}
void set(char hide[ROWS][COLS], int row, int col)
{
int count = EASY;
while (count > 0)
{
int r = rand() % row +1;
int c = rand() % col +1;
if (hide[r][c] == '0')
{
hide[r][c] = '1';
count--;
}
}
}
void show_me(char look[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int k = 0;
for (k = 0; k <= col; k++)
{
printf("%d ", k);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ",look[i][j]);
}
printf("\n");
}
}
玩家在' * ' 棋盘上指定坐标,将这个坐标与雷的位置作对比,决定要输出或者返回什么内容。如果是雷就提示玩家被炸了,游戏结束,如果不是,就计算这个坐标周围一圈有几个雷,并把改坐标内容改为雷的数量。因为雷被初始化为字符‘1’,非雷为‘0’,这两个字符的ASCII码值差1,所以把这些坐标全部加起来再减去一个 8 * ‘ 0 ’ 就得到了这个坐标周围雷的数量。
如果所有的非雷位置都被排查完毕,就可以提示玩家获胜了。这里可以定义一个变量来计数,每次玩家排查出一个非雷坐标,再提示玩家该位置非雷后,这个计数变量就 + 1 ,当计数变量的值等于棋盘内总坐标数减去雷的个数时,就说明玩家已经排查完所有非雷坐标。
int get_lei(char hide[ROWS][COLS], int r, int c)
{
return hide[r - 1][c - 1] + hide[r - 1][c] + hide[r - 1][c + 1] +
hide[r][c - 1] + hide[r][c + 1] + hide[r + 1][c - 1] +
hide[r + 1][c] + hide[r + 1][c + 1] - 8 * '0';
}
void find(char hide[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
printf("开始扫雷,请输入排查坐标\n");
int r = 0;
int c = 0;
int win = 0;
while (win < row * col - EASY)
{
scanf("%d %d", &r, &c);
printf("\n");
if (r >= 1 && r <= row && c >=1 && c <= col)
{
if (hide[r][c] == '1')
{
printf("恭喜你,被炸飞了\n");
show_me(hide, ROW, COL);
break;
}
else
{
int lei = get_lei(hide,r,c);
show[r][c] = lei + '0';
show_me(show, ROW, COL);
win++;
}
}
else
{
printf("坐标错误,请重新输入:\n");
}
}
if (win == row * col - EASY)
{
printf("扫雷成功\n");
show_me(hide, ROW, COL);
}
}
这就是简单的扫雷设计思路了。