INFINITY MAZE

· · 休闲·娱乐

INFINITY MAZE

你被困在了一个 128\times128 的迷宫中,这可不是一个好消息,因为你只有一个光源了,它还能使用2000秒,并且迷宫每 30s 刷新一次地形,你以前走的路都可能会是一条非常长的死路,你没有机会出去的!本程序使用空间填充曲线迷宫生成法,为了防止你觉得陷入了循环,我们贴心地为你准备了定位器,你可以知道你现在的坐标。

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME)&0x8000)?1:0)
struct Button{
    int x,y,color;
    const char *name;
    int len;
};
struct Point{
    int x,y;
    Point():x(0),y(0){}
    Point(int x,int y):x(x),y(y){}
};mt19937_64 rd(time(0));
void rot(int n,Point& pt,int rx,int ry){
    if(ry==0){
        if(rx==1){
            pt.x=n-1-pt.x;
            pt.y=n-1-pt.y;
        }
        int temp=pt.x;
        pt.x=pt.y;
        pt.y=temp;
    }
}
void d2xy(int n,int d,Point& pt){
    int rx,ry,s,t=d;
    pt.x=pt.y=0;
    for(s=1;s<n;s<<=1){
        rx=1&(t/2);
        ry=1&(t^rx);
        rot(s,pt,rx,ry);
        pt.x+=s*rx;
        pt.y+=s*ry;
        t/=4;
    }
}
int xy2d(int n,const Point& pt){
    int rx,ry,s,d=0;
    Point tempPt=pt;
    for(s=n/2;s>0;s>>=1){
        rx=((tempPt.x&s)>0)?1:0;
        ry=((tempPt.y&s)>0)?1:0;
        d+=s*s*((3*rx)^ry);
        rot(s,tempPt,rx,ry);
    }
    return d;
}
void color(int a){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);}
void gto(int x,int y){
    COORD pos;pos.X=y;pos.Y=x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void setsize(int col, int row){
    char cmd[64];
    sprintf(cmd,"mode con cols=%d lines=%d",col,row);
    system(cmd);
}
void GetPos(POINT &pt){
    HWND hwnd=GetForegroundWindow();
    GetCursorPos(&pt);
    ScreenToClient(hwnd,&pt);
    pt.y=pt.y/16,pt.x=pt.x/16;
}
Button NewButton(int x,int y,int color,const char *name){
    Button t;
    t.x=x,t.y=y,t.name=name;
    t.color=color;
    t.len=strlen(name);
    return t;
}
bool Preserve(Button A){
    gto(A.x,A.y),color(A.color),printf("%s",A.name);
    POINT pt;GetPos(pt);
    if(pt.y==A.x&&(pt.x>=A.y/2&&pt.x<=A.y/2+A.len/2)){
        color(A.color+16),gto(A.x,A.y),printf("%s",A.name);
        if(KEY_DOWN(MOUSE_MOVED)) return 1;
    }
    return 0;
}
atomic_int timer;
int x=511,y=3,hilbert[150][150];
atomic_int maze[520][520];
atomic_int backup[520][520];
bool flag=0;
inline void get_maze(atomic_int (&mz)[520][520]){
    memset(mz,0,sizeof mz);
    for(int i=1;i<=513;i++)
        mz[1][i]=mz[513][i]=
        mz[i][1]=mz[i][513]=1;
    for(int i=5;i<=513;i+=4)
        for(int j=5;j<=513;j+=4)
            mz[i][j]=2;
    for(int i=1;i<=128;i++)
        for(int j=1;j<=128;j++){
            if(i==1&&j==128)continue;
            vector<int>v;
            if(hilbert[i][j]<hilbert[i+1][j])v.push_back(1);
            if(hilbert[i][j]<hilbert[i-1][j])v.push_back(2);
            if(hilbert[i][j]<hilbert[i][j-1])v.push_back(3);
            if(hilbert[i][j]<hilbert[i][j+1])v.push_back(4);
            int x=v[rd()%int(v.size())];
            switch(x){
                case 1:
                    mz[4*i+1][4*j-2]=
                    mz[4*i+1][4*j-1]=
                    mz[4*i+1][4*j]=-1;
                    break;
                case 2:
                    mz[4*i-3][4*j-2]=
                    mz[4*i-3][4*j-1]=
                    mz[4*i-3][4*j]=-1;
                    break;
                case 3:
                    mz[4*i-2][4*j-3]=
                    mz[4*i-1][4*j-3]=
                    mz[4*i][4*j-3]=-1;
                    break;
                case 4:
                    mz[4*i-2][4*j+1]=
                    mz[4*i-1][4*j+1]=
                    mz[4*i][4*j+1]=-1;
                    break;
            }
        }
    for(int i=1;i<=128;i++)
        for(int j=1;j<=128;j++){
            if(mz[4*i-3][4*j-2]!=-1)
                mz[4*i-3][4*j-2]=
                mz[4*i-3][4*j-1]=
                mz[4*i-3][4*j]=1;
            if(mz[4*i-2][4*j-3]!=-1)
                mz[4*i-2][4*j-3]=
                mz[4*i-1][4*j-3]=
                mz[4*i][4*j-3]=1;
        }
    for(int i=1;i<=513;i++)
        for(int j=1;j<=513;j++)
            if(mz[i][j]==-1)mz[i][j]=0;
    for(int i=2;i<=4;i++)
        for(int j=510;j<=512;j++)
            mz[i][j]=3;
    if(rd()%2==0)
        for(int i=1;i<=513;i++)
            for(int j=1;j<=513-i;j++){
                atomic_int tmp;
                tmp.store(mz[i][j].load());
                mz[i][j].store(mz[514-j][514-i].load());
                mz[514-j][514-i].store(tmp.load());
            }

}
void Timer(){
    while(true){
        ++timer;
        if(timer>=2000){
            gto(4,8);
            color(71);
            printf("Time is up!");
            exit(0);
        }
        Sleep(998);
    }
}
void Mapper(){
    int turn=0;
    while(true)
        if(turn*30<=timer){
            get_maze(backup);
            flag=1;
            turn++;
        }
}
void draw(){
    gto(0,0);color(7);
    printf("x=%04d  %04ds      ",(y-1)/4,2000-timer);
    printf("y=%04d  hurry up!    ",(513-x)/4);
    for(int i=-1;i<=1;i++){
        gto(4+i,10);
        for(int j=-1;j<=1;j++){
            if(i==j&&i==0){
                color(12);
                printf("■");
                color(7);
                continue;
            }
            if(maze[x+i][y+j]==0){
                printf(" ");
                continue;
            }
            if(maze[x+i][y+j]==1){
                printf("■");
                continue;
            }
            if(maze[x+i][y+j]==2){
                color(11);
                printf("■");
                color(7);
                continue;
            }
            if(maze[x+i][y+j]==3){
                color(160);
                printf(" ");
                color(7);
                continue;
            }
        }
    }
    if(maze[x-1][y-1]==0||maze[x-1][y-1]==3){
        gto(2,10);
        if(maze[x-2][y-1]==0)
            printf(" ");
        if(maze[x-2][y-1]==1)
            printf("■");
        if(maze[x-2][y-1]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x-2][y-1]==3){
            color(160);
            printf(" ");
            color(7);
        }
        gto(3,8);
        if(maze[x-1][y-2]==0)
            printf(" ");
        if(maze[x-1][y-2]==1)
            printf("■");
        if(maze[x-1][y-2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x-1][y-2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(2,10);printf("■");
        gto(3,8);printf("■");
        color(7);
    }
    if(maze[x-1][y+1]==0||maze[x-1][y+1]==3){
        gto(2,14);
        if(maze[x-2][y+1]==0)
            printf(" ");
        if(maze[x-2][y+1]==1)
            printf("■");
        if(maze[x-2][y+1]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x-2][y+1]==3){
            color(160);
            printf(" ");
            color(7);
        }
        gto(3,16);
        if(maze[x-1][y+2]==0)
            printf(" ");
        if(maze[x-1][y+2]==1)
            printf("■");
        if(maze[x-1][y+2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x-1][y+2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(2,14);printf("■");
        gto(3,16);printf("■");
        color(7);
    }
    if(maze[x+1][y-1]==0||maze[x+1][y-1]==3){
        gto(6,10);
        if(maze[x+2][y-1]==0)
            printf(" ");
        if(maze[x+2][y-1]==1)
            printf("■");
        if(maze[x+2][y-1]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x+2][y-1]==3){
            color(160);
            printf(" ");
            color(7);
        }
        gto(5,8);
        if(maze[x+1][y-2]==0)
            printf(" ");
        if(maze[x+1][y-2]==1)
            printf("■");
        if(maze[x+1][y-2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x+1][y-2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(6,10);printf("■");
        gto(5,8);printf("■");
        color(7);
    }
    if(maze[x+1][y+1]==0||maze[x+1][y+1]==3){
        gto(6,14);
        if(maze[x+2][y+1]==0)
            printf(" ");
        if(maze[x+2][y+1]==1)
            printf("■");
        if(maze[x+2][y+1]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x+2][y+1]==3){
            color(160);
            printf(" ");
            color(7);
        }
        gto(5,16);
        if(maze[x+1][y+2]==0)
            printf(" ");
        if(maze[x+1][y+2]==1)
            printf("■");
        if(maze[x+1][y+2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x+1][y+2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(6,14);printf("■");
        gto(5,16);printf("■");
        color(7);
    }
    if(maze[x-1][y]==0||maze[x-1][y]==3){
        gto(2,12);
        if(maze[x-2][y]==0)
            printf(" ");
        if(maze[x-2][y]==1)
            printf("■");
        if(maze[x-2][y]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x-2][y]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(2,12);printf("■");
        color(7);
    }
    if(maze[x+1][y]==0||maze[x+1][y]==3){
        gto(6,12);
        if(maze[x+2][y]==0)
            printf(" ");
        if(maze[x+2][y]==1)
            printf("■");
        if(maze[x+2][y]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x+2][y]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(6,12);printf("■");
        color(7);
    }
    if(maze[x][y-1]==0||maze[x][y-1]==3){
        gto(4,8);
        if(maze[x][y-2]==0)
            printf(" ");
        if(maze[x][y-2]==1)
            printf("■");
        if(maze[x][y-2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x][y-2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(4,8);printf("■");
        color(7);
    }
    if(maze[x][y+1]==0||maze[x][y+1]==3){
        gto(4,16);
        if(maze[x][y+2]==0)
            printf(" ");
        if(maze[x][y+2]==1)
            printf("■");
        if(maze[x][y+2]==2){
            color(11);
            printf("■");
            color(7);
        }
        if(maze[x][y+2]==3){
            color(160);
            printf(" ");
            color(7);
        }
    }
    else{
        color(8);
        gto(4,16);printf("■");
        color(7);
    }
    gto(7,0);color(7);
    printf("target:(127,127)     ");

}
int main(){
    SetConsoleTitle("INFINITY MAZE");
    SetWindowLongPtrA(GetConsoleWindow(),GWL_STYLE,GetWindowLongPtrA(
    GetConsoleWindow(),GWL_STYLE)&~WS_SIZEBOX&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX);
    CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
    setsize(26,8);
    int n=128;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            hilbert[i+1][j+1]=xy2d(n,Point(j,i));
    color(7);
    printf("■■   ■■■■■■■■");
    printf("■■   ■■■■■■■■");
    printf("             ");
    color(12);
    printf("  -=≡■       ");
    color(7);
    printf("             ");
    printf("■■   ■■■■■■■■");
    printf("■■   ■■■■■■■■");
    printf("■■   ■■■■■■■■");
    Button btn=NewButton(3,16,63,"Escape");
    while(1){
        if(Preserve(btn))
            break;
        Sleep(100);
    }
    color(7);
    system("cls");
    thread tmr(Timer);
    tmr.detach();
    thread mpr(Mapper);
    mpr.detach();
    get_maze(maze);
    while(1){
        draw();
        if(flag==1){
            memcpy(maze,backup,sizeof(backup));
            flag=0;
            continue;
        }
        if(maze[x][y]==3){gto(4,9);color(71);printf("Perfect!");exit(0);}
        if(KEY_DOWN('W')){
            int xx=x-1;
            int yy=y;
            if(maze[xx][yy]==1||maze[xx][yy]==2);
            else{
                x=xx,y=yy;
                Sleep(75);
                continue;
            }
        }
        if(KEY_DOWN('A')){
            int xx=x;
            int yy=y-1;
            if(maze[xx][yy]==1||maze[xx][yy]==2);
            else{
                x=xx,y=yy;
                Sleep(75);
                continue;
            }
        }
        if(KEY_DOWN('S')){
            int xx=x+1;
            int yy=y;
            if(maze[xx][yy]==1||maze[xx][yy]==2);
            else{
                x=xx,y=yy;
                Sleep(75);
                continue;
            }
        }
        if(KEY_DOWN('D')){
            int xx=x;
            int yy=y+1;
            if(maze[xx][yy]==1||maze[xx][yy]==2);
            else{
                x=xx,y=yy;
                Sleep(75);
                continue;
            }
        }
    }
    return 0;
}