2020.11.07 19,20课 扫雷

include <stdio.h>

include<graphics.h>

include<easyx.h>

include<time.h>;

include<stdlib.h>;

////扫雷
//初始化一个图形库窗口
//定义一个10*10二维数组用来表示的地图
//对地图初始化,往二维数组里面放雷
//鼠标点击,翻开点击位置的周围
//判断输赢

//失败后点击重试再点击第二次的时候不动了

void initMap();
void initImg();
void initMyMap();
void play();
void draw();

void isWin();

struct nodeMap
{
int val;//地图下面的值
int x, y;//地图坐标
int sign;//标记

};

//辅助结构体数组,读取地图,获取在对应地图里面的值
nodeMap myMap[10][10] = { 0 };

//定义地图
int map[10][10] = { 0 };

//展示所有的数字
void show() {

for (int i = 0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

if (myMap[i][j].val < 9) {

myMap[i][j].val += 10;

}
}

}
}
void draw();

//广度寻路
//定义一个数组表示八个方向
int dir[8][2] = { {0,1},{0,-1},{1,1},{1,-1},{1,0},{-1,0},{-1,1},{-1,-1} };
//右 左 下右 下左 下 上 上右 上左

IMAGE img[14];

//加载图片
void initImg() {
loadimage(&img[0], "res\0.png", 50, 50);
loadimage(&img[1], "res\1.png", 50, 50);
loadimage(&img[2], "res\2.png", 50, 50);
loadimage(&img[3], "res\3.png", 50, 50);
loadimage(&img[4], "res\4.png", 50, 50);
loadimage(&img[5], "res\5.png", 50, 50);
loadimage(&img[6], "res\6.png", 50, 50);
loadimage(&img[7], "res\7.png", 50, 50);
loadimage(&img[8], "res\8.png", 50, 50);
loadimage(&img[9], "res\12.png", 50, 50);
loadimage(&img[10], "res\11.png", 50, 50);
loadimage(&img[11], "res\9.png", 50, 50);
loadimage(&img[12], "res\10.png", 50, 50);
loadimage(&img[13], "res\13.png", 50, 50);

}

//初始化地图 的雷
void initMap() {
int x = 0; int y = 0;//雷的位置

//雷的位置会重复
//for (int i = 0; i < 10; i++) {
// x = rand() % 10;
// y = rand() % 10;
// //在10*10的地图中随机
// map[x][y] = -1;
//
//}

//随机雷
for (int i = 0; i < 10; ) {
x = rand() % 10;
y = rand() % 10;
//在10*10的地图中随机

if (map[x][y] != -1) {

map[x][y] = -1;
i++;
//得在这个区间里循环,if才有效雷才不会重复所以在这里i++
}

}

//使雷周围加1
for (size_t i = 0; i < 10; i++)
{
for (size_t j = 0; j<10 ; j++)
{ //找到雷
if (map[i][j]==-1)
{ //雷的周围
for (int m = i - 1; m <= i + 1; m++)
{

for (int n = j - 1; n <= j + 1; n++)
{ //雷周围加一,排除雷
if (m >= 0 && m < 10 && n >= 0 && n < 10 && map[m][n] != -1) {
map[m][n]++;

}

}

}
}
}
}
}

//初始化辅助数组
void initMyMap() {
for (size_t i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++) {
myMap[i][j].sign = 0; //0表示没有标记
myMap[i][j].val = map[i][j];
myMap[i][j].x = i;
myMap[i][j].y = j;
}
}
}

//通过递归翻开一片不是雷和数字的区域
void overntun(int x, int y) {

//遍历8个方向
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 != -1)
{
myMap[dx][dy].val += 10;
overntun(dx, dy);
}

//点到数字
else if (myMap[dx][dy].val < 9 && myMap[dx][dy].val != -1)
{
myMap[dx][dy].val += 10;

}

}

}

}

//鼠标点击消息
void play() {

int x = 0, y = 0;//用来保存鼠标点击位置
MOUSEMSG msg = GetMouseMsg();//获取鼠标消息
switch (msg.uMsg) {

//按下左键消息
case WM_LBUTTONDOWN:
x = msg.y/50;
y = msg.x/50;
//printf("x=%d,y=%d\n", x, y);//还得除50才是每个小格子的坐标

if (myMap[x][y].val >= 10)break;// 点过了。跳出

//点到雷,游戏结束
else if (myMap[x][y].val == -1) {

show();
draw();
putimage(y * 50, x * 50, &img[13]);

/*if(MessageBox(GetHWnd(), "游戏失败", "提示", MB_ABORTRETRYIGNORE)==IDRETRY) {
cleardevice();
initMap();
initImg();
initMyMap();
play();
draw();

isWin();

}*/

//getchar();
//exit(1);

}

//空地在贴图中他的值就改变贴相应的值
else if (myMap[x][y].val == 0)
{
myMap[x][y].val += 10;//翻方块
overntun(x, y);//翻一片

}

//else if (myMap[x][y].val != 0 && myMap[x][y].val != -1)
else{

myMap[x][y].val += 10;

}

break;

//按下右键消息
case WM_RBUTTONDOWN:
x = msg.y/50;
y = msg.x/50;
//printf("x=%d,y=%d\n", x, y);

//修改左键点击后还能右键点击的bug 9和100之间的10到18不在此范围内
if (myMap[x][y].val < 9 || myMap[x][y].val>100)

{
if (myMap[x][y].sign == 0)//标记
{
myMap[x][y].sign++;//1表示旗子
myMap[x][y].val = 123;
}

else if (myMap[x][y].sign == 1)
{
myMap[x][y].sign++;//2表示问号
myMap[x][y].val = 321;
}

else if (myMap[x][y].sign == 2)
{
myMap[x][y].sign = 0;//2表示问号//赋值为0
myMap[x][y].val = map[x][y];//从问号翻回最初值不改变
}

}

break;
}

}

//判断游戏是否胜利 messagebox
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) {
if (MessageBox(GetHWnd(), "游戏胜利", "提示", MB_YESNO) == IDYES)
{
//清零
/void memset(void* s, int ch, size_t n);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法[1] 。*/
memset(map, 0, sizeof(int) * 10 * 10);
initMap();
initMyMap();
draw();
}
else if (MessageBox(GetHWnd(), "游戏胜利", "提示", MB_YESNO) == IDNO) {

exit(1);

}

}

}

//MessageBox
//void draw();
////点到雷失败后重试
//void isdefeat()
//{
// MOUSEMSG msg1 = GetMouseMsg();
// int x=0, y=0;
//
//
// for (int i = 0; i < 10; i++) {
//
// for (int j = 0; j < 10; j++) {
//
//
// switch (msg1.uMsg) {
// x = msg1.y / 50;
// y = msg1.x / 50;
//
// case WM_LBUTTONDOWN: if (myMap[x][y].val == -1) {
// if(MessageBox(GetHWnd(), "游戏失败", "提示", MB_ABORTRETRYIGNORE)==IDRETRY)
// {
// memset(map, 0, sizeof(int) * 10 * 10);
// initMap();
//
// initMyMap();
// initImg();
// draw();
// };
// }
//
// }
// }
// }
//}

//贴图
void draw() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
switch (myMap[i][j].val)//map[i][j]
{
//case 0:putimage(i * 50, j * 50, &img[0]); break;
//辅助数组的作用,把.val改成鼠标点击为10
case 9:putimage(j * 50, i * 50, &img[11]); break;
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 17:putimage(j * 50, i * 50, &img[7]); break;

case 18:putimage(j * 50, i * 50, &img[8]); break;

case 123:putimage(j * 50, i * 50, &img[10]); break;//旗子

case 321:putimage(j * 50, i * 50, &img[12]); break;//问号
default:putimage(j * 50, i * 50, &img[9]); break;

}

}

}

}

int main()
{
srand((unsigned)time(NULL));
initgraph(10 * 50, 10 * 50, EW_SHOWCONSOLE);

//MessageBox(GetHWnd(), "游戏失败", "提示", MB_ABORTRETRYIGNORE);

initMap();
initImg();
initMyMap();

while (1) {

play();
draw();

isWin();
//isdefeat();

}

/for (size_t i = 0; i < 10; i++)
{
for (size_t j = 0; j < 10; j++)
{
printf("%d\t", map[i][j]);
}
printf("\n");
}
/

system("pause");
//getchar();
return 0;
}

posted @ 2020-11-26 09:19  鹤儿哈  阅读(46)  评论(0)    收藏  举报