#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <mmsystem.h>
#include "resource.h"


HINSTANCE hInst;
HBITMAP pic,empty,compare_pic,pict[8],compare_pict[8],other;    //所有图的变量名
HDC hdc,mdc;                                                    //DC名
int mouse_x,mouse_y,n=0,line=3,high3=100,high4=200,high5=300;   //鼠标X Y 移动步数 难度 记录
char str[10]=" ";                                               //字符串,显示步数和记录时用
bool fin=false,new3=true,new4=false,new5=false;                 //完成 难度三 四 五 的重绘
struct Point
{
    int x;
    int y; 
    int num;
}point[26];                                                     //块

ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
void MyPaint();                                                  //显示
void Change_Block(int block1,int block2);                        //交换两块的属性
void Save();                                                     //保存记录
void GetPos();                                                   //为重绘做的随机排列

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    MSG msg;
    MyRegisterClass(hInstance);
    if (!InitInstance (hInstance, nCmdShow))    //如果实例化失败,退出
    {
        return FALSE;
    }
    while (GetMessage(&msg, NULL, 0, 0))        //消息循环,一直获取消息,直到消息返回值为假
    {
        TranslateMessage(&msg);                 //翻译消息
        DispatchMessage(&msg);                  //将消息发到适当的对象上
    }
    return msg.wParam;
}



ATOM MyRegisterClass(HINSTANCE hInstance)    //注册窗口类,通知你要建的窗口是什么样的.可以有多个,用类名来区分
{
    WNDCLASSEX wcex;                                      //类名
    wcex.cbSize = sizeof(WNDCLASSEX);                     //类的长度       cb...表示存储空间
    wcex.style            = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;        //窗口风格  水平horizontal.垂直vertical.重画redraw
    wcex.lpfnWndProc    = (WNDPROC)WndProc;               //指向函数的一个指针 指向WndProc
                                                //LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    wcex.cbClsExtra        = 0;                              //类变量占用的存储 (cb表示存储空间的前缀)
    wcex.cbWndExtra        = 0;                              //实例变量占用的存储
    wcex.hInstance        = hInstance;                      //定义该类的应用程序实例的句柄
    wcex.hIcon            = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));                     //图标对象的句柄
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);    //光标图像的句柄
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);       //用于擦掉用户区的刷子的句柄
    wcex.lpszMenuName    = (LPCSTR)IDR_MENU1;                           //标识选单对象的字符串
    wcex.lpszClassName    = "CAN";                          //该类名字的字符串  lpsz长指针,以\0结束
    wcex.hIconSm        = NULL;                           //
    return RegisterClassEx(&wcex);                        //定义完类的各个对象后注册
}



BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    hInst = hInstance;
    char filename[30]=" ";
    hWnd = CreateWindow("CAN", "游戏窗口", WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)          //类名,用于标识创建的窗口属于哪个类.
    {
        return FALSE;
    }
    MoveWindow(hWnd,80,100,1087,526,true);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    hdc=GetDC(hWnd);
    mdc=CreateCompatibleDC(hdc);                          //创建缓存
    empty=(HBITMAP)LoadImage(hInstance,"Source\\pic\\empty.bmp",IMAGE_BITMAP,687,526,LR_LOADFROMFILE);
    
    for(int m=0;m<=7;m++)
    {
        sprintf(filename,"Source\\pic\\pic%d.bmp",m);       //读图,没什么好说的
        pict[m] = (HBITMAP)LoadImage(hInstance,filename,IMAGE_BITMAP,600,480,LR_LOADFROMFILE);
        compare_pict[m]=(HBITMAP)LoadImage(hInstance,filename,IMAGE_BITMAP,450,360,LR_LOADFROMFILE);
    }
    pic=pict[0];
    compare_pic=compare_pict[0];
    FILE *fp;                                       //读入record文件中的记录
    if((fp=fopen("Source\\record","ab+"))==NULL)
    {
        MessageBox(NULL,"不能打开record文件,可能被删除,请在Source中重新建立.","",NULL);
        return false;
    }
    else 
    {
        fread(&high3,sizeof(high3),1,fp);
        fread(&high4,sizeof(high4),1,fp);
        fread(&high5,sizeof(high5),1,fp);
        fclose(fp);
    }
    MyPaint();
    return TRUE;
}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    int block_num=0;                        //用于鼠标所指的块的编号,非NUM号 要区分
    switch (message) 
    {
    case WM_PAINT:                          //显示
        hdc = BeginPaint(hWnd, &ps);
        hdc=GetDC(hWnd);
        MyPaint();
        EndPaint(hWnd, &ps);
        break;
    case WM_COMMAND:                                      //菜单命令        
        switch(LOWORD(wParam))
        {
        case ID_NEWGAME:
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;           //读图后要重排图
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC0:
            pic=pict[0];                       //读入大图
            compare_pic=compare_pict[0];       //读入参照图 
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;           //读图后要重排图
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC1:
                pic=pict[1];
                compare_pic=compare_pict[1];
                fin=0;n=0;
                switch(line)
                {
                case 3: new3=true;break;
                case 4: new4=true;break;
                case 5: new5=true;break;
                default:;
                }
                MyPaint();
                break;
        case ID_PIC2:
            pic=pict[2];
            compare_pic=compare_pict[2];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;        
        case ID_PIC3:
            pic=pict[3];
            compare_pic=compare_pict[3];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC4:
            pic=pict[4];
            compare_pic=compare_pict[4];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC5:
            pic=pict[5];
            compare_pic=compare_pict[5];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC6:
            pic=pict[6];
            compare_pic=compare_pict[6];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC7:
            pic=pict[7];
            compare_pic=compare_pict[7];
            fin=0;n=0;
            switch(line)
            {
            case 3: new3=true;break;
            case 4: new4=true;break;
            case 5: new5=true;break;
            default:;
            }
            MyPaint();
            break;
        case ID_PIC8:
            if(LoadImage(NULL,"Source\\pic\\other.bmp",IMAGE_BITMAP,600,480,LR_LOADFROMFILE))    //成功载入other.bmp
            {
                pic = (HBITMAP)LoadImage(NULL,"Source\\pic\\other.bmp",IMAGE_BITMAP,600,480,LR_LOADFROMFILE);    
                compare_pic=(HBITMAP)LoadImage(NULL,"Source\\pic\\other.bmp",IMAGE_BITMAP,450,360,LR_LOADFROMFILE);
                fin=0;n=0;
                switch(line)
                {
                case 3: new3=true;break;     
                case 4: new4=true;break;
                case 5: new5=true;break;
                default:;
                }
                MyPaint();
            }
            else MessageBox(hWnd,"pic文件夹中无other.bmp文件.","说明",NULL);    //未成功载入other.bmp
            break;
       case ID_THREE:
           new3=true;new4=false;new5=false;line=3;fin=0;n=0;  //如果选难度三,则要重排图,不许四,五重排.难度设为三,标记未完成,n从0记数.
           MyPaint();
           break;
        case ID_FOUR:
            new3=false;new4=true;new5=false;line=4;fin=0;n=0;
            MyPaint();
            break;
        case ID_FIVE:
            new3=false;new4=false;new5=true;line=5;fin=0;n=0;
            MyPaint();
            break;
        case ID_INTRODUCE:
            MessageBox(hWnd,"鼠标点击移动,拼完整即胜利!\n\n如果想自添加图需要用BMP格式,文件名为other.bmp。并放入pic文件夹中.","说明",NULL);
            break;
        case ID_ABOUT:
            MessageBox(hWnd,"如发现BUG或有好的建议。请致信EMAIL:29648634@。谢谢!\n\n\t    Special Thank 老婆--悦 对我的大力支持!\n\n\t\t\t\t\t作者:高坤","说明",NULL);
            break;
        case ID_EXIT:
            
                DestroyWindow(hWnd);
            
            break;
        default:
            MessageBox(hWnd,"菜单命令错误!","",NULL);
            
        }
        break;

        case WM_LBUTTONDOWN:                               //鼠标左键控制块的移动
            mouse_x=LOWORD(lParam);                        //记录鼠标的位置
            mouse_y=HIWORD(lParam);
            block_num=0;        
            switch(line)
            {
            case 3:
                if(mouse_x<600 && mouse_y<480)                     //鼠标在允许点击的大图上才赋块值
                    block_num=mouse_x/200+1+(mouse_y/160)*3;
                if(!fin && block_num>0)
                {
                    sndPlaySound("Source\\sound\\click.wav",SND_ASYNC | SND_FILENAME);
                    switch(block_num)
                    {
                    case 1:
                        if(point[2].num==9)                  //第一块可以与第二块交换
                        {
                            Change_Block(1,2);
                            n++;                                         //移动步数加1
                        }
                        else if(point[4].num==9)           //第一块可以与第四块交换
                        {
                            Change_Block(1,4);
                            n++;                                         //移动步数加1
                        }
                        break;
                    case 2:
                        if(point[1].num==9)                          //第二块可以与第一块交换
                        {
                            Change_Block(2,1);
                            n++;    //移动步数加1
                        }
                        else if(point[5].num==9)                          //第二块可以与第五块交换
                        {
                            Change_Block(2,5);
                            n++;    //移动步数加1
                        }
                        else if(point[3].num==9)                          //第二块可以与第三块交换
                        {
                            Change_Block(2,3);
                            n++;    //移动步数加1
                        }
                        break;
                    case 3:
                        if(point[2].num==9)                              //第三块可以与第二块交换
                        {
                            Change_Block(3,2);
                            n++;  //移动步数加1
                        }
                        else if(point[6].num==9)                              //第三块可以与第六块交换
                        {
                            Change_Block(3,6);
                            n++;  //移动步数加1
                        }
                        break;
                    case 4:
                        if(point[1].num==9)                          //第四块可以与第一块交换
                        {
                            Change_Block(4,1);
                            n++;    //移动步数加1
                        }
                        else if(point[5].num==9)                          //第四块可以与第五块交换
                        {
                            Change_Block(4,5);
                            n++;    //移动步数加1
                        }
                        else if(point[7].num==9)                          //第四块可以与第七块交换
                        {
                            Change_Block(4,7);
                            n++;    //移动步数加1
                        }
                        break;
                    case 5:
                        if(point[2].num==9)                          //第五块可以与第二块交换
                        {
                            Change_Block(5,2);
                            n++;    //移动步数加1
                        }
                        else if(point[4].num==9)                          //第五块可以与第四块交换
                        {
                            Change_Block(5,4);
                            n++;    //移动步数加1
                        }
                        else if(point[6].num==9)                          //第五块可以与第六块交换
                        {
                            Change_Block(5,6);
                            n++;    //移动步数加1
                        }
                        else if(point[8].num==9)                          //第五块可以与第八块交换
                        {
                            Change_Block(5,8);
                            n++;    //移动步数加1
                        }
                        break;
                    case 6:
                        if(point[3].num==9)                          //第六块可以与第三块交换
                        {
                            Change_Block(6,3);
                            n++;    //移动步数加1
                        }
                        else if(point[5].num==9)                          //第六块可以与第五块交换
                        {
                            Change_Block(6,5);
                            n++;    //移动步数加1
                        }
                        else if(point[9].num==9)                          //第六块可以与第九块交换
                        {
                            Change_Block(6,9);
                            n++;    //移动步数加1
                        }                               
                        break;
                    case 7:
                        if(point[8].num==9)                  //第七块可以与第八块交换
                        {
                            Change_Block(7,8);
                            n++;                                         //移动步数加1
                        }
                        else if(point[4].num==9)           //第七块可以与第四块交换
                        {
                            Change_Block(7,4);
                            n++;                                         //移动步数加1
                        }                                   
                        break;
                    case 8:
                        if(point[7].num==9)                          //第八块可以与第七块交换
                        {
                            Change_Block(8,7);
                            n++;    //移动步数加1
                        }
                        else if(point[5].num==9)                          //第八块可以与第五块交换
                        {
                            Change_Block(8,5);
                            n++;    //移动步数加1
                        }
                        else if(point[9].num==9)                          //第八块可以与第九块交换
                        {
                            Change_Block(8,9);
                            n++;    //移动步数加1
                        }                                     
                        break;
                    case 9:
                        if(point[8].num==9)                              //第九块可以与第八块交换
                        {
                            Change_Block(9,8);
                            n++;  //移动步数加1
                        }
                        else if(point[6].num==9)                              //第九块可以与第六块交换
                        {
                            Change_Block(9,6);
                            n++;  //移动步数加1
                        }                                 
                        break;
                    default:;
                }
            }
            break;
            case 4:
                if(mouse_x<600 && mouse_y<480)
                    block_num=mouse_x/150+1+(mouse_y/120)*4;            
                if(!fin && block_num>0)                        //如果block_num没能从鼠标坐标上获取值则说明点的位置不对。
                {
                    sndPlaySound("Source\\sound\\click.wav",SND_ASYNC | SND_FILENAME);
                    switch(block_num)
                    {
                    case 1:
                        if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }
                        else if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }                    
                        break;
                    case 4:
                        if(point[block_num-1].num==16)
                        {    
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }
                        break;
                    case 13:
                        if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }
                        else if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }                
                        break;
                    case 16:
                        if(point[block_num-1].num==16)
                        {
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }
                        break;
                    case 2:
                    case 3:
                        if(point[block_num-1].num==16)
                        {
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }
                        else if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }
                        break;
                    case 5:
                    case 9:
                        if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }
                        else if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }
                        else if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }
                        break;
                    case 8:
                    case 12:
                        if(point[block_num-1].num==16)
                        {
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }
                        else if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }
                        break;
                    case 14:
                    case 15:
                        if(point[block_num-1].num==16)
                        {
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }
                        else if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }
                        break;
                    default:
                        if(point[block_num-1].num==16)
                        {
                            Change_Block(block_num,block_num-1);
                            n++;
                        }
                        else if(point[block_num+4].num==16)
                        {
                            Change_Block(block_num,block_num+4);
                            n++;
                        }
                        else if(point[block_num+1].num==16)
                        {
                            Change_Block(block_num,block_num+1);
                            n++;
                        }
                        else if(point[block_num-4].num==16)
                        {
                            Change_Block(block_num,block_num-4);
                            n++;
                        }    
                    }
                }
                break;
              case 5:
                  if(mouse_x<600 && mouse_y<480)
                      block_num=mouse_x/120+1+(mouse_y/96)*5;            
                  if(!fin && block_num>0)                        //如果block_num没能从鼠标坐标上获取值则说明点的位置不对。
                  {
                      sndPlaySound("Source\\sound\\click.wav",SND_ASYNC | SND_FILENAME);
                      switch(block_num)                                  //移动两块
                      {
                      case 1:
                          if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }
                          else if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }                    
                          break;
                      case 5:
                          if(point[block_num-1].num==25)
                          {    
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }
                          break;
                      case 21:
                          if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                          else if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }                
                          break;
                      case 25:
                          if(point[block_num-1].num==25)
                          {
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                          break;
                      case 2:
                      case 3:
                      case 4:
                          if(point[block_num-1].num==25)
                          {
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }
                          else if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }
                          break;
                      case 6:
                      case 11:
                      case 16:
                          if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }
                          else if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }
                          else if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                          break;
                      case 10:
                      case 15:
                      case 20:
                          if(point[block_num-1].num==25)
                          {
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }
                          else if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                          break;
                      case 22:
                      case 23:
                      case 24:
                          if(point[block_num-1].num==25)
                          {
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }
                          else if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                          break;
                      default:
                          if(point[block_num-1].num==25)
                          {
                              Change_Block(block_num,block_num-1);
                              n++;
                          }
                          else if(point[block_num+5].num==25)
                          {
                              Change_Block(block_num,block_num+5);
                              n++;
                          }
                          else if(point[block_num+1].num==25)
                          {
                              Change_Block(block_num,block_num+1);
                              n++;
                          }
                          else if(point[block_num-5].num==25)
                          {
                              Change_Block(block_num,block_num-5);
                              n++;
                          }
                }
            }
            break;
        default:;
        }
        MyPaint(); 
        break;
    case WM_CLOSE:
        if(IDYES==MessageBox(hWnd,"真的不玩了?","提示",MB_YESNO))
        {
            DestroyWindow(hWnd);
        }
        break;
    case WM_DESTROY:
        int k;
        for(k=0;k<7;k++)
        {
            DeleteObject(pict[k]);
            DeleteObject(compare_pict[k]);
        }
        DeleteObject(compare_pic);
        DeleteObject(pic);
        DeleteObject(empty);
        ReleaseDC(hWnd,hdc);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}



void MyPaint()
{
    SelectObject(mdc,empty);                         //贴上背景图
    BitBlt(hdc,600,0,487,526,mdc,200,0,SRCCOPY);
    SelectObject(mdc,compare_pic);                   //贴上参照图
    BitBlt(hdc,617,0,450,360,mdc,0,0,SRCCOPY);
    sprintf(str,"%d",n);                             //显示移动步数
    TextOut(hdc,817,433,str,strlen(str));
    if(3==line)
    {
        sprintf(str,"%d",high3);                    //在其位置显示最高记录
        TextOut(hdc,1007,433,str,strlen(str));
        if(new3)                //如果要重排
        {
            GetPos();            //重排
            new3=false;
        }
        SelectObject(mdc,pic);
        for(int i=1;i<=9;i++)
        {
            switch(i)             //按属性贴图
            {
            case 1:
                BitBlt(hdc,0,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 2:
                BitBlt(hdc,200,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 3:
                BitBlt(hdc,400,0,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 4:
                BitBlt(hdc,0,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 5:
                BitBlt(hdc,200,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 6:
                BitBlt(hdc,400,160,200,160,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 7:
                BitBlt(hdc,0,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 8:
                BitBlt(hdc,200,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 9:
                BitBlt(hdc,400,320,200,160,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            default:
                MessageBox(NULL,"贴图序列号错误!","",NULL);
            }
        }    
        for(int j=1;j<=9;j++)
        {
            if(point[j].num==9)
            {
                SelectObject(mdc,empty);
                switch(j)                                     //贴上空白图
                {
                case 1:
                    BitBlt(hdc,0,0,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 2:
                    BitBlt(hdc,200,0,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 3:
                    BitBlt(hdc,400,0,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 4:
                    BitBlt(hdc,0,160,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 5:
                    BitBlt(hdc,200,160,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 6:
                    BitBlt(hdc,400,160,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 7:
                    BitBlt(hdc,0,320,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 8:
                    BitBlt(hdc,200,320,200,160,mdc,0,0,SRCCOPY);
                    break;
                case 9:
                    BitBlt(hdc,400,320,200,160,mdc,0,0,SRCCOPY);
                    break;
                default:;
                }
                break;
            }
        }
        int finish=0;
        for(int k=1;k<=9;k++)
        {
            if(point[k].num==k)
                finish++;            //做完成判断 完成则finish应该为line*line
        }
        if(finish==9)              //完成则执行
        {
            fin=true;
            sndPlaySound("Source\\sound\\FTELEP2电火花.wav",SND_ASYNC | SND_FILENAME);
            MessageBox(NULL,"Finish! Change a harder one,try it again!","恭喜^_^",NULL);
            if(n<high3)  //如果出现新记录...
            {
                Sleep(100);                                        //睡一下,让记录来的别太突然~
                high3=n;
                SelectObject(mdc,empty);
                BitBlt(hdc,1007,433,100,30,mdc,250,0,SRCCOPY);     //贴个背景的绿图,要不如n为44,记录为100,就会出现记录显示为440 再刷新下才能看到是44
                sprintf(str,"%d",high3);                            //显示新记录!
                TextOut(hdc,1007,433,str,strlen(str));
                sndPlaySound("Source\\sound\\new.wav",SND_ASYNC | SND_FILENAME);
                MessageBox(NULL,"THE NEW RECORD!","恭喜^_^",NULL);            
                Save();            //保存新记录到文件
            }
        }
    }

    else if(4==line)
    {
        sprintf(str,"%d",high4);
        TextOut(hdc,1007,433,str,strlen(str));
        if(new4)
        {
            GetPos();
            new4=false;
        }
        SelectObject(mdc,pic);
        for(int i=1;i<=16;i++)
        {
            switch(i)
            {
            case 1:
                BitBlt(hdc,0,0,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 2:
                BitBlt(hdc,150,0,150,120,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 3:
                BitBlt(hdc,300,0,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 4:
                BitBlt(hdc,450,0,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 5:
                BitBlt(hdc,0,120,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 6:
                BitBlt(hdc,150,120,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 7:
                BitBlt(hdc,300,120,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 8:
                BitBlt(hdc,450,120,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 9:
                BitBlt(hdc,0,240,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 10:
                BitBlt(hdc,150,240,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 11:
                BitBlt(hdc,300,240,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 12:
                BitBlt(hdc,450,240,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 13:
                BitBlt(hdc,0,360,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 14:
                BitBlt(hdc,150,360,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 15:
                BitBlt(hdc,300,360,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 16:
                BitBlt(hdc,450,360,150,120,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            default:
                MessageBox(NULL,"贴图序列号错误!","",NULL);
            }
        }    
        for(int j=1;j<=16;j++)
        {
            if(point[j].num==16)
            {
                SelectObject(mdc,empty);
                switch(j)
                {
                case 1:
                    BitBlt(hdc,0,0,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 2:
                    BitBlt(hdc,150,0,150,120,mdc,0,0,SRCCOPY);            
                    break;
                case 3:
                    BitBlt(hdc,300,0,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 4:
                    BitBlt(hdc,450,0,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 5:
                    BitBlt(hdc,0,120,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 6:
                    BitBlt(hdc,150,120,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 7:
                    BitBlt(hdc,300,120,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 8:
                    BitBlt(hdc,450,120,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 9:
                    BitBlt(hdc,0,240,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 10:
                    BitBlt(hdc,150,240,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 11:
                    BitBlt(hdc,300,240,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 12:
                    BitBlt(hdc,450,240,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 13:
                    BitBlt(hdc,0,360,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 14:
                    BitBlt(hdc,150,360,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 15:
                    BitBlt(hdc,300,360,150,120,mdc,0,0,SRCCOPY);                
                    break;
                case 16:
                    BitBlt(hdc,450,360,150,120,mdc,0,0,SRCCOPY);                
                    break;
                default:;
                }
                break;
            }
        }
        int finish=0;
        for(int k=1;k<=16;k++)
        {
            if(point[k].num==k)
                finish++;
        }
        if(finish==16)
        {
            fin=true;
            sndPlaySound("Source\\sound\\FTELEP2电火花.wav",SND_ASYNC | SND_FILENAME);
            MessageBox(NULL,"Finish! Change a harder one,try it again!","恭喜^_^",NULL);
            if(n<high4)
            {
                Sleep(100);
                high4=n;
                SelectObject(mdc,empty);
                BitBlt(hdc,1007,433,100,30,mdc,250,0,SRCCOPY);
                sprintf(str,"%d",high4);
                TextOut(hdc,1007,433,str,strlen(str));
                sndPlaySound("Source\\sound\\new.wav",SND_ASYNC | SND_FILENAME);
                MessageBox(NULL,"THE NEW RECORD!","恭喜^_^",NULL);            
                Save();
            }
        }
    }
    else if(5==line)
    {
        sprintf(str,"%d",high5);
        TextOut(hdc,1007,433,str,strlen(str));
        if(new5)             //更新5X5
        {
            GetPos();
            new5=false;
        }
        SelectObject(mdc,pic);
        for(int i=1;i<=25;i++)
        {
            switch(i)
            {
            case 1:
                  BitBlt(hdc,0,0,120,96,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 2:
                BitBlt(hdc,120,0,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 3:
                BitBlt(hdc,240,0,120,96,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 4:
                BitBlt(hdc,360,0,120,96,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 5:
                BitBlt(hdc,480,0,120,96,mdc,point[i].x,point[i].y,SRCCOPY);                
                break;
            case 6:
                  BitBlt(hdc,0,96,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 7:
                BitBlt(hdc,120,96,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 8:
                BitBlt(hdc,240,96,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 9:
                BitBlt(hdc,360,96,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 10:
                BitBlt(hdc,480,96,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 11:
                  BitBlt(hdc,0,192,120,96,mdc,point[i].x,point[i].y,SRCCOPY);        
                break;
            case 12:
                BitBlt(hdc,120,192,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 13:
                BitBlt(hdc,240,192,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 14:
                BitBlt(hdc,360,192,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 15:
                BitBlt(hdc,480,192,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 16:
                  BitBlt(hdc,0,288,120,96,mdc,point[i].x,point[i].y,SRCCOPY);        
                break;
            case 17:
                BitBlt(hdc,120,288,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 18:
                BitBlt(hdc,240,288,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 19:
                BitBlt(hdc,360,288,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 20:
                BitBlt(hdc,480,288,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 21:
                  BitBlt(hdc,0,384,120,96,mdc,point[i].x,point[i].y,SRCCOPY);        
                break;
            case 22:
                BitBlt(hdc,120,384,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 23:
                BitBlt(hdc,240,384,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 24:
                BitBlt(hdc,360,384,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            case 25:
                BitBlt(hdc,480,384,120,96,mdc,point[i].x,point[i].y,SRCCOPY);            
                break;
            default:
                MessageBox(NULL,"贴图序列号错误!","",NULL);
            }
        }    
        for(int j=1;j<=25;j++)
        {
            if(point[j].num==25)
            {
                SelectObject(mdc,empty);
                switch(j)
                {
                case 1:
                      BitBlt(hdc,0,0,120,96,mdc,0,0,SRCCOPY);                
                    break;
                case 2:
                    BitBlt(hdc,120,0,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 3:
                    BitBlt(hdc,240,0,120,96,mdc,0,0,SRCCOPY);                
                    break;
                case 4:
                    BitBlt(hdc,360,0,120,96,mdc,0,0,SRCCOPY);                
                    break;
                case 5:
                    BitBlt(hdc,480,0,120,96,mdc,0,0,SRCCOPY);                
                    break;
                case 6:
                      BitBlt(hdc,0,96,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 7:
                    BitBlt(hdc,120,96,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 8:
                    BitBlt(hdc,240,96,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 9:
                    BitBlt(hdc,360,96,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 10:
                    BitBlt(hdc,480,96,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 11:
                      BitBlt(hdc,0,192,120,96,mdc,0,0,SRCCOPY);        
                    break;
                case 12:
                    BitBlt(hdc,120,192,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 13:
                    BitBlt(hdc,240,192,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 14:
                    BitBlt(hdc,360,192,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 15:
                    BitBlt(hdc,480,192,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 16:
                      BitBlt(hdc,0,288,120,96,mdc,0,0,SRCCOPY);        
                    break;
                case 17:
                    BitBlt(hdc,120,288,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 18:
                    BitBlt(hdc,240,288,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 19:
                    BitBlt(hdc,360,288,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 20:
                    BitBlt(hdc,480,288,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 21:
                      BitBlt(hdc,0,384,120,96,mdc,0,0,SRCCOPY);        
                    break;
                case 22:
                    BitBlt(hdc,120,384,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 23:
                    BitBlt(hdc,240,384,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 24:
                    BitBlt(hdc,360,384,120,96,mdc,0,0,SRCCOPY);            
                    break;
                case 25:
                    BitBlt(hdc,480,384,120,96,mdc,0,0,SRCCOPY);            
                    break;
                default:
                    ;
                }break;     //遇到成功的就跳出
            }
        }
        int finish=0;
        for(int k=1;k<=25;k++)
        {
            if(point[k].num==k)
                finish++;
        }
        if(finish==25)
        {
            fin=true;
            sndPlaySound("Source\\sound\\FTELEP2电火花.wav",SND_ASYNC | SND_FILENAME);
            MessageBox(NULL,"Finish! This is the final map! You Win!","恭喜^_^",NULL);
            if(n<high5)
            {
                Sleep(100);
                high5=n;
                SelectObject(mdc,empty);
                BitBlt(hdc,1007,433,100,30,mdc,250,0,SRCCOPY);
                sprintf(str,"%d",high5);
                TextOut(hdc,1007,433,str,strlen(str));
                sndPlaySound("Source\\sound\\new.wav",SND_ASYNC | SND_FILENAME);
                MessageBox(NULL,"THE NEW RECORD!","恭喜^_^",NULL);    
                Save();
            }
        }
    }

}

void Change_Block(int block1,int block2)
{
    int temp=0;
    temp=point[block1].x;
    point[block1].x=point[block2].x;
    point[block2].x=temp;
    temp=point[block1].y;
    point[block1].y=point[block2].y;
    point[block2].y=temp;
    temp=point[block1].num;
    point[block1].num=point[block2].num;
    point[block2].num=temp;
}

void Save()
{
    FILE *fp;
    if((fp=fopen("Source\\record","wb+"))==NULL)
    {
        MessageBox(NULL,"不能打开record文件,可能被删除,请在Source中重新建立.","",NULL);
        return;
    }
    if(fwrite(&high3,sizeof(high3),1,fp)!=1)
       MessageBox(NULL,"不能写入记录","",NULL);
    if(fwrite(&high4,sizeof(high4),1,fp)!=1)
       MessageBox(NULL,"不能写入记录","",NULL);
    if(fwrite(&high5,sizeof(high5),1,fp)!=1)
       MessageBox(NULL,"不能写入记录","",NULL);
    fclose(fp);
}

void GetPos()
{
    int now_pos;
    for(int j=1;j<=25;j++)
    {
        point[j].num=j;
    }
    int i;
    switch(line)
    {
    case 3:
        now_pos=9;
        for(i=1;i<=9;i++)                                    //对各块从原图中哪个位置读图的坐标进行赋值
        {
            switch(point[i].num)
            {
            case 1:point[i].x=0;    point[i].y=0;  break;
            case 2:point[i].x=200;  point[i].y=0;  break;
            case 3:point[i].x=400;  point[i].y=0;  break;
            case 4:point[i].x=0;    point[i].y=160;break;
            case 5:point[i].x=200;  point[i].y=160;break;
            case 6:point[i].x=400;  point[i].y=160;break;
            case 7:point[i].x=0;    point[i].y=320;break;
            case 8:point[i].x=200;  point[i].y=320;break;
            case 9:point[i].x=400;  point[i].y=320;break;
            default:MessageBox(NULL,"初始化point[i]坐标错误!","",NULL);
            }
        }
        break;
    case 4:
        now_pos=16;
        for(i=1;i<=16;i++)                                    //对各块从原图中哪个位置读图的坐标进行赋值
        {
            switch(point[i].num)
            {
            case 1:point[i].x=0;    point[i].y=0;    break;
            case 2:point[i].x=150;  point[i].y=0;    break;
            case 3:point[i].x=300;  point[i].y=0;    break;
            case 4:point[i].x=450;  point[i].y=0;    break;
            case 5:point[i].x=0;    point[i].y=120;  break;
            case 6:point[i].x=150;  point[i].y=120;  break;
            case 7:point[i].x=300;  point[i].y=120;  break;
            case 8:point[i].x=450;  point[i].y=120;  break;
            case 9:point[i].x=0;    point[i].y=240;  break;
            case 10:point[i].x=150; point[i].y=240;  break;
            case 11:point[i].x=300; point[i].y=240;  break;
            case 12:point[i].x=450; point[i].y=240;  break;
            case 13:point[i].x=0;   point[i].y=360;  break;
            case 14:point[i].x=150; point[i].y=360;  break;
            case 15:point[i].x=300; point[i].y=360;  break;
            case 16:point[i].x=450; point[i].y=360;  break;
            default:MessageBox(NULL,"初始化point[i]坐标错误!","",NULL);
            }
        }
        break;
    case 5:
        now_pos=25;
        for(i=1;i<=25;i++)                                    //对各块从原图中哪个位置读图的坐标进行赋值
        {
            switch(point[i].num)
            {
            case 1:point[i].x=0;    point[i].y=0;    break;
            case 2:point[i].x=120;  point[i].y=0;    break;
            case 3:point[i].x=240;  point[i].y=0;    break;
            case 4:point[i].x=360;  point[i].y=0;    break;
            case 5:point[i].x=480;  point[i].y=0;    break;
            case 6:point[i].x=0;    point[i].y=96;   break; 
            case 7:point[i].x=120;  point[i].y=96;   break; 
            case 8:point[i].x=240;  point[i].y=96;   break; 
            case 9:point[i].x=360;  point[i].y=96;   break; 
            case 10:point[i].x=480; point[i].y=96;   break; 
            case 11:point[i].x=0;   point[i].y=192;  break; 
            case 12:point[i].x=120; point[i].y=192;  break; 
            case 13:point[i].x=240; point[i].y=192;  break; 
            case 14:point[i].x=360; point[i].y=192;  break; 
            case 15:point[i].x=480; point[i].y=192;  break; 
            case 16:point[i].x=0;   point[i].y=288;  break; 
            case 17:point[i].x=120; point[i].y=288;  break; 
            case 18:point[i].x=240; point[i].y=288;  break; 
            case 19:point[i].x=360; point[i].y=288;  break; 
            case 20:point[i].x=480; point[i].y=288;  break; 
            case 21:point[i].x=0;   point[i].y=384;  break; 
            case 22:point[i].x=120; point[i].y=384;  break; 
            case 23:point[i].x=240; point[i].y=384;  break; 
            case 24:point[i].x=360; point[i].y=384;  break; 
            case 25:point[i].x=480; point[i].y=384;  break; 
            default:MessageBox(NULL,"初始化point[i]坐标错误!","",NULL);
            }
        }
        break;
    default:;
    }
    srand((unsigned)time(NULL));

    for(int k=0;k<200;k++)
    {
        switch(rand()%4)
        {
        case 0:
            if((now_pos+1) % line!=1)
            {
                Change_Block(now_pos,now_pos+1);
                now_pos++;
            }
            break;
        case 1:
            if((now_pos-1) % line!=0)
            {
                Change_Block(now_pos,now_pos-1);
                now_pos--;
            }
            break;
        case 2:
            if(now_pos+line < line*line)
            {
                Change_Block(now_pos,now_pos+line);
                now_pos+=line;
            }
            break;
        case 3:
            if(now_pos-line>0)
            {
                Change_Block(now_pos,now_pos-line);
                now_pos-=line;
            }
            break;
        default:;
        }
    }
}