zoukankan      html  css  js  c++  java
  • 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;
    		}
  • 相关阅读:
    在阿里写了8年代码后,我才明白这些道理
    2017双11交易系统TMF2.0技术揭秘,实现全链路管理
    加入新公司快速进入状态的心得
    Kibana+ElasticSearch实现索引数据的几种查询方式
    记一次jenkins发生的无法判断字符串前后空格
    ansible-playbook调试
    记一次ansible-playbook jenkins传空格的标量导致删除了服务的主目录
    rabbitmq集群中队列的完整性
    html5分割上传实现超大文件无插件网页上传思路
    html5分割上传实现超大文件无插件网页上传功能
  • 原文地址:https://www.cnblogs.com/heerha/p/14040545.html
Copyright © 2011-2022 走看看