AK-IOI复刻

· · 个人记录

AK-IOI复刻

作者链接(顺序不分先后):

(luogu)

https://www.luogu.com.cn/user/429147

https://www.luogu.com.cn/user/218376

(codeforces)

https://codeforces.com/profile/hxhhxh

https://codeforces.com/profile/tujunbo

编译环境

建议:-std=c++14 -Wall -Wextra -Wno-sign-compare -Wunreachable-code -Wpointer-arith -Wfloat-equal

更新记录

2021.11.12:

随意大小与分数显示

Ctrl可以强制刷新屏幕,解决调整窗口时导致屏幕混乱的问题

代码

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
#define O(a,b) ((a==19 && b!=15 && b!=16 && b!=17 && b!=18 && b!=19) || (b==19 && a!=15 && a!=16 && a!=17 && a!=18 && a!=19))
#define J(a,b) ((a==17 && b!=18 && b!=19) || (b==17 && a!=18 && a!=19))
int t[2020][2020],lt[2020][2020],cas,score;
int dx[5]={0,-1,0,1,0};
int dy[5]={0,0,-1,0,1};
int n;
char str[2020][2020]={"\033[0m   ","\033[43m\033[1m CE","\033[46m\033[97mJUG","\033[105m\033[97m RE","\033[44m\033[97mTLE","\033[44m\033[97mMLE","\033[44m\033[97mILE","\033[44m\033[97mOLE","\033[100m\033[97mUKE","\033[101m\033[97m WA","\033[41m\033[33m PC","\033[102m\033[97m AC","\033[45m\033[97m PE","\033[43m\033[30mDOJ","\033[107m\033[95mSJE","\033[103m \033[4mAU","\033[104m\033[97m AK","\033[40m\033[97m # ","\033[100m\033[97m O2","\033[100m\033[97m O3","   ","   ","   "};
int dtsc[2020]={2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,0,-2,-4,0,0,0};
void maker(){printf("\033[?25l");for(register int i=18;i>=1;--i){system("cls");if(GetAsyncKeyState(VK_CONTROL)!=0)break;printf("\033[%dm",(i-1)%6+32);for(register int j=1;j<=i;++j)putchar('\n');printf("Maker:\n");printf("(luogu)    218376 ,429147\n");printf("(codeforces)tujunbo,hxhhxh\n");printf("\033[0m");Sleep(50);}system("cls");printf("Maker:\n");printf("(luogu)    218376 ,429147\n");printf("(codeforces)tujunbo,hxhhxh\n");Sleep(100);printf("\033[?25h");}
void setpos(int x,int y){static HANDLE m=GetStdHandle(STD_OUTPUT_HANDLE);COORD cp={x,y};SetConsoleCursorPosition(m,cp);}
void remap(){
    for(register int i=0;i<=n+1;++i){
        for(register int j=0;j<=n+1;++j){
            lt[i][j]=t[i][j];
        }
    }
}
void output(){
    system("cls");
    printf("\n");
    for(register int i=1;i<=n*2+33;++i)putchar(' ');
    printf("AK-IOI\n");
    printf("\n");
    printf("                                   ");
    for(register int j=0;j<=n*4;++j)putchar('-');
    putchar('\n');
    for(register int i=1;i<=n;++i){
        printf("                                   |");
        for(register int j=1;j<=n;++j){
            printf("%s\033[0m|",str[t[i][j]]);
        }
        printf("\n                                   "); 
        for(register int j=0;j<=n*4;++j)putchar('-');
        putchar('\n');
    }
    if(score>1073741823)score=1073741823;
    for(register int i=1;i<=n*2+27;++i)putchar(' ');
    printf("score:%10d\n",score);
    for(register int i=1;i<=7;++i){
        for(register int i=1;i<=n*2+17;++i)putchar(' ');
        putchar('|');
        for(register int j=1;j<=3;++j){
            printf("%s\033[0m : %5d|",str[(i-1)*3+j],dtsc[(i-1)*3+j-1]);
        }
        putchar('\n');
    }
}
void newput(){
    for(register int i=1;i<=n;++i){
        for(register int j=1;j<=n;++j){
            if(t[i][j]!=lt[i][j]){
                setpos(36+(j-1)*4,4+(i-1)*2);
                printf("%s\033[0m",str[t[i][j]]);
            }
        }
    }
    setpos(n*2+27,4+2*n);
    if(score>1073741823)score=1073741823;
    printf("score:%10d\n",score);
}
void randput(){
    int x=rand()%n+1,y=rand()%n+1,v=rand()%100+1;
    if(v<=60) v=1;
    else if(v<=85) v=2;
    else if(v<=93) v=17;
    else v=18;
    while(t[x][y]!=0) x=rand()%n+1,y=rand()%n+1;
    t[x][y]=v;
}
bool pd(){
    #define sames(i,j) ((i==j && i!=19) || (i==18 && j!=17 && j!=19) || (j==18 && i!=17 && i!=19))
    for(register int i=1;i<=n;++i){
        for(register int j=1;j<=n;++j){
            if(t[i][j]==16)return true;
        }
    }
    for(register int i=1;i<=n;++i){
        for(register int j=1;j<=n;++j){
            if(!t[i][j])return false;
            for(register int d=1;d<=4;++d){
                if(i+dx[d]<1 || n<i+dx[d])continue;
                if(j+dy[d]<1 || n<j+dy[d])continue;
                if(!t[i+dx[d]][j+dy[d]])return false;
                else if(O(t[i+dx[d]][j+dy[d]],t[i][j]))return false;
                else if(J(t[i+dx[d]][j+dy[d]],t[i][j]))return false;
                else if(sames(t[i+dx[d]][j+dy[d]],t[i][j]))return false;
            }
        }
    }
    return true;
}
bool vis[2020][2020];
bool mve[2020][2020];
bool poi(int i,int j,int d){
    if(!t[i][j])return false;
    if(!t[i+dx[d]][j+dy[d]]){
        mve[i][j]=mve[i+dx[d]][j+dy[d]]=0;
        swap(t[i+dx[d]][j+dy[d]],t[i][j]);
        swap(vis[i+dx[d]][j+dy[d]],vis[i][j]);
    }else if(((t[i+dx[d]][j+dy[d]]==18 && t[i][j]!=17 && t[i][j]!=19 && mve[i+dx[d]][j+dy[d]] && mve[i][j]) || (t[i][j]==18 && t[i+dx[d]][j+dy[d]]!=17 && t[i+dx[d]][j+dy[d]]!=19 && mve[i][j] && mve[i+dx[d]][j+dy[d]]) || (t[i+dx[d]][j+dy[d]]==t[i][j] && t[i][j]!=18 && t[i][j]!=19)) && vis[i][j] && vis[i+dx[d]][j+dy[d]]){
        mve[i][j]=mve[i+dx[d]][j+dy[d]]=0;
        vis[i][j]=vis[i+dx[d]][j+dy[d]]=0;
        t[i+dx[d]][j+dy[d]]=(t[i+dx[d]][j+dy[d]]==18?t[i][j]:t[i+dx[d]][j+dy[d]])+1;
        t[i][j]=0;
        score+=dtsc[t[i+dx[d]][j+dy[d]]-1];
    }else if(O(t[i+dx[d]][j+dy[d]],t[i][j]) && vis[i][j] && vis[i+dx[d]][j+dy[d]]){
        mve[i][j]=mve[i+dx[d]][j+dy[d]]=0;
        vis[i][j]=vis[i+dx[d]][j+dy[d]]=0;
        t[i+dx[d]][j+dy[d]]=(t[i+dx[d]][j+dy[d]]==19?t[i][j]:t[i+dx[d]][j+dy[d]])+2;
        t[i][j]=0;
        score+=dtsc[t[i+dx[d]][j+dy[d]]-1];
    }else if(J(t[i+dx[d]][j+dy[d]],t[i][j]) && vis[i][j] && vis[i+dx[d]][j+dy[d]] && mve[i][j] && mve[i+dx[d]][j+dy[d]]){
        mve[i][j]=mve[i+dx[d]][j+dy[d]]=0;
        vis[i][j]=vis[i+dx[d]][j+dy[d]]=0;
        t[i+dx[d]][j+dy[d]]=(t[i+dx[d]][j+dy[d]]==17?t[i][j]:t[i+dx[d]][j+dy[d]]);
        t[i][j]=0;
        score+=dtsc[t[i+dx[d]][j+dy[d]]-1];
    }else{
        return false;
    }
    return true;
}
bool mov(int d){
    memset(vis,true,sizeof(vis));
    memset(mve,true,sizeof(vis));
    bool sf=false;
    for(int _=1;_<=n*n;_++){
        if(d==1){
            for(register int i=2;i<=n;++i){
                for(register int j=1;j<=n;++j){
                    sf|=poi(i,j,d);
                }
            }
        }else if(d==2){
            for(register int i=1;i<=n;++i){
                for(register int j=2;j<=n;++j){
                    sf|=poi(i,j,d);
                }
            }
        }else if(d==3){
            for(register int i=n-1;i;--i){
                for(register int j=n;j;--j){
                    sf|=poi(i,j,d);
                }
            }
        }else{
            for(register int i=n;i;--i){
                for(register int j=n-1;j;--j){
                    sf|=poi(i,j,d);
                }
            }
        }
    }
    return sf;
}
bool win(){
    for(register int i=1;i<=n;i++) for(register int j=1;j<=n;j++) if(t[i][j]==16) return true;
    return false;
}
int main(){
    printf("\033[40\033[37");
    srand(time(NULL));
    system("cls");
    maker();
    Sleep(1000);
    printf("Press space to start.\n");
    while(GetAsyncKeyState(VK_SPACE)==0)Sleep(10);
    system("cls");
    printf("SIZE(4-1000): ");
    scanf("%d",&n);
    while(n<4 || n>1000){
        system("cls");
        printf("SIZE(4-1000): ");
        scanf("%d",&n);
    }
    start:;
    system("cls");
    printf("start game?1:0\n");
    cin>>cas;
    if(cas==0){
        system("cls");
        printf("good bye!");
        return 0;

    }
    memset(t,0,sizeof(t));
    score=0;
    printf("\033[?25l");
    randput();
    output();
    remap();
    while(1){
        randput();
        newput();
        remap();
        if(pd())break;
        at:;
        bool p1=false,p2=false,p3=false,p4=false,p5=false,p6=false,p7=false,p8=false;
        while(!(p1||p2||p3||p4)){
            if(GetAsyncKeyState(VK_CONTROL)!=0)output();
            p1=(GetAsyncKeyState(VK_UP)!=0);
            p2=(GetAsyncKeyState(VK_LEFT)!=0);
            p3=(GetAsyncKeyState(VK_DOWN)!=0);
            p4=(GetAsyncKeyState(VK_RIGHT)!=0);
        }
        p5=p1;
        p6=p2;
        p7=p3;
        p8=p4;
        while(p5||p6||p7||p8){
            if(p1) p5=(GetAsyncKeyState(VK_UP)!=0);
            if(p2) p6=(GetAsyncKeyState(VK_LEFT)!=0);
            if(p3) p7=(GetAsyncKeyState(VK_DOWN)!=0);
            if(p4) p8=(GetAsyncKeyState(VK_RIGHT)!=0);
        }
        int dir;
        if(p1) dir=1;
        else if(p2) dir=2;
        else if(p3) dir=3;
        else dir=4;
        if(!mov(dir)) goto at;
    }
    printf("\033[?25h");
    output();
    for(register int i=1;i<=n*2;++i)putchar(' ');
    if(win())printf("                                 YOU AK IOI!\n");
    else printf("                                     AFO\n");
    for(register int i=1;i<=n*2;++i)putchar(' ');
    printf("                               your score:%d\n",score);
    for(register int i=1;i<=n*2;++i)putchar(' ');
    printf("                            Press space to start.\n");
    while(GetAsyncKeyState(VK_SPACE)==0)Sleep(10);
    goto start;
}