#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
int m=10,n=10,step,shortest,wave;
int px,py,ex,ey,foggy=0;
char go,again='Y',rule;
int pf=0;
string me="@",wall="#",focus="$";
int P=0,S=0,A=0,B=0,C=0;
int mat[1000][1000],path[1000][1000],dir[5][5]={{-1,0},{1,0},{0,-1},{0,1}};
struct coor{
	int x,y;
};
string nd[10]={"Eazy","Hard!","Crazy!!!"};
int idx=1;
void colorful(int,string);
int c_main_game();
int e_main_game();
int c_options();
int choose_languagu(){
	system("cls");
	char cz;
	cout<<"+=----- choose a languagu -----=+"<<endl;
	cout<<"C : 中文"<<endl;
	cout<<"E : English"<<endl;
	cout<<"[cin]>>";
	cin>>cz;
	if(cz=='C'){
		c_main_game();
		return 0;
	}
	else if(cz=='E'){
		e_main_game();
	}
	else{
		cout<<"Error!";
		Sleep(1000);
		choose_languagu();
		return 0;
	}
}
queue<coor> arrive;
int e_options(){
	system("cls");
	char cz;
	cout<<"~------- Optins -------~"<<endl;
	cout<<"A : Set the size of the maze"<<endl;
	cout<<"B : Set the brightness of the flashlight"<<endl;
	cout<<"C : Change the icon settings"<<endl;
	cout<<"D : Current language : ";
	colorful(9,"English");
	cout<<endl;
	cout<<"F : Current difficulty : ";
	if(idx==0){
		colorful(2,nd[idx]);
		cout<<endl; 
	}
	else if(idx==1){
		colorful(4,nd[idx]);
		cout<<endl; 
	}
	else if(idx==2){
		colorful(5,nd[idx]);
		cout<<endl; 
	}
	cout<<"Current data:"<<endl;
	printf("P=%d,S=%d,A=%d,B=%d,C=%d\n",P,S,A,B,C);
	
	cout<<"E : Exit"<<endl; 
	cout<<"[cin]>>";
	cin>>cz;
	if(cz=='A'){
		cout<<"Please enter the size of the maze(m*n)"<<endl<<"[cin]>>";
		scanf("%d*%d",&m,&n);
		Sleep(500);
		cout<<"Save successfully!" <<endl;
		e_options();
		return 0; 
	}
	else if(cz=='B'){
		cout<<"Please enter the brightness of the flashlight (full brightness is 0)"<<endl<<"[cin]>>";
		scanf("%d",&foggy);
		foggy/=2;
		Sleep(500);
		cout<<"Save successfully!" <<endl;
		e_options();
		return 0; 
	}
	else if(cz=='C'){
		char cz_2;
		system("cls");
		cout<<"A : (Template) classic" <<endl;
		cout<<"B : (Template) point of the legend"<<endl;
		cout<<"C : (Template) ancient"<<endl;
		cout<<"D : Custom"<<endl;
		cout<<"[cin]>>";
		cin>>cz_2;
		if(cz_2=='A'){
			me='@';
			wall='#';
			focus='$';
            Sleep(500);
            cout<<"Save successfully!" <<endl;
            e_options();
            return 0;
        }
        else if(cz_2=='B'){
            me=',';
            wall='.';
            focus='`';
            Sleep(500);
            cout<<"Save successfully!!" <<endl;
            e_options();
            return 0;
        }
        else if(cz_2=='C'){
            me='+';
            wall='*';
            focus='!';
            Sleep(500);
            cout<<"Save successfully!" <<endl;
            e_options();
            return 0;
        }
        else if(cz_2=='D'){
            cout<<"Please enter the 'me' icon"<<endl<<"[cin]>>";
            scanf("%s",&me); 
            cout<<endl<<"Please enter the 'wall' icon"<<endl<<"[cin]>>";
            scanf("%s",&wall);
            cout<<endl<<"Please enter the 'End' icon"<<endl<<"[cin]>>";
            scanf("%s",&focus);
            Sleep(500);
            cout<<"Save successfully!" <<endl;
            e_options();
            return 0;
        }
        else{
            cout<<"Error!!!"<<endl;
            e_options();
            return 0;
        }
    }
    else if(cz=='D'){
        c_options();
        return 0;
    }
    else if(cz=='F'){
        idx++;
        if(idx==3){
            idx=0;
        }
        e_options();
        return 0;
    }
    else if(cz=='E'){
        e_main_game();
        return 0; 
    }
    else{
        cout<<"Error!!!"<<endl;
        e_options();
        return 0;
    }
}
int c_options(){
    system("cls");
    char cz;
    cout<<"~------- 设置 -------~"<<endl;
    cout<<"A : 设置迷宫大小"<<endl;
    cout<<"B : 设置手电亮度"<<endl;
    cout<<"C : 更改图标设置"<<endl;
    cout<<"D : 现在语言 : ";
    colorful(6,"中文"); 
    cout<<endl;
    cout<<"F : 当前难度 : "; 
    if(idx==0){
        colorful(2,nd[idx]);
        cout<<endl; 
    }
    else if(idx==1){
        colorful(4,nd[idx]);
        cout<<endl; 
    }
    else if(idx==2){
        colorful(5,nd[idx]);
        cout<<endl; 
    }
    cout<<"目前数据:"<<endl;
    printf("P=%d,S=%d,A=%d,B=%d,C=%d\n",P,S,A,B,C); 
    cout<<"E : 返回"<<endl; 
    cout<<"[cin]>>";
    cin>>cz;
    if(cz=='A'){
        cout<<"请输入迷宫大小(m*n)"<<endl<<"[cin]>>";
        scanf("%d*%d",&m,&n);
        Sleep(500);
        cout<<"保存成功!" <<endl;
        c_options();
        return 0; 
    }
    else if(cz=='B'){
        cout<<"请输入手电亮度(全亮为0)"<<endl<<"[cin]>>";
        scanf("%d",&foggy);
        foggy/=2;
        Sleep(500);
        cout<<"保存成功!" <<endl;
        c_options();
        return 0; 
    }
    else if(cz=='C'){
        char cz_2;
        system("cls");
        cout<<"A : (模板)经典" <<endl;
        cout<<"B : (模板)点的传奇"<<endl;
        cout<<"C : (模板)远古"<<endl;
        cout<<"D : 自定义 Custom"<<endl;
        cout<<"[cin]>>";
        cin>>cz_2;
        if(cz_2=='A'){
            me='@';
            wall='#';
            focus='$';
            Sleep(500);
            cout<<"保存成功!" <<endl;
            c_options();
            return 0;
        }
        else if(cz_2=='B'){
            me=',';
            wall='.';
            focus='`';
            Sleep(500);
            cout<<"保存成功!" <<endl;
            c_options();
            return 0;
        }
        else if(cz_2=='C'){
            me='+';
            wall='*';
            focus='!';
            Sleep(500);
            cout<<"保存成功!" <<endl;
            c_options();
            return 0;
        }
        else if(cz_2=='D'){
            cout<<"请输入'我'的图标"<<endl<<"[cin]>>";
            scanf("%s",&me); 
            cout<<endl<<"请输入'墙'的图标"<<endl<<"[cin]>>";
            scanf("%s",&wall);
            cout<<endl<<"请输入'终点'的图标"<<endl<<"[cin]>>";
            scanf("%s",&focus);
            Sleep(500);
            cout<<"保存成功!" <<endl;
            c_options();
            return 0;
        }
        else{
            cout<<"Error!!!"<<endl;
            c_options();
            return 0;
        }
    }
    else if(cz=='D'){
        e_options();
        return 0;
    }
    else if(cz=='F'){
        idx++;
        if(idx==3){
            idx=0;
        }
        c_options();
        return 0;
    }
    else if(cz=='E'){
        c_main_game();
        return 0; 
    }
    else{
        cout<<"Error!!!"<<endl;
        c_options();
        return 0;
    }
}
void colorful(int word,string content){
    int back=0;
    WORD change=((back&0x0F)<<4)+(word&0x0F);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),change);
    cout<<content;
    change=((back&0x0F)<<4)+(15&0x0F);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),change);
} 
void all_print(){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(i==px&&j==py){
                colorful(12,me);
            }
            else if(i==ex&&j==ey){
                colorful(14,focus);
            }
            else if(mat[i][j]==0){
                colorful(3,wall);
            }
            else if(mat[i][j]==1){
                cout<<" ";
            }
        }
        cout<<endl;
    }
}
void foggy_print(){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(i>=px-foggy&&i<=px+foggy&&j>=py-foggy&&j<=py+foggy){
                if(i==px&&j==py){
                    colorful(12,me);
                }
                else if(i==ex&&j==ey){
                    colorful(14,focus);
                }
                else if(mat[i][j]==0){
                    colorful(3,wall);
                }
                else if(mat[i][j]==1){
                    cout<<" ";
                }
            }
            else{
                cout<<" ";
            }
        }
        cout<<endl;
    }
}
int escape(){
    arrive.push((coor){px,py});
    path[px][py]=0;
    while(!arrive.empty()){
        coor now=arrive.front();
        arrive.pop();
        for(int i=0;i<4;i++){
            int tx=now.x+dir[i][0],ty=now.y+dir[i][1];
            if(tx==1||tx==m||ty==1||ty==m){
                continue;
            }
            if(mat[tx][ty]==0){
                continue;
            }
            if(path[tx][ty]!=-1){
                continue;
            }
            arrive.push((coor){tx,ty});
            path[tx][ty]=path[now.x][now.y]+1;
        }
    }
    return path[ex][ey];
}
void home(){
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD){0,0});
}
void make(int x,int y){
    if(x==1||x==m||y==1||y==n){
        return ;
    }
    if(mat[x][y]==1){
        return ;
    }
    if(mat[x-1][y]+mat[x+1][y]+mat[x][y-1]+mat[x][y+1]>1){
        return ;
    }
    mat[x][y]=1;
    home();
    all_print();
    printf("loading...");
    random_shuffle(dir,dir+4);
    for(int i=0;i<4;i++){
        make(x+dir[i][0],y+dir[i][1]);
    }
}
bool blocked(int x,int y){
    if(mat[x-1][y]+mat[x+1][y]+mat[x][y-1]+mat[x][y+1]==0){
        return true;
    }
    else{
        return false;
    }
}
int e_main_game(){
    char cz;
    system("cls");
    srand(time(0));
    while(again=='Y'){
        system("cls");
        wave++;
        px=0;
        py=0;
        ex=0;
        ey=0;
        colorful(15,"~");
        printf("~~~~~~~~~~~~~~~~~~~~~~~Welcome to the escape room~~~~~~~~~~~~~~~~~~~~~~~~\n");
        cout<<"version: V3.2.0 by ";
        colorful(9,"WxdPea");
        cout<<endl;
        cout<<"S : Start game"<<endl;
        cout<<"O : Opions"<<endl;
        cout<<"W : My homepage"<<endl;
        cout<<"E : Exit"<<endl;
        cout<<"[cin]>>";
        cin>>cz;
        if(cz=='S'){
            if(wave==1){
                printf("\nBefore you start your escape, there are a few rules:");
                Sleep(500);
                printf("\n    1.You are'");
                colorful(12,me);
                printf("',Exit is'");
                colorful(14,focus);
                printf("',wall is'");
                colorful(3,wall);
                printf("',road is' '.");
                Sleep(500);
                printf("\n    2.You can only walk, you can't go through walls, and you can win when you reach the exit.");
                Sleep(500);
                printf("\n    3.In the secret room, use the '↑', '↓', '←', '→' keys to move.");
                Sleep(6000);
            }
            else{
                printf("\nWhether to view the rule ('Y'/'N'): ");
                cin>>rule;
                if(rule=='Y'){
                    printf("\nBefore you start your escape, there are a few rules:");
                    Sleep(500);
                    printf("\n    1.You are'");
                    colorful(12,me);
                    printf("',Exit is'");
                    colorful(14,focus);
                    printf("',wall is'");
                    colorful(3,wall);
                    printf("',road is' '.");
                    Sleep(500);
                    printf("\n    2.You can only walk, you can't go through walls, and you can win when you reach the exit.");
                    Sleep(500);
                    printf("\n    3.In the secret room, use the '↑', '↓', '←', '→' keys to move.");
                    Sleep(6000);
                }
                else{
                    Sleep(1000);
                } 
            }
            system("cls");
            printf("Now, start escaping!");
            Sleep(500);
            system("cls");
            memset(mat,0,sizeof mat);
            all_print();
            make(m/2,n/2);
            while((px==ex&&py==ey)||blocked(px,py)||blocked(ex,ey)||abs(px-ex)+abs(py-ey)<m/2+n/2){
                px=rand()%(m-2)+2;
                py=rand()%(n-2)+2;
                ex=rand()%(m-2)+2;
                ey=rand()%(n-2)+2;
            }
            mat[px][py]=1;
            mat[ex][ey]=1;
            memset(path,-1,sizeof path);
            dir[0][0]=-1;
            dir[0][1]=0;
            dir[1][0]=1;
            dir[1][1]=0;
            dir[2][0]=0;
            dir[2][1]=-1;
            dir[3][0]=0;
            dir[3][1]=1;
            shortest=escape();
            system("cls");
            all_print();
            step=0;
            while(1){
                go=getch();
                if(go==72&&mat[px-1][py]==1){
                    px--;
                    step++;
                }
                else if(go==80&&mat[px+1][py]==1){
                    px++;
                    step++;
                }
                else if(go==75&&mat[px][py-1]==1){
                    py--;
                    step++;
                }
                else if(go==77&&mat[px][py+1]==1){
                    py++;
                    step++;
                }
                if(px==ex&&py==ey){
                    px=0;
                    py=0;
                    home();
                    all_print();
                    Sleep(1000);
                    printf("\nCongratulations, you've escaped the Escape Room!\n");
                    printf("The minimum is %d steps, and you use %d steps.\n",shortest,step);
                    Sleep(1000);
                    cout<<"Your rating is......"<<endl;
                    Sleep(2000); 
                    if(idx==0){
                        if(step-shortest<=10){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=25){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=50){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=75){
                            colorful(2,"B");
                            B++;
                            pf=2;
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    if(idx==1){
                        if(shortest==step){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=10){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=25){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=50){
                            colorful(2,"B");
                            B++;
                            pf=2;
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    else if(idx==2){
                        if(shortest==step){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=5){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=10){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=20){
                            colorful(2,"B");
                            B++;
                            pf=2;
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    if(pf==5){
                        cout<<endl<<"Good Job!!!"<<endl; 
                    }
                    else if(pf==4){
                        cout<<endl<<"Very Good!"<<endl;
                    }
                    else if(pf==3){
                        cout<<endl<<"Pretty Good!"<<endl;
                    }
                    else if(pf==2){
                        cout<<endl<<"Continue Good!"<<endl;
                    }
                    else if(pf==1){
                        cout<<endl<<"e...Come on!"<<endl;
                    }
                    Sleep(5000);
                    break;
                }
                home();
                if(foggy==0){
                    all_print();
                }
                else{
                    foggy_print();
                }
            }
            printf("\n\nContinue to escape ('Y'/'N'): ");
            cin>>again;
        }
        else if(cz=='O'){
            e_options();
            return 0;
        }
        else if(cz=='E'){
            cout<<"Good bye"<<endl;
            return 0;
        }
        else if(cz=='W'){
            system("start http://oj.cqxiaomawang.com:8888/d/CQ02_23012/user/2534");
            return 0;
        }
        else{
            cout<<"Error!!!"<<endl;
            e_main_game();
            return 0;
        }

    }
    system("cls");
    printf("You've escaped %d times in total!",wave);

    Sleep(5000);
    return 0;
}
int c_main_game(){
    char cz;
    system("cls");
    srand(time(0));
    while(again=='Y'){
        system("cls");
        wave++;
        px=0;
        py=0;
        ex=0;
        ey=0;
        colorful(15,"~");
        printf("~~~~~~~~~~~~~~~~~~~~~~~欢迎来到密室逃脱~~~~~~~~~~~~~~~~~~~~~~~~\n");
        cout<<"version: V3.2.0 by ";
        colorful(9,"WxdPea");
        cout<<endl;
        cout<<"S : 开始游戏"<<endl;
        cout<<"O : 设置"<<endl;
        cout<<"W : 我的主页"<<endl;
        cout<<"E : 退出游戏"<<endl;
        cout<<"[cin]>>";
        cin>>cz;
        if(cz=='S'){
            if(wave==1){
                printf("\n在开始逃脱之前,有一些规则:");
                Sleep(500);
                printf("\n    1.你是'");
                colorful(12,me);
                printf("',出口是'");
                colorful(14,focus);
                printf("',墙是'");
                colorful(3,wall);
                printf("',路是' '");
                Sleep(500);
                printf("\n    2.只能走路,不能穿墙,到达出口就算胜利");
                Sleep(500);
                printf("\n    3.在密室中,通过'↑','↓','←','→'键移动");
                Sleep(6000);
            }
            else{
                printf("\n是否查看规则('Y'/'N'): ");
                cin>>rule;
                if(rule=='Y'){
                    printf("\n密室逃脱规则:");
                    Sleep(500);
                    printf("\n    1.你是'");
                    colorful(12,me);
                    printf("',出口是'");
                    colorful(14,focus);
                    printf("',墙是'");
                    colorful(3,wall);
                    printf("',路是' '");
                    Sleep(500);
                    Sleep(500);
                    printf("\n    2.只能走路,不能穿墙,到达出口就算胜利");
                    Sleep(500);
                    printf("\n    3.在密室中,通过'↑','↓','←','→'键移动");
                    Sleep(6000);
                }
                else{
                    Sleep(1000);
                } 
            }
            system("cls");
            printf("现在,开始逃脱!");
            Sleep(500);
            system("cls");
            memset(mat,0,sizeof mat);
            all_print();
            make(m/2,n/2);
            while((px==ex&&py==ey)||blocked(px,py)||blocked(ex,ey)||abs(px-ex)+abs(py-ey)<m/2+n/2){
                px=rand()%(m-2)+2;
                py=rand()%(n-2)+2;
                ex=rand()%(m-2)+2;
                ey=rand()%(n-2)+2;
            }
            mat[px][py]=1;
            mat[ex][ey]=1;
            memset(path,-1,sizeof path);
            dir[0][0]=-1;
            dir[0][1]=0;
            dir[1][0]=1;
            dir[1][1]=0;
            dir[2][0]=0;
            dir[2][1]=-1;
            dir[3][0]=0;
            dir[3][1]=1;
            shortest=escape();
            system("cls");
            all_print();
            step=0;
            while(1){
                go=getch();
                if(go==72&&mat[px-1][py]==1){
                    px--;
                    step++;
                }
                else if(go==80&&mat[px+1][py]==1){
                    px++;
                    step++;
                }
                else if(go==75&&mat[px][py-1]==1){
                    py--;
                    step++;
                }
                else if(go==77&&mat[px][py+1]==1){
                    py++;
                    step++;
                }
                if(px==ex&&py==ey){
                    px=0;
                    py=0;
                    home();
                    all_print();
                    Sleep(1000);
                    printf("\n恭喜你,逃出了密室!\n");
                    printf("最少用%d步,你用了%d步!\n",shortest,step);
                    Sleep(1000);
                    cout<<"你的评分是......"<<endl;
                    Sleep(2000); 
                    if(idx==0){
                        if(step-shortest<=10){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=25){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=50){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=75){
                            colorful(2,"B");
                            B++;
                            pf=2; 
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    if(idx==1){
                        if(shortest==step){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=10){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=25){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=50){
                            colorful(2,"B");
                            B++;
                            pf=2;
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    else if(idx==2){
                        if(shortest==step){
                            colorful(6,"P");
                            cout<<"!!!!!"<<endl;
                            P++;
                            pf=5;
                        }
                        else if(step-shortest<=5){
                            colorful(4,"S");
                            cout<<"!!!"<<endl;
                            S++;
                            pf=4;
                        }
                        else if(step-shortest<=10){
                            colorful(9,"A");
                            cout<<"!"<<endl;
                            A++;
                            pf=3;
                        }
                        else if(step-shortest<=20){
                            colorful(2,"B");
                            B++;
                            pf=2;
                        }
                        else{
                            colorful(7,"C");
                            C++;
                            pf=1;
                        }
                    }
                    if(pf==5){
                        cout<<endl<<"牛逼!!!"<<endl; 
                    }
                    else if(pf==4){
                        cout<<endl<<"very 好!"<<endl;
                    }
                    else if(pf==3){
                        cout<<endl<<"挺不错的!"<<endl;
                    }
                    else if(pf==2){
                        cout<<endl<<"再接再厉!"<<endl;
                    }
                    else if(pf==1){
                        cout<<endl<<"e...加油!"<<endl;
                    }
                    Sleep(5000);
                    break;
                }
                home();
                if(foggy==0){
                    all_print();
                }
                else{
                    foggy_print();
                }
            }
            printf("\n\n是否继续逃脱('Y'/'N'): ");
            cin>>again;
        }
        else if(cz=='O'){
            c_options();
            return 0;
        }
        else if(cz=='E'){
            FILE *fp;
            cout<<"Good bye"<<endl;
            return 0;
        }
        else if(cz=='W'){
            system("start http://oj.cqxiaomawang.com:8888/d/CQ02_23012/user/2534");
            return 0;
        }
        else{
            cout<<"Error!!!"<<endl;
            c_main_game();
            return 0;
        }

    }
    system("cls");
    printf("你总共逃脱了%d次!",wave);

    Sleep(5000);
    return 0;
}
int main(){
    choose_languagu();
    return 0; 
}