如图,这两天做了一个简易版的扫雷,勉强可以运行。
扫雷的逻辑是什么?
点击草坪,如果下面有地雷,那么游戏结束。如果下面没有雷,那么点击的地方显示周围8个格子内一共有多少地雷。
我的思路
我首先设置两个二维数组,一个二维数组表示的是草坪的表面,一个二维数组表示里面的地雷和数字。
unsigned char arr[10][10] = { 0 };//暗面
unsigned char arr2[10][10] = { 0 };//明面
这里使用的是最小的无符号char型变量,这样可以方便移植到单片机上。
unsigned char arr[10][10] = { 0 };//暗面
unsigned char arr2[10][10] = { 0 };//明面
unsigned char* pa[10];
for (int i = 0; i < 10; i++)//我们使用指针数组
pa[i] = arr[i];
int xx = 0, yy = 0;//这里定义的是数组的下标
initgraph(322, 322);//初始化窗口,
ExMessage m;//定义一个结构体变量m,这个是用来储存鼠标的数据
IMAGE picture;//这个就是指向图片的指针
lei(pa, 15);//利用这个函数自动布雷和布置数字
int baozha=0;
因为我需要把整个二维数组都送到布雷函数里面,所以这里我就需要一个指针数组,然后用指针数组储存二维数组的行。
void lei(unsigned char** pa, int how)//这里负责随机生成雷
{
srand(time(NULL));
for (int a = 0; a < 10; a++)//首先要把暗面数组初始化
{
for (int b = 0; b < 10; b++)
pa[a][b] = 3;
}
while (how)
{
int A = rand() % 9;
int B= rand() % 9;
if (pa[A][B] != 1)//如果之前这里没有雷
{
pa[A][B] = 1;//布雷
how--;//防止重复布雷
}
}
我们之前是用指针数组储存储存了二维数组的行地址,然后我们再把指针数组的数组名当做二级指针传进来,这样就实现了数组的整个传递;
我们这个棋盘是10*10个格子,数组的大小也是10*10,所以随机数生成当然就是0到9的范围
int shuliang = 0;
for (int b = 0; b < 10; b++)
{
for (int bb = 0; bb < 10; bb++)
{
if (pa[b][bb] == 3)//如果检测到这里是空白的地方
{
for (int aa = -1; aa < 2; aa++)//因为要检测点击格子的周边八个格子
for (int ba = -1; ba < 2; ba++)
{
if((b+aa>=0&&b+aa<=9)&&(bb+ba>=0&&bb+ba<=9))//防止越界访问
if (pa[b + aa][bb + ba] == 1)
shuliang++;//这里是计算雷的数量
}
pa[b][bb] = shuliang * 10;//因为后面用的是switch函数,所以这里这样
shuliang = 0;//别忘了归零
}
}
}
这里是生成数字,数字部分是点击后才会出现的,所以当然应该就存在暗区数组。
while (1)
{
m = getmessage(EX_MOUSE | EX_KEY);//这里获取鼠标的值
if (m.message == WM_LBUTTONDOWN)
{
xx = m.x / 32;
yy = m.y / 32;//相当巧妙地方法
if (m.ctrl)//插旗和拔旗
{
if (arr2[yy][xx] == 2)
arr2[yy][xx] = 0;
else if (arr2[yy][xx] == 0)
arr2[yy][xx] = 2;
}
else if (arr2[yy][xx] != arr[yy][xx])
{
arr2[yy][xx] = arr[yy][xx];
}
cleardevice();
}
for (int ii = 2, y = 0; ii < 300; ii += 32, y++)
{
for (int i = 2, x = 0; i < 300; i += 32, x++)
{
switch (arr2[y][x])
{
case 0: {
setfillcolor(GREEN);
solidrectangle(i, ii, i + 30, ii + 30);
}; break;
case 1: {
loadimage(&picture, "雷.jpg", 30, 30);
putimage(i, ii, &picture);
baozha = 1;
}; break;
case 2: {
loadimage(&picture, "小红旗.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 3: {
setfillcolor(BLACK);
solidrectangle(i, ii, i + 30, ii + 30);
}; break;
case 10: {
loadimage(&picture, "1.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 20: {
loadimage(&picture, "2.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 30: {
loadimage(&picture, "3.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 40: {
loadimage(&picture, "4.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 50: {
loadimage(&picture, "5.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 60: {
loadimage(&picture, "6.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 70: {
loadimage(&picture, "7.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 80: {
loadimage(&picture, "8.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
}
}
}
这里是显示区域
整体代码如下
#include<stdio.h>
#include <graphics.h>
#include<conio.h>
#include <time.h>
void lei(unsigned char** pa, int how)//这里负责随机生成雷
{
srand(time(NULL));
for (int a = 0; a < 10; a++)//首先要把暗面数组初始化
{
for (int b = 0; b < 10; b++)
pa[a][b] = 3;
}
while (how)
{
int A = rand() % 9;
int B= rand() % 9;
if (pa[A][B] != 1)
{
pa[A][B] = 1;
how--;
}
}
//下面就是开始布置数字
int shuliang = 0;
for (int b = 0; b < 10; b++)
{
for (int bb = 0; bb < 10; bb++)
{
if (pa[b][bb] == 3)//如果检测到这里是空白的地方
{
for (int aa = -1; aa < 2; aa++)
for (int ba = -1; ba < 2; ba++)
{
if((b+aa>=0&&b+aa<=9)&&(bb+ba>=0&&bb+ba<=9))
if (pa[b + aa][bb + ba] == 1)
shuliang++;
}
pa[b][bb] = shuliang * 10;//这样就不会冲突
shuliang = 0;
}
}
}
};
int game(int M)
{
// 初始化图形窗口
unsigned char arr[10][10] = { 0 };//暗面
unsigned char arr2[10][10] = { 0 };//明面
unsigned char* pa[10];
for (int i = 0; i < 10; i++)//我们使用指针数组
pa[i] = arr[i];
int xx = 0, yy = 0;
initgraph(322, 322);
ExMessage m;
IMAGE picture;//这个就是指向图片的指针
lei(pa, 15);
int baozha=0;
if (M == 1)
{
loadimage(&picture, "你死了.jpg", 322, 322);
putimage(0, 0, &picture);
Sleep(1000);
}
while (1)
{
m = getmessage(EX_MOUSE | EX_KEY);//这里获取鼠标的值
if (m.message == WM_LBUTTONDOWN)
{
xx = m.x / 32;
yy = m.y / 32;//相当巧妙地方法
if (m.ctrl)//插旗和拔旗
{
if (arr2[yy][xx] == 2)
arr2[yy][xx] = 0;
else if (arr2[yy][xx] == 0)
arr2[yy][xx] = 2;
}
else if (arr2[yy][xx] != arr[yy][xx])
{
arr2[yy][xx] = arr[yy][xx];
}
cleardevice();
}
for (int ii = 2, y = 0; ii < 300; ii += 32, y++)
{
for (int i = 2, x = 0; i < 300; i += 32, x++)
{
switch (arr2[y][x])
{
case 0: {
setfillcolor(GREEN);
solidrectangle(i, ii, i + 30, ii + 30);
}; break;
case 1: {
loadimage(&picture, "雷.jpg", 30, 30);
putimage(i, ii, &picture);
baozha = 1;
}; break;
case 2: {
loadimage(&picture, "小红旗.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 3: {
setfillcolor(BLACK);
solidrectangle(i, ii, i + 30, ii + 30);
}; break;
case 10: {
loadimage(&picture, "1.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 20: {
loadimage(&picture, "2.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 30: {
loadimage(&picture, "3.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 40: {
loadimage(&picture, "4.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 50: {
loadimage(&picture, "5.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 60: {
loadimage(&picture, "6.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 70: {
loadimage(&picture, "7.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
case 80: {
loadimage(&picture, "8.jpg", 30, 30);
putimage(i, ii, &picture);
}; break;
}
}
}
if (baozha == 1)
{
Sleep(1000);
return 1;
}
}
// 关闭图形窗口
closegraph();
}
int main()
{
int a = 0;
while (1)
{
a=game(a);
}
return 0;
}