初级扫雷游戏代码
工具下载地址: https://docs.easyx.cn
编译环境:vs2013
#include"stdio.h"
#include"easyx.h"//调用库函数
#include"time.h"//产生随机数的头文件
#include"graphics.h"
// -1表示雷
// 0表示没有翻开的空地
int map[10][10] = { 0 };//地图 全局数组 所有的位置初始化为0
IMAGE img[14];//图片数组
struct nodeMap{
int val;//对应地图里面的值
int x, y;//对应地图里面的坐标
int sign;//标记 作为后面鼠标点击事件的入口
};
nodeMap myMap[10][10] = { 0 };//辅助数组 cpp不需要用struct关键字定义结构体数组 这是cpp对c的优化
void initMyMap()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
myMap[i][j].sign = 0;//表示都没有标记过
myMap[i][j].val = map[i][j];
myMap[i][j].x = i;
myMap[i][j].y = j;
}
}
}
//用随机数布置雷
void initMap()
{
int x, y;//表示雷的坐标
for (int i = 0; i < 10;)//在for循环里无条件的自增 防止雷的坐标会有重复的 把自增条件写在循环体内
{
x = rand() % 10;//表示随机数的范围在0到9
y = rand() % 10;//表示随机数的范围在0到9
//用if语句 防止雷的坐标重复
if (map[x][y] != -1)
{
map[x][y] = -1;
i++;
}
}
//雷放入地图之后,让雷的周围一圈+1
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (map[i][j] == -1)//如果这个位置是雷 就给雷的周围一圈+1
{
//给雷的周围一圈加1
for (int m=i - 1; m <= i + 1; m++)//行的变化
{
for (int n=j - 1; n < j + 1; n++)
{
//不越界并且当前位置不是雷
if (m >= 0 && m <= 9 && n >= 0 && n <= 9 && map[m][n] != -1)
{
map[m][n]++;
}
}
}
}
}
}
}
void initImg()
{
//sprintf()格式化写入字符串
char str[30] = { 0 };
for (int i = 0; i < 14; i++)
{
sprintf(str, "res/%d.png", i);//第一参:放入哪一个字符串数组
loadimage(&img[i], str, 50, 50);//最后两个是图片的宽和高 如果没有那么大 就会被等比例拉伸
}
}
void drawMap()
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
switch (myMap[i][j].val)
{
case 10:
putimage(j * 50, i * 50, &img[0]);
break;
case 11:
putimage(j * 50, i * 50, &img[1]);
break;
case 12:
putimage(j * 50, i * 50, &img[2]);
break;
case 13:
putimage(j * 50, i * 50, &img[3]);
break;
case 14:
putimage(j * 50, i * 50, &img[4]);
break;
case 15:
putimage(j * 50, i * 50, &img[5]);
break;
case 16:
putimage(j * 50, i * 50, &img[6]);
break;
case 9:
putimage(j * 50, i * 50, &img[9]);
break;
case 123:
putimage(j * 50, i * 50, &img[11]);
break;
case 321:
putimage(j * 50, i * 50, &img[10]);
break;
default:
putimage(j * 50, i * 50, &img[12]);
}
}
}
}
int dir[8][2] = {
{ 0, 1 }, { 0, -1 }, { 1, 1, }, {1,-1},
{ 1, 0 }, { -1, 0 }, { -1, 1 }, {-1,-1}
};
void show()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 10; j++)
{
if (myMap[i][j].val < 9)//标记的额外判断
{
myMap[i][j].val += 10;
}
}
}
}
void overeturn(int x, int y)
{
for (int i = 0; i < 8; i++)
{
if (myMap[x][y].val != -1)
{
int dx = dir[i][1] + x;
int dy = dir[i][0] + y;
if (dx < 0 || dx >= 10 || dy < 0 || dy >= 10)//如果越界,这个地方就不需要判断
continue;
if (myMap[dx][dy].val == 0)//翻开的是空地的地方就递归
{
myMap[dx][dy].val += 10;//翻开是空地
overeturn(dx, dy);//循环执行完递归就完事了 并非百分百的递归
}
else if (myMap[dx][dy].val < 8 && myMap[dx][dy].val != -1)
{
myMap[dx][dy].val += 10;
}
}
}
}
void isWin()
{
int sum = 0;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (myMap[i][j].val<9 || myMap[i][j].val>100)
{
sum++;
}
}
}
if (sum == 10)
{
//游戏胜利
}
}
void play()
{
int x = 0, y = 0;//获取鼠标的位置
MOUSEMSG msg = GetMouseMsg();//获取鼠标消息
switch (msg.uMsg)//获取当前的鼠标消息
{
case WM_LBUTTONDOWN://翻开
//获取x,y的坐标
x = msg.y / 50;//鼠标的坐标和数组的坐标不一样 数组的行是鼠标的y
y = msg.x / 50;
if (myMap[x][y].val >= 9) break;//不能写>=10 否则雷会被翻开了+10 然后再左键点击又+10 就翻不过来了
else if (myMap[x][y].val == -1)
{
//MessageBox弹窗
//MB_YESNO 有两个按钮 是和否
if (MessageBox(GetHWnd(), "显示内容", "提示", MB_YESNO) == IDYES)//IDYES表示选择了是
{
memset(map, 0, 10 * 10 * 4);//把数组map全部初始化为0
initMap();
initMyMap();
drawMap();
}
else
{
exit(0);//退出程序
}
}
else if (myMap[x][y].val == 0)
{
myMap[x][y].val += 10;
overeturn(x, y);
}
else
{
myMap[x][y].val += 10;
}
break;
case WM_RBUTTONDOWN://进行标记
x = msg.y / 50;//鼠标的坐标和数组的坐标不一样 数组的行是鼠标的y
y = msg.x / 50;
if (myMap[x][y].val<9||myMap[x][y].val>100)//没有翻开过的就可以标记
{
if (myMap[x][y].sign == 0)
{
myMap[x][y].val = 123;//表示旗帜
myMap[x][y].sign++;
}
else if (myMap[x][y].sign == 1)
{
myMap[x][y].val = 321;//表示?问号
myMap[x][y].sign++;//2
}
else if (myMap[x][y].sign == 2)
{
myMap[x][y].val = map[x][y];//从原来的地图没动过的值复制过来
myMap[x][y].sign = 0;
}
}
break;
}
}
int main()
{
initgraph(10 * 50, 10 * 50);//列*图片大小 行*图片大小
srand((unsigned)time(NULL));//伪随机数,不会出现重复数字
//如果是真随机,出现的1到10十个数的概率都是十分之一
initMap();//初始化地图
initMyMap();//出世话辅助地图
initImg();//初始化图片
while (1)
{
play();
drawMap();//画地图
}
closegraph();//关闭图形库窗口大小
return 0;
}