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.png", 50, 50);
loadimage(&img[1], "res1.png", 50, 50);
loadimage(&img[2], "res2.png", 50, 50);
loadimage(&img[3], "res3.png", 50, 50);
loadimage(&img[4], "res4.png", 50, 50);
loadimage(&img[5], "res5.png", 50, 50);
loadimage(&img[6], "res6.png", 50, 50);
loadimage(&img[7], "res7.png", 50, 50);
loadimage(&img[8], "res8.png", 50, 50);
loadimage(&img[9], "res12.png", 50, 50);
loadimage(&img[10], "res11.png", 50, 50);
loadimage(&img[11], "res9.png", 50, 50);
loadimage(&img[12], "res10.png", 50, 50);
loadimage(&img[13], "res13.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
", 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
", 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	", map[i][j]);
				}
				printf("
");
			}*/








			system("pause");
			//getchar();
			return 0;
		}
原文地址:https://www.cnblogs.com/heerha/p/14040545.html