#include<easyx.h>
#include<conio.h>
//推箱子项目 10行10列的图片 ,假设每一个图片是正方形(边长50)
//1、打开窗口
//2、定义图片数组,把图片加载进图片数组里
//3、通过图片数组,把图片贴在图形窗口;定义一个三维数组(作为多个地图),定义辅助数组:把当前关卡的地图装进辅助数组里面
//4、人物的移动
//5、关卡的胜利判断

IMAGE img[5];//定义图片数组

//0表示空地   1表示墙  2表示人   3表示箱子   4表示目的地  6表示人在目的地上    7表示箱子在目的地上

int arr[3][10][10] =
 {
     {
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 4, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 3, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 2, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
         1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     },
     {
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
         1, 0, 4, 4, 4, 0, 4, 0, 0, 1,
         1, 3, 3, 3, 0, 3, 3, 0, 1, 1,
         1, 4, 3, 0, 2, 0, 3, 0, 0, 1,
         1, 1, 0, 0, 0, 3, 0, 0, 1, 1,
         1, 1, 0, 4, 4, 4, 0, 1, 1, 1,
         1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
         1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     },
     {
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 0, 4, 3, 0, 3, 4, 0, 1, 1,
         1, 0, 4, 3, 0, 3, 4, 0, 1, 1,
         1, 0, 4, 3, 0, 3, 4, 0, 1, 1,
         1, 0, 4, 3, 2, 3, 4, 0, 1, 1,
         1, 0, 4, 3, 0, 3, 4, 0, 1, 1,
         1, 0, 4, 3, 0, 3, 4, 0, 1, 1,
         1, 0, 0, 3, 3, 3, 0, 0, 1, 1,
         1, 0, 0, 4, 4, 4, 0, 0, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1
     }
 };


int tempMap[10][10];//辅助数组  保存当前所在关卡的地图
 int level = 0;//表示关卡//函数功能:初始化地图
 void initMap()
 {
     for (int i = 0; i < 10; i++)
     {
         for (int j = 0; j < 10; j++)
         {
             tempMap[i][j] = arr[level][i][j];//在这个三位数组中level,可以理解成第几个二维数组(从0开始)
         }
     }
 }//函数功能:把图片加载进图片数组里
 void picLoadArr()
 {
     loadimage(&img[0], "1.jpg", 50, 50);//墙
     loadimage(&img[1], "2.jpg", 50, 50);//人
     loadimage(&img[2], "3.jpg", 50, 50);//箱子
     loadimage(&img[3], "4.jpg", 50, 50);//目的地
     loadimage(&img[4], "7.jpg", 50, 50);//箱子在目的地上
 }
 //函数功能:把图片贴在图形界面上
 void drawMap()
 {
     BeginBatchDraw();//开始批量绘图
     //putimage(200, 300, &img[0]);//贴墙
     //putimage(200, 400, &img[1]);//贴人
     //putimage(300, 300, &img[2]);//贴箱子
     //putimage(300, 400, &img[3]);//贴目的地
     //putimage(400, 400, &img[4]);//贴箱子在目的地上    //图形窗口的x坐标:与列下标j有关,50*j
     //图形窗口的y坐标:与行下标i有关,50*i    for (int i = 0; i < 10; i++)//i作为二维数组的行下标
     {
         for (int j = 0; j < 10; j++)//j作为二维数组的列下标
         {
             switch (tempMap[i][j])
             {
                 //贴墙
             case 1:
                 putimage(j*50, i*50, &img[0]);
                 break;                //贴人物
             case 2:
             case 6:
                 putimage(j * 50, i * 50, &img[1]);
                 break;                //贴箱子
             case 3:
                 putimage(j * 50, i * 50, &img[2]);
                 break;                //贴目的地
             case 4:
                 putimage(j * 50, i * 50, &img[3]);
                 break;
                 //贴 箱子在目的地上
             case 7:
                 putimage(j * 50, i * 50, &img[4]);
                 break;
             }        }
     }    EndBatchDraw();//结束批量绘制
}
//函数功能:人物移动
 void move()
 {
     int X = 0, Y = 0;//X用来保存人物的行下标 Y用来保存人物的列下标
     for (int i = 0; i <= 9; i++)
     {
         for (int j = 0; j <= 9; j++)
         {
             if (tempMap[i][j] == 2 || tempMap[i][j]==6)//找到了人
             {
                 X = i;
                 Y = j;
                 break;
             }
             
         }
     }
     //通过改变二维数组元素的值,来形成一个人物移动的效果
     //通过按键,判断人物的移动方向  asdw
     //conio.h   _getch()函数:等待从键盘输入一个字符,不需要和getchar函数一样以回车结束
     switch (_getch())
     {
         //人物往上移动
     case 'w':
         if (tempMap[X - 1][Y] == 0 || tempMap[X - 1][Y] == 4)//人的上面是空地,或者是目的地
         {
             tempMap[X - 1][Y] = tempMap[X - 1][Y] + 2;
             tempMap[X][Y] = tempMap[X][Y] - 2;
         }
         if (tempMap[X - 1][Y] == 3 || tempMap[X - 1][Y] == 7)//如果人的上面是箱子,或者人的上面是箱子在目的地上
         {
             if (tempMap[X - 2][Y] == 0 || tempMap[X - 2][Y] == 4)//如果箱子的上面是空地,或者是目的地
             {
                 tempMap[X][Y] -= 2; //完全等价  tempMap[X][Y] = tempMap[X][Y] - 2;
                 tempMap[X - 1][Y] -= 1;
                 tempMap[X - 2][Y] += 3;
             }
         }
         break;
     case 's'://人物往下移动
         if (tempMap[X + 1][Y] == 0 || tempMap[X + 1][Y] == 4)//如果人的下面是空地,或者是目的地,人就可以往下走
         {
             tempMap[X][Y] -= 2;
             tempMap[X + 1][Y] += 2;
         }
         if (tempMap[X + 1][Y] == 3 || tempMap[X + 1][Y] == 7)//如果人的下面是箱子,或者人的下面是箱子在目的地上
         {
             if (tempMap[X + 2][Y] == 0 || tempMap[X + 2][Y] == 4)//如果箱子的下面是空地,或者是目的地
             {
                 tempMap[X][Y] -= 2;
                 tempMap[X + 1][Y] -= 1;
                 tempMap[X + 2][Y] += 3;
             }
         }
         break;
     case 'a'://人物往左移动
         if (tempMap[X][Y-1] == 0 || tempMap[X][Y-1] == 4)//如果人的左面是空地,或者是目的地,人就可以往左走
         {
             tempMap[X][Y] -= 2;
             tempMap[X][Y-1] += 2;
         }
         if (tempMap[X][Y-1] == 3 || tempMap[X][Y-1] == 7)//如果人的左面是箱子,或者人的左面是箱子在目的地上
         {
             if (tempMap[X][Y-2] == 0 || tempMap[X][Y-2] == 4)//如果箱子的左面是空地,或者是目的地
             {
                 tempMap[X][Y] -= 2;
                 tempMap[X][Y-1] -= 1;
                 tempMap[X][Y-2] += 3;
             }
         }
         break;
     case 'd'://人物往右移动
         if (tempMap[X][Y + 1] == 0 || tempMap[X][Y + 1] == 4)//如果人的右面是空地,或者是目的地,人就可以往右走
         {
             tempMap[X][Y] -= 2;
             tempMap[X][Y + 1] += 2;
         }
         if (tempMap[X][Y + 1] == 3 || tempMap[X][Y + 1] == 7)//如果人的右面是箱子,或者人的右面是箱子在目的地上
         {
             if (tempMap[X][Y + 2] == 0 || tempMap[X][Y + 2] == 4)//如果箱子的右面是空地,或者是目的地
             {
                 tempMap[X][Y] -= 2;
                 tempMap[X][Y + 1] -= 1;
                 tempMap[X][Y + 2] += 3;
             }
         }    }
}
//函数功能:判断是否通过关卡
 void isWin()
 {
     //找不到箱子(3),就是通过关卡
     for (int i = 0; i <= 9; i++)
     {
         for (int j = 0; j <= 9; j++)
         {
             if (tempMap[i][j] == 3)//只要辅助数组里面有一个箱子(3),就继续推箱子
             {
                 return;
             }
         }
     }
     //如果函数到这里还没有结束,表示已经通过了当前关卡     //如果到最后一关
     if (level==2)//选择结束还是重新开始
     {//MessageBox消息盒子:弹出一个窗口
         int temp=MessageBox(GetHWnd(), "是否开始第一关", "提示", MB_YESNO);//窗口弹出两个按钮,一个是(6),一个否(7)
         if (temp == IDYES)//如果我们按下的是:是
         {
             level = 0;//重新开始
             initMap();//重新加载地图
         }
         else
         {
             exit(0);//退出程序
         }    }
     //否则就继续下一关卡
     else
     {
         level++;
         initMap();//重新加载地图
     }
 } int main()
 {
     initgraph(500, 500);//初始化窗口
     picLoadArr();//把图片加载进图片数组里
     level = 2;
     initMap();//把当前的关卡,装进辅助地图中    while (1)
     {
         isWin();//判断是否胜利
         cleardevice();//清除屏幕
         drawMap();//画地图
         move();//人物的移动
         cleardevice();//清除屏幕
         drawMap();//画地图    }
     closegraph();//关闭窗口
     return 0;
 }