qqwq

· · 个人记录


// -std=c++14 -lgdi32 -lOpengl32

#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
#include <gl/gl.h>

using namespace std;
typedef long long ll;
typedef __int128 lll;

mt19937 rng(time(0));

int rnd(int p) {
    return int(rng()%p);
}
double rndf() {
    return double(rnd(10001)*0.0001);
}
double BackgroundRatio = 0.1;
double BoardRatio = 0.2;
int GridColor=0x888888, BufferColor=0x555555, ShadowColor=0x777777, RoundColor=0xAAAAAA, VanishColor=0x330066;
int SlotColor=0x555555, OverSlotColor=0x333333;
int StatColor=0x99FFFF, TextColor=0xDDDDDD;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;
    case WM_DESTROY:
        return 0;
    case WM_KEYDOWN:
        switch (wParam) {
        /*case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;*/
        }
        return 0;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}
void EnableOpenGL(HWND hWnd, HDC *hDC, HGLRC *hRC) {
    PIXELFORMATDESCRIPTOR pfd; int iFormat;
    *hDC = GetDC(hWnd);
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat(*hDC, &pfd);
    SetPixelFormat(*hDC, iFormat, &pfd);
    *hRC = wglCreateContext(*hDC);
    wglMakeCurrent(*hDC, *hRC);
}
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC) {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
    ReleaseDC(hWnd, hDC);
}
int Mix(int ca, int cb, double rt) {
    int Ar = (ca>>16);
    int Ag = ((ca>>8)&((1<<8)-1));
    int Ab = (ca&((1<<8)-1));
    int Br = (cb>>16);
    int Bg = ((cb>>8)&((1<<8)-1));
    int Bb = (cb&((1<<8)-1));
    int R = int(floor(rt*double(Ar)+(1.0-rt)*double(Br)));
    int G = int(floor(rt*double(Ag)+(1.0-rt)*double(Bg)));
    int B = int(floor(rt*double(Ab)+(1.0-rt)*double(Bb)));
    return (max(0,min(255,R))<<16)+(max(0,min(255,G))<<8)+max(0,min(255,B));
}
int PS = 800;
struct ClassPiece {
    int B[10][10], LX, LY, clr, SDel, FstX, FstY;
    ClassPiece() {
        LX=LY=clr=SDel=0; FstX=FstY=-1;
        for (int i=0; i<=9; ++i) {
            for (int j=0; j<=9; ++j) B[i][j]=0;
        }
    }
    ClassPiece(int _LX, int _LY, int _clr, int _SDel, vector<vector<int> > _B) {
        LX=_LX; LY=_LY; clr=_clr; SDel=_SDel; FstX=FstY=-1;
        for (int i=0; i<=9; ++i) {
            for (int j=0; j<=9; ++j) B[i][j]=0;
        }
        for (int i=0; i<_LX; ++i) {
            for (int j=0; j<_LY; ++j) {
                B[i][j] = _B[_LX-i-1][j];
                if ((B[i][j])&&(FstX<0)) {
                    FstX=i; FstY=j;
                }
            }
        }
    }
} Piece[155][4];
vector<pair<int,int> > Kick[155][4][4];
bool Focus = false;
int SelX=0, SelY=0;
bool LButtonCD = false;
bool CheckKey(char ch) {
    if (!Focus) return false;
    if (ch==VK_LBUTTON) {
        if (!(GetAsyncKeyState(ch)&0x8000)) LButtonCD=false;
        if (LButtonCD) return false;
    }
    return bool(GetAsyncKeyState(ch)&0x8000);
}
struct Particle {
    double x, y, vx, vy, ax, ay, sz, de, th; int n, clr;
};
struct FloatText {
    double x, y, sz, bd, de; string str; int clr;
};
struct ClassSta {
    int p, d, x, y;
    bool operator <(ClassSta b) const {
        if (p!=b.p) return p<b.p;
        if (d!=b.d) return d<b.d;
        if (x!=b.x) return x<b.x;
        return y<b.y;
    }
};
#warning char
vector<string> Char[999]; string LCW[999], ATKN[999];
char PName[155] = {' ','I','J','L','O','S','T','Z','C','D','B','A','i','t','U','V','X','F','E','s','z','j','l','Y','R','H','N','Q','P','W'};
int Flip[155];
void InitChar() {
    LCW[1]="SINGLE"; LCW[2]="DOUBLE"; LCW[3]="TRIPLE"; LCW[4]="QUAD";
    LCW[5]="PENTA"; LCW[6]="HEXA"; LCW[7]="HEPTA"; LCW[8]="OCTA";
    LCW[9]="ENNEA"; LCW[10]="DECA"; LCW[11]="HENDECA"; LCW[12]="DODECA";
    LCW[13]="TRIADECA"; LCW[14]="TESSARADECA"; LCW[15]="PENTEDECA"; LCW[16]="HEXADECA";
    LCW[17]="HEPTADECA"; LCW[18]="OCTADECA"; LCW[19]="ENNEADECA"; LCW[20]="EICOSA";
    LCW[21]="ULTIMATRIS"; LCW[22]="KIRBTRIS"; LCW[23]="INFINITRIS"; LCW[24]="KAGARIS"; LCW[25]="ELECTRIS";
    for(int i=26; i<999; ++i) LCW[i]="PERFECTRIS";
    ATKN[1] = "Even";
    ATKN[2] = "KO\'s";
    ATKN[3] = "Random";
    ATKN[4] = "Payback";
    ATKN[5] = "Badges";
    ATKN[6] = "Attackers";
    Char['0'] = {"fbdj375zf","zj"};
    Char['1'] = {"kc6","48"};
    Char['2'] = {"fbdjo483"};
    Char['3'] = {"fbdjosy374","qs"};
    Char['4'] = {"7dckuy"};
    Char['5'] = {"eapmt374"};
    Char['6'] = {"jdbfz573ysp"};
    Char['7'] = {"aejr6"};
    Char['8'] = {"qsojdbfkquz573ys"};
    Char['9'] = {"tqkfbdj375z"};
    Char['A'] = {"4c8","vx"};
    Char['B'] = {"sojdapsy374p"};
    Char['C'] = {"jdbfz573"};
    Char['D'] = {"adj374a"};
    Char['E'] = {"ea48","pt"};
    Char['F'] = {"ea4","pt"};
    Char['G'] = {"jdbfz56ytr","y8"};
    Char['H'] = {"a4","e8","pt"};
    Char['I'] = {"ae","48","c6"};
    Char['J'] = {"de375z"};
    Char['K'] = {"a4","eq8","pq"};
    Char['L'] = {"a48"};
    Char['M'] = {"4are8"};
    Char['N'] = {"4a8e"};
    Char['O'] = {"fbdj375zf"};
    Char['P'] = {"4adjosp"};
    Char['Q'] = {"6yjdbfz56","w8"};
    Char['R'] = {"4adjosp","q8"};
    Char['S'] = {"jdbfkqsy375z"};
    Char['T'] = {"ae","c6"};
    Char['U'] = {"az573e"};
    Char['V'] = {"a6e"};
    Char['W'] = {"a5m7e"};
    Char['X'] = {"a8","4e"};
    Char['Y'] = {"6r","are"};
    Char['Z'] = {"ae48"};
    Char['a'] = {"y65zplnt8"};
    Char['b'] = {"a473tnk"};
    Char['c'] = {"tnlpz573"};
    Char['d'] = {"e85zplo"};
    Char['e'] = {"uxtnlpz58"};
    Char['f'] = {"edh;?","ko"};
    Char['g'] = {"85zplntBFD>","ot"};
    Char['h'] = {"a4","plms7"};
    Char['i'] = {"76rq","h"};
    Char['j'] = {"i","rs<@?9"};
    Char['k'] = {"a4","nu8"};
    Char['l'] = {"c67"};
    Char['m'] = {"4k","plr6","rnt8"};
    Char['n'] = {"4k","plms7"};
    Char['o'] = {"z573tnlpz"};
    Char['p'] = {"z573tnlp","kC"};
    Char['q'] = {"oG","tnlpz573"};
    Char['r'] = {"4k","plms"};
    Char['s'] = {"z573xvplnt"};
    Char['t'] = {"ko","c173"};
    Char['u'] = {"kz562","n78"};
    Char['v'] = {"k6o"};
    Char['w'] = {"kp5r7to"};
    Char['x'] = {"k8","o4"};
    Char['y'] = {"kz573","oBFD>"};
    Char['z'] = {"ko48"};
    Char['+'] = {"pt","h1"};
    Char['-'] = {"ps"};
    Char['*'] = {"ay","eu"};
    Char['/'] = {"e4"};
    Char['\\'] = {"a8"};
    Char[','] = {"y7"};
    Char['.'] = {"7"};
    Char['?'] = {"fbdjorw","6"};
    Char['!'] = {"cw","6"};
    Char[':'] = {"h","w"};
    Char['#'] = {"fj","uy","b4","e7"};
    Char['|'] = {"cm","r6"};
    Char['\''] = {"dm"};
    Char['\"'] = {"cl","en"};
    Char['~'] = {"plso"};
    Char['['] = {"ca46"};
    Char[']'] = {"ce86"};
    Char['<'] = {"jp3"};
    Char['>'] = {"ftz"};
    Char['%'] = {"abgfa","e4","23872"};
    Char['$'] = {"oigkqsy375z","c;"};
    Char['_'] = {"48"};
    Char['='] = {"ko","uy"};
    Char['{'] = {"dcglpv067"};
    Char['}'] = {"bcintx265"};
    Char['('] = {"dlv7"};
    Char[')'] = {"bnx5"};
    Char['^'] = {"lcn"};
    Char['@'] = {"smqwsxyjdbfz473"};
    Char[';'] = {"h","w15"};
    Char[0] = {"r"};
    Char[1] = {"ht1ph","mswqm","r"};
    Char[2] = {"hp1th","hm","pq","ts","1w","r"};
    /*
    a b c d e
    f g h i j
    k l m n o
    p q r s t
    u v w x y
    z 0 1 2 3
    4 5 6 7 8
    9 : ; < =
    > ? @ A B
    C D E F G
    */
}
int ERR=-998244353, ERR2=-998244352;
int _TIME=time(0), Plrs, PlrsCnt, RoundTot=0; char buf[9999];
int TarRem[111][111], ShiftCD[111];
int PaintLim = 10;
bool Con=false; string Command="", Respond; int RespondTime=0, RespondColor=0;
bool CheckBlockType(int tp) {
    if (tp>154) return false; 
    return ((!tp)||(Piece[tp][0].LX>0));
}
pair<int,int> Shift[155][4];
string BaseRule="default", SpinRule="allspin", B2BRule="surge", ComboRule="multipler", KickTable="extend", ACRule="extend";
string GarbageShape = "cheese";
string GarbageMode = "combo";
string GarbageCancel = "default"; 
string ClutchRule = "default";
string GarbageType = "layer";
string ClearGravity = "default"; 
string LevelRule = "default";
bool LqOS = false;
void InitKick() {
    for (int o=0; o<155; ++o) {
        for (int i=0; i<4; ++i) {
            Shift[o][i] = make_pair(0,0);
            for (int j=0; j<4; ++j) Kick[o][i][j]={{0,0}};
        }
    }
    if ((KickTable=="default")||(KickTable=="srsplus")||(KickTable=="extend")||(KickTable=="srs")) {
        if ((KickTable!="default")&&(KickTable!="extend")) {
            Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
            Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
            Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        }
        else {
            Shift[4][3]={+1,0}; Shift[4][2]={+1,-1}; Shift[4][1]={0,-1};
            Shift[11][3]={+1,0}; Shift[11][2]={+1,-1}; Shift[11][1]={0,-1};
            Shift[16][3]={+1,0}; Shift[16][2]={+1,-1}; Shift[16][1]={0,-1};
        }
        for (int i=0; i<4; ++i) {
            for (int j=0; j<4; ++j) {
                Kick[1][0][3]={{0,0},{-2,0},{+1,0},{-2,-1},{+1,+2}};
                Kick[1][3][0]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
                Kick[1][3][2]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
                Kick[1][2][3]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
                Kick[1][2][1]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
                Kick[1][1][2]={{0,0},{-2,0},{+1,0},{-2,-1},{+1,+2}};
                Kick[1][1][0]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
                Kick[1][0][1]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
                Kick[1][0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
                Kick[1][2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
                Kick[1][1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
                Kick[1][3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};
                for (int o=2; o<155; ++o) {
                    Kick[o][0][3]={{0,0},{-1,0},{-1,+1},{0,-2},{-1,-2}};
                    Kick[o][3][0]={{0,0},{+1,0},{+1,-1},{0,+2},{+1,+2}};
                    Kick[o][3][2]={{0,0},{+1,0},{+1,-1},{0,+2},{+1,+2}};
                    Kick[o][2][3]={{0,0},{-1,0},{-1,+1},{0,-2},{-1,-2}};
                    Kick[o][2][1]={{0,0},{+1,0},{+1,+1},{0,-2},{+1,-2}};
                    Kick[o][1][2]={{0,0},{-1,0},{-1,-1},{0,+2},{-1,+2}};
                    Kick[o][1][0]={{0,0},{-1,0},{-1,-1},{0,+2},{-1,+2}};
                    Kick[o][0][1]={{0,0},{+1,0},{+1,+1},{0,-2},{+1,-2}};
                    Kick[o][0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
                    Kick[o][2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
                    Kick[o][1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
                    Kick[o][3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};
                }
            }
        }
        if (KickTable!="srs") {
            /*Kick[1][0][3]={{0,0},{-2,0},{+1,0},{+1,+2},{-2,-1}};
            Kick[1][3][0]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
            Kick[1][3][2]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
            Kick[1][2][3]={{0,0},{-2,0},{+1,0},{-2,+1},{+1,-1}};
            Kick[1][2][1]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-1}};
            Kick[1][1][2]={{0,0},{+1,0},{-2,0},{+1,+2},{-2,-1}};
            Kick[1][1][0]={{0,0},{-2,0},{+1,0},{-2,+1},{+1,-2}};
            Kick[1][0][1]={{0,0},{+2,0},{-1,0},{-1,+2},{+2,-1}};
            Kick[1][0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
            Kick[1][2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
            Kick[1][1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
            Kick[1][3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};*/
            Kick[1][0][3]={{0,0},{+1,0},{-2,0},{-2,-1},{+1,+2}};
            Kick[1][3][0]={{0,0},{-1,0},{+2,0},{-1,-2},{+2,+1}};
            Kick[1][3][2]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
            Kick[1][2][3]={{0,0},{-2,0},{+1,0},{-2,+1},{+1,-2}};
            Kick[1][2][1]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
            Kick[1][1][2]={{0,0},{+1,0},{-2,0},{+1,+2},{-2,-1}};
            Kick[1][1][0]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
            Kick[1][0][1]={{0,0},{-1,0},{+2,0},{+2,-1},{-1,+2}};
            Kick[1][0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
            Kick[1][2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
            Kick[1][1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
            Kick[1][3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};
        }
        if ((KickTable=="default")||(KickTable=="extend")) {
            vector<pair<int,int> > CCW={{0,0},{0,-1},{1,0},{1,-1},{0,-2},{1,-2},{2,0},{2,-1},{2,-2},{-1,0},{-1,-1},{0,1},{1,1},{2,1},{-1,-2},{-2,0},{0,2},{1,2},{2,2},{-2,-1},{-2,-2},{-1,1},{-1,2},{-2,1},{-2,2}}, CW, FLIP, RFLIP;
            for (pair<int,int> p : CCW) CW.push_back(make_pair(-p.first,p.second));
            for (int i=0; i<CW.size(); ++i) {
                bool ok = true;
                for (int j=0; j<FLIP.size(); ++j) {
                    if (FLIP[j]==CCW[i]) ok=false;
                }
                if (ok) FLIP.push_back(CCW[i]);
                ok = true;
                for (int j=0; j<FLIP.size(); ++j) {
                    if (FLIP[j]==CW[i]) ok=false;
                }
                if (ok) FLIP.push_back(CW[i]);
            }
            for (pair<int,int> p : FLIP) RFLIP.push_back(make_pair(-p.first,p.second));
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) {
                    for (int o=12; o<155; ++o) {
                        if (j==((i+1)&3)) Kick[o][i][j]=CCW;
                        if (j==((i+2)&3)) Kick[o][i][j]=(i<2)?FLIP:RFLIP;
                        if (j==((i+3)&3)) Kick[o][i][j]=CW;
                    }
                }
            }
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) {
                    for (int o=1; o<11; ++o) {
                        vector<pair<int,int> > NK;
                        if (j==((i+1)&3)) NK=CCW;
                        if (j==((i+2)&3)) {
                            NK=(i<2)?FLIP:RFLIP; if (KickTable=="extend") Kick[o][i][j].clear();
                        }
                        if (j==((i+3)&3)) NK=CW;
                        for (pair<int,int> gg : NK) {
                            bool ok = true;
                            for (pair<int,int> hh : Kick[o][i][j]) {
                                if (gg==hh) ok=false;
                            }
                            if (ok) Kick[o][i][j].push_back(gg);
                        }
                    }
                }
            }
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) Kick[4][i][j]=Kick[1][i][j];
            }
        }
        if (KickTable=="srs") {
            for (int o=0; o<155; ++o) {
                for (int i=0; i<4; ++i) {
                    int j = (i==3)?0:i+1;
                    int k = (j==3)?0:j+1;
                    for (int d=0; d<Kick[o][i][k].size(); ++d) Kick[o][i][k][d]=make_pair(Kick[o][i][j][d].first+Kick[o][j][k][d].first,Kick[o][i][j][d].second+Kick[o][j][k][d].second);
                }
            }
        }
    }
    if ((KickTable=="asc")||(KickTable=="ascplus")) {
        vector<pair<int,int> > CCW={{0,0},{1,0},{0,-1},{1,-1},{0,-2},{1,-2},{2,0},{2,-1},{2,-2},{-1,0},{-1,-1},{0,1},{1,1},{2,1},{-1,-2},{-2,0},{0,2},{1,2},{2,2},{-2,-1},{-2,-2},{-1,1}}, CW, FLIP, RFLIP;
        if (KickTable=="asc") {
            Shift[1][1]={+1,0}; Shift[1][2]={+1,+1}; Shift[1][3]={0,+1};
        }
        else {
            Shift[4][3]={+1,0}; Shift[4][2]={+1,-1}; Shift[4][1]={0,-1};
            Shift[11][3]={+1,0}; Shift[11][2]={+1,-1}; Shift[11][1]={0,-1};
            Shift[16][3]={+1,0}; Shift[16][2]={+1,-1}; Shift[16][1]={0,-1};
            CCW = {{0,0},{0,-1},{1,0},{1,-1},{0,-2},{1,-2},{2,0},{2,-1},{2,-2},{-1,0},{-1,-1},{0,1},{1,1},{2,1},{-1,-2},{-2,0},{0,2},{1,2},{2,2},{-2,-1},{-2,-2},{-1,1},{-1,2},{-2,1},{-2,2}};
        }
        for (pair<int,int>p : CCW) CW.push_back(make_pair(-p.first,p.second));
        for (int i=0; i<CW.size(); ++i) {
            bool ok = true;
            for (int j=0; j<FLIP.size(); ++j) {
                if (FLIP[j]==CCW[i]) ok=false;
            }
            if (ok) FLIP.push_back(CCW[i]);
            ok = true;
            for (int j=0; j<FLIP.size(); ++j) {
                if (FLIP[j]==CW[i]) ok=false;
            }
            if (ok) FLIP.push_back(CW[i]);
        }
        for (pair<int,int> p : FLIP) RFLIP.push_back(make_pair(-p.first,p.second));
        for (int i=0; i<4; ++i) {
            for (int j=0; j<4; ++j) {
                for (int o=1; o<155; ++o) {
                    if (j==((i+1)&3)) Kick[o][i][j]=CCW;
                    if (j==((i+2)&3)) Kick[o][i][j]=(i<2)?FLIP:RFLIP;
                    if (j==((i+3)&3)) Kick[o][i][j]=CW;
                }
            }
        }
    }
    if (KickTable=="ors") {
        Shift[1][1]={+1,0}; Shift[1][2]={0,+1};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][0]={0,-1}; Shift[5][1]={+1,0};
        Shift[7][0]={0,-1}; Shift[7][1]={+1,0};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
    }
    if (KickTable=="rnrs") {
        Shift[1][1]={+1,0}; Shift[1][0]={0,-1};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][0]={0,-1}; Shift[5][1]={+1,0};
        Shift[7][0]={0,-1}; Shift[7][1]={+1,0};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
    }
    if (KickTable=="lnrs") {
        Shift[1][1]={+1,0}; Shift[1][0]={0,-1};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][0]={0,-1}; Shift[5][3]={-1,0};
        Shift[7][0]={0,-1}; Shift[7][3]={-1,0};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
    }
    if (KickTable=="ars") {
        Shift[1][1]={+1,0}; Shift[1][2]={0,+1};
        Shift[2][0]=Shift[3][0]={0,-1};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][0]={0,-1}; Shift[5][1]={+1,0};
        Shift[6][0] = {0,-1};
        Shift[7][0]={0,-1}; Shift[7][3]={-1,0};
        Shift[10][0] ={0,-1};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[14][1]=Shift[14][2]=Shift[14][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        Shift[21][1]=Shift[21][3]={0,+1};
        Shift[22][1]=Shift[22][3]={0,+1};
        Shift[23][1]=Shift[23][3]={0,+1};
        Shift[24][1]=Shift[24][3]={0,+1};
        Shift[25][1]=Shift[25][3]={0,+1};
        Shift[26][1]=Shift[26][3]={0,+1};
        Shift[27][1]=Shift[27][2]=Shift[27][3]={0,+1};
        Shift[28][1]=Shift[28][2]=Shift[28][3]={0,+1};
        for (int o=0; o<155; ++o) {
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) Kick[o][i][j]={{0,0},{+1,0},{-1,0}};
            }
        }
        for (int i=0; i<4; ++i) {
            for (int j=0; j<4; ++j) {
                if ((i&1)&&(!(j&1))) {
                    Kick[1][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                    Kick[12][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                    Kick[21][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                    Kick[22][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                    Kick[23][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                    Kick[24][i][j] = {{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
                }
                if ((!(i&1))&&(j&1)) {
                    Kick[1][i][j].push_back({0,+1}); Kick[1][i][j].push_back({0,+2});
                    Kick[12][i][j].push_back({0,+1}); Kick[12][i][j].push_back({0,+2});
                    Kick[21][i][j].push_back({0,+1}); Kick[21][i][j].push_back({0,+2});
                    Kick[22][i][j].push_back({0,+1}); Kick[22][i][j].push_back({0,+2});
                    Kick[23][i][j].push_back({0,+1}); Kick[23][i][j].push_back({0,+2});
                    Kick[24][i][j].push_back({0,+1}); Kick[24][i][j].push_back({0,+2});
                    Kick[25][i][j].push_back({0,+1}); Kick[25][i][j].push_back({0,+2});
                    Kick[26][i][j].push_back({0,+1}); Kick[26][i][j].push_back({0,+2});
                }
                if (!j) {
                    Kick[6][i][j].push_back({0,+1}); Kick[13][i][j].push_back({0,+1});
                }
            }
        }
    }
    if (KickTable=="c2") {
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        for (int o=0; o<155; ++o) {
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) Kick[o][i][j]={{0,0},{-1,0},{+1,0},{0,-1},{-1,-1},{+1,-1},{-2,0},{+2,0}};
            }
        }
    }
    if (KickTable=="new") {
        Shift[1][0]={0,-1}; Shift[1][3]={-1,0}; 
        Shift[2][2]={0,+1}; Shift[2][1]={+1,0};
        Shift[3][2]={0,+1}; Shift[3][3]={-1,0};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][2]={0,+1}; Shift[5][1]={+1,0};
        Shift[7][2]={0,+1}; Shift[7][3]={-1,0};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        for (int o=0; o<155; ++o) {
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) {
                    if (j==((i+1)&3)) Kick[o][i][j]={{0,0},{-1,0},{0,-1},{+1,0},{0,+1}};
                    if (j==((i+3)&3)) Kick[o][i][j]={{0,0},{+1,0},{0,-1},{-1,0},{0,+1}};
                }
            }
        }
    }
    if (KickTable=="atari") {
        Shift[1][0]={0,+1}; Shift[1][2]={0,+2}; Shift[1][3]={-1,0}; 
        Shift[2][2]={0,+1}; Shift[2][3]={-1,0};
        Shift[3][2]={0,+1}; Shift[3][3]={-1,0};
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[5][2]={0,+1}; Shift[5][3]={-1,0};
        Shift[6][2]={0,+1}; Shift[6][3]={-1,0};
        Shift[7][2]={0,+1}; Shift[7][3]={-1,0};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        for (int o=0; o<155; ++o) {
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) Kick[o][i][j]={{0,0},{-1,0}};
            }
        }
    }
    if (KickTable=="tetrax") {
        Shift[4][1]={+1,0}; Shift[4][2]={+1,+1}; Shift[4][3]={0,+1};
        Shift[11][1]={+1,0}; Shift[11][2]={+1,+1}; Shift[11][3]={0,+1};
        Shift[16][1]={+1,0}; Shift[16][2]={+1,+1}; Shift[16][3]={0,+1};
        for (int o=0; o<155; ++o) {
            for (int i=0; i<4; ++i) {
                for (int j=0; j<4; ++j) {
                    if (((i+2)&3)==j) {
                        if (o!=1) Kick[o][i][j]={{0,0},{0,+1},{0,-1},{-1,0},{+1,0}};
                        else Kick[o][i][j]={{0,0},{0,-1},{0,+1}};
                    }
                    else if (i!=j) {
                        if (((i+3)&3)==j) Kick[o][i][j]={{0,0},{0,+1},{-1,0},{+1,0},{-1,+1},{+1,+1},{0,-1},{-1,-1},{+1,-1}};
                        else Kick[o][i][j]={{0,0},{0,+1},{+1,0},{-1,0},{+1,+1},{-1,+1},{0,-1},{+1,-1},{-1,-1}};
                    }
                }
            }
        }
        Kick[1][0][3] = {{0,0},{0,-1},{0,-2},{0,+1},{+1,-1},{-1,-1},{+1,-2},{-1,-2}};
        Kick[1][3][0]=Kick[1][3][2]={{0,0},{0,-1},{0,-2},{0,+1},{-1,0},{+1,0},{+2,0}};
        Kick[1][2][3] = {{0,0},{0,+1},{0,+2},{0,-1},{-1,+1},{+1,+1},{-1,+2},{+1,+2}};
        Kick[1][2][1] = {{0,0},{0,+1},{0,+2},{0,-1},{+1,+1},{-1,+1},{+1,+2},{-1,+2}};
        Kick[1][1][2]=Kick[1][1][0]={{0,0},{0,-1},{0,-2},{0,-1},{+1,0},{-1,0},{-2,0}};
        Kick[1][0][1] = {{0,0},{0,-1},{0,-2},{0,+1},{-1,-1},{+1,-1},{-1,-2},{+1,-2}};
    }
    if (KickTable=="none") {
        Shift[4][3]={+1,0}; Shift[4][2]={+1,-1}; Shift[4][1]={0,-1};
    }
    for (int o=0; o<155; ++o) {
        for (int i=0; i<4; ++i) {
            for (int j=0; j<4; ++j) {
                for (int d=0; d<Kick[o][i][j].size(); ++d) {
                    Kick[o][i][j][d].first += Shift[o][j].first-Shift[o][i].first;
                    Kick[o][i][j][d].second += Shift[o][j].second-Shift[o][i].second;
                }
            }
        }
    }
}
char AskKey(string str) {
    if (str.empty()) return 0;
    if (str.size()==1) {
        char ch = str[0];
        if ((ch>='a')&&(ch<='z')) return ch+'A'-'a';
        if ((ch>='0')&&(ch<='9')) return ch;
        return 0;
    }
    if (str=="up") return VK_UP;
    if (str=="down") return VK_DOWN;
    if (str=="left") return VK_LEFT;
    if (str=="right") return VK_RIGHT;
    if (str=="shift") return VK_SHIFT;
    if (str=="space") return VK_SPACE;
    if (str=="tab") return VK_TAB;
    if (str=="enter") return VK_RETURN;
    //if (str=="esc") return VK_ESCAPE;
    if (str=="caps") return VK_CAPITAL;
    if (str=="ctrl") return VK_CONTROL;
    if (str=="none") return VK_F24;
    return 0;
}
string IToS(int x) {
    if (!x) return "0";
    string res = "";
    while (x) {
        res=char(x%10+'0')+res; x/=10;
    }
    return res;
}
int SToI(string s) {
    if (s=="max") return 99999999;
    if (s.size()>8) return ERR;
    int res = 0;
    for (char ch : s) {
        if ((ch<'0')||(ch>'9')) return ERR;
        res = res*10+int(ch-'0');
    }
    return res;
}
struct ClassAtkEff {
    double x, y, th, dir; int tar, clr, sz;
};
vector<ClassAtkEff> AtkEff;
string ForceExecute = "";
int Obs = -1;
bool ForceRound, ForceAbort; int sortval[999];
bool QuickPlay = false;
bool Odoo = false;
int ConstE = 0;
bool Arcade=false, ArcadeRound=false;
bool ObserveAI = true;
string TargetBonus = "default";
string BadgeBonus = "default";
bool DisAtk = true;
string GarbageBonus="default", OpenerBonus="default", Style="default", DefaultRot="ccw";
int _InnerMess=0, _SegMess=100, _Luck=0;
int BegDelay=3000; bool Zen=false, Storage=false, Undo=false;
vector<int> DefaultBag = {1,2,3,4,5,6,7};
vector<pair<int,int> > DDP[155][4]; int UseAI=0;
vector<ll> Floor =
{0, 50, 150, 300, 450, 650, 850, 1100, 1350, 1650,
2000, 2400, 2950, 3500, 4000, 4500, 5000, 5500, 6000, 6500,
7000, 7500, 8000, 8500, 9000, 9500, 10000, 11000, 12000, 15000};
vector<int> DecDis = {5000,4800,3900,2100,1400,1300,900,600,400,300,200,180,160,140,120,100,90,80,70,60,55,50,45,40,35,30,25,20,15,10,5,0};
vector<int> ComboBase = {2440,1120,400,60,-160,-330,-470,-600,-710,-830,-940,-1050,-1160,-1260};
vector<int> ComboBonus = {1220,610,300,180,120,90,70,50,40,30,30,20}; 
vector<int> GradeDec = {125,80,80,50,45,45,45,40,40,40,40,40,30,30,30,20,20,20,20,20,15,15,15,15,15,15,15,15,15,15,10};
vector<int> ArcadeAre = {25,25,25,25,25,25,25,16,12,12,6,5,4};
vector<int> ArcadeLcd = {40,40,40,40,40,25,16,12,6};
vector<int> ArcadeLock = {30,30,30,30,30,30,30,30,30,17,17,15};
vector<int> CoolTm = {52,52,49,45,45,42,42,38,38,-1};
vector<int> RegretTm = {90,75,75,68,60,60,50,50,50,50,99999};
vector<pair<int,int> > ArcadeGrav = {{0,4},{30,6},{35,8},{40,10},{50,12},{60,16},{70,32},{80,48},{90,64},{100,80},{120,96},{140,112},{160,128},{170,144},
{200,4},{220,32},{230,64},{233,96},{236,128},{239,160},{243,192},{247,224},{251,256},{300,512},{330,768},{360,1024},{400,1280},{420,1024},{450,768},{500,5120}};
vector<int> GradeBonus[5], ComboMul[5];
vector<int> SegGrade = {0,1,2,3,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,11,12,12,12,13,13,14,14,15,15,16,16,17};
vector<string> GradeName = {"9","8","7","6","5","4","3","2","1","S1","S2","S3","S4","S5","S6","S7","S8","S9","m1","m2","m3","m4","m5","m6","m7","m8","m9","M","MK","MV","MO","MM","GM"};
int DX0 = 0;
int AddTp = 1;
bool RDown = false;
bool _fstl = true;
double MX[111], MY[111];
int HoleEval[111];
queue<ll> FP;
vector<lll> ClearTemplate; int TemplatePos=0;
char KEY_LEFT = VK_LEFT;
char KEY_RIGHT = VK_RIGHT;
char KEY_DOWN = VK_DOWN;
char KEY_UP = 'W';
char KEY_CW = 'X';
char KEY_CCW = 'Z';
char KEY_180 = 'A';
char KEY_HARD = ' ';
char KEY_HOLD = 'C';
char KEY_ROT = VK_UP;
char KEY_EVEN = '1';
char KEY_KO = '2';
char KEY_RANDOM = '3';
char KEY_PAYBACK = '4';
char KEY_BADGE = '5';
char KEY_ATTACKERS = '6';
char KEY_UNDO = 'P';
char KEY_RETRY = 'U';
char KEY_RESET = 'E';
char KEY_SONIC = 'S';
char KEY_WASTE = 'T';
char KEY_FLIP = 'Q';
char KEY_LOCK = 'R';
int RotType = 3;
//int DAS=60, ARR=0, SDDAS=0, SDARR=0;
int DAS=167, ARR=33, SDDAS=300, SDARR=20;
int DCD=0, HCD=100;
bool DropEff=true, RotEff=false;
bool MoveEff=true, SpinEff=true;
struct Board {
    int HoldRule=1, Sequence=1, DivOperTime=0, UndoCD=0;
    int ModHold=0, ModMess=0, ModGravity=0, ModStrength=0, ModDivergence=0, ModInvisible=0, ModSpin=0, ModExpert=0;
    int Plr, Tar=-1; bool Over=false, InChain=false; int ChainLine=0;
    int B[111][55], C[111][55], ID[111][55], LE[111][55], PrePos[111][55], LX, LY, DX;
    int PartID = 0;
    int Hold, HoldEnable, InitFacing=0;
    int DropL=800, LockL=500, ResetLim=15, ARE=0, LCD=0, DeathARE=500, AreLeft=0;
    int GLockL=99999999, FLockL=99999999, GTime=0, FTime=0;
    int DcdLeft=0, HcdLeft=0, DrdLeft=0, VisTm=0;
    int BaseDropL=800, BaseLockL=500;
    int InitHold=0, InitRot=0;
    int GarbageGap=8, DXDel=0;
    int DRD = 0;
    int GarbDelay=500, GarbRise=0, Stock=0, Life=0;
    deque<int> Next; vector<Particle> PQu; vector<FloatText> TQu; 
    deque<pair<int,pair<lll,ll> > > Rec; queue<pair<int,int> > Atk;
    deque<pair<int,lll> > ActiveGarb;
    deque<pair<int,lll> > AllSpinGarb;
    vector<lll> ClearShape;
    int EV[8], ED[8];
    bool UseRotEff = false;
    bool AllSpinGarbOper = false;
    double KX, KY, sz=1.0; int Pid, Dir, LstReady=999, ViewNxt=5;
    double DropKX=0.0, DropKY=0.0, Rot=0.0, DropRot=0.0;
    int RoundHeight=0, VanishHeight=99999999;
    int StaticHeight=0, StartHeight=0;
    int AtkType = 1;
    int DropTime, ResetRem; bool Bot=false;
    int LastGarb=9999999, Combo, B2B, ComboRem=0;
    int ComboCol[55];
    double ShiftX, ShiftY; mt19937 gen;
    vector<char> KeyList = {0,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_CW,KEY_CCW,KEY_180,KEY_HARD,KEY_HOLD,
    KEY_ROT,KEY_EVEN,KEY_KO,KEY_RANDOM,KEY_PAYBACK,KEY_BADGE,KEY_ATTACKERS,KEY_UNDO,KEY_LOCK,KEY_RETRY,KEY_RESET,KEY_SONIC,KEY_WASTE,KEY_FLIP,KEY_UP};
    vector<char> DasKey = {KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_UP,KEY_SONIC};
    int KeySta[256], KeyTime[256], Key; bool KeyDas[256], UseDas[256];
    double avx=0.0, avy=0.0; ll begtm = clock();
    double savx=-100.0, savy=-100.0, tavx=-100.0, tavy=-100.0;
    int OperDis, OperTime=0; bool MiniSpin=false; pair<int,int> LstAct=make_pair(-1,-1); 
    int SumPiece=0, SumLine=0, SumAttack=0, SumDig=0, KO=0, SKO=0; ll Score=0LL, DisScore=0LL;
    int ClearType=0, ClearWType=0, ClearTm=0, ClearColor=0, SpinType=0, SpinFull=0, SpinTm=0, SpinDis=0;
    int ComboType=0, ComboTm=0, B2BType=0, B2BTm=0, Wins=0, PCTime=0;
    int VSRnk=0, GarbagePreview=10, OpenerPhrase=14;
    double SKX, SKY, Ssz, isz; int LstAtk=-1; bool BeFrom=false, BeTo=false, ShowShadow=true, Flipped=false;
    bool AllowMove=true, AllowRot=true, Allow2Rot=true, AllowHalf=true, AllowHard=true, AllowSoft=true, AllowSonic=true;
    bool AllowFlip=false, AllowUp=false, AllowLock=false, AllowDeep=false; int WasteLim=0, WasteRem=0;
    bool ForceOver=0, ForceLock=0; int ForceWaste=0;
    int Level=0, SumCool=0, SumRegret=0, CurSeg=0, Seg70=0, Seg100=0, SegSta[12];
    int Acc=0, AccRnk=0, AccProtect=0, CurFloor=0;
    int AggTm=0, AggDec=0, LstHole=0, FloorTm=0, RecIncTm=0;
    int Grade=0, GradeRnk=0, GradeDecTm=0, ArcadeInvis=0, InvisGrade=0, InvisTm=0;
    int His=4, Rol=6, Ext=0, BagSz=0; deque<int> HisSeq;
    bool Complete = false;
    int TarPiece=0, TarLine=0, TarAttack=0, TarTime=0, TarScore=0, Passthrough=0;
    int EcCD=0, BnCD=0, ScTm=0, OgTm=0; queue<ll> Bl; deque<pair<ll,int> > Cy;
    int LevBase=0, LevStart=0, LevLine=0, LevTime=0, LevPiece=0, LevAttack=0, LstLev=0;
    int LevLineInc=0, LevTimeInc=0, LevPieceInc=0, LevAttackInc=0;
    int MasterBeg=18, Diff=7;
    double RotEffVal=0.0; int LqC=0;
    vector<int> Bag = {};
    Board() {
    }
    Board(int _Plr, int _LX, int _LY, int _DX, double _KX, double _KY, bool _Bot=false, int _OperTime=0) {
        Plr=_Plr; begtm=clock();
        LX=_LX; LY=_LY; DX=_DX;
        KX=SKX=_KX; KY=SKY=_KY; Bot=_Bot; OperTime=_OperTime;
        for (int i=0; i<111; ++i) {
            for (int j=0; j<55; ++j) B[i][j]=C[i][j]=0;
        }
        for (int i=0; i<256; ++i) {
            KeySta[i]=KeyTime[i]=0; KeyDas[i]=UseDas[i]=false;
        }
        for (int i : DasKey) UseDas[i]=true;
        Next.clear();
        Hold=DropTime=0; HoldEnable=1; ResetRem=max(1,ResetLim);
        double tmp = min(300.0/double(10),600.0/double(22))*0.7;
        isz=sz=Ssz=min(300.0/double(LY),600.0/double(DX))*0.7/tmp*20.0;
        SumPiece=SumLine=SumAttack=0;
        ShiftX=ShiftY=0.0; gen=mt19937(_TIME);
        if (QuickPlay) ++_TIME;
    }
    void ReloadKey() {
        for (int i=0; i<256; ++i) {
            KeySta[i]=KeyTime[i]=0; KeyDas[i]=UseDas[i]=false;
        }
        KeyList = {0,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_CW,KEY_CCW,KEY_180,KEY_HARD,KEY_HOLD,
        KEY_ROT,KEY_EVEN,KEY_KO,KEY_RANDOM,KEY_PAYBACK,KEY_BADGE,KEY_ATTACKERS,KEY_UNDO,KEY_LOCK,KEY_RETRY,KEY_RESET,KEY_SONIC,KEY_WASTE,KEY_FLIP,KEY_UP};
        DasKey = {KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_UP,KEY_SONIC};
        for (int i : DasKey) UseDas[i]=true;
    }
    void Plot(double x, double y, int clr) {
        int _clr=clr; clr=abs(clr);
        if ((fabs(RotEffVal)>=0.001)&&(UseRotEff)&&(savx>=-99.0)) {
            double mx=sz*double(double(DX)-savx), my=sz*double(savy), len=sqrt((x-mx)*(x-mx)+(y-my)*(y-my));
            if ((len>=0.001)&&(abs(RotEffVal)>=0.001)&&(sz>=10.0)) {
                double theta = atan2(y-my,x-mx);
                x=mx+cos(theta+RotEffVal)*len; y=my+sin(theta+RotEffVal)*len;
            }
        }
        if (fabs(Rot)>=0.001) {
            double mx=sz*double(DX)*0.5, my=sz*double(LY)*0.5, len=sqrt((x-mx)*(x-mx)+(y-my)*(y-my));
            if ((len>=0.001)&&(abs(Rot)>=0.001)&&(sz>=10.0)) {
                double theta = atan2(y-my,x-mx);
                x=mx+cos(theta+Rot)*len; y=my+sin(theta+Rot)*len;
            }
        }
        x+=KX; y+=KY;
        int B=clr&255; clr>>=8;
        int G=clr&255; clr>>=8;
        int R = clr&255;
        double px = 1.0-x/double(PS);
        double py = y/double(PS);
        px = px*1.6-0.8;
        py = py*1.6-0.8;
        glColor3f(min(1.0,max(0.0,double(R)/255.0)), min(1.0,max(0.0,double(G)/255.0)), min(1.0,max(0.0,double(B)/255.0)));
        glVertex2f(py*2.0/3.0-1.0/3.0, px);
    }
    void Poly(double x, double y, double r, int n, int clr, double th=0.0) {
        glBegin(GL_POLYGON);
        for (int i=0; i<n; ++i) {
            Plot(x-r*cos(th), y+r*sin(th), clr);
            th += 2.0*acos(-1.0)/double(n);
        }
        glEnd();
    }
    void Square(double x, double y, double d, int clr) {
        glBegin(GL_POLYGON);
        Plot(x, y, clr);
        Plot(x+d, y, clr);
        Plot(x+d, y+d, clr);
        Plot(x, y+d, clr);
        glEnd();
    }
    void Rectangle(double x, double y, double dx, double dy, int clr) {
        glBegin(GL_POLYGON);
        Plot(x, y, clr);
        Plot(x+dx, y, clr);
        Plot(x+dx, y+dy, clr);
        Plot(x, y+dy, clr);
        glEnd();
    }
    void PaintChar(int ch, double x, double y, double sz, int clr, double bd=0.15, double th=0.0, double sc=0.0) {
        ch%=256; if (ch<0) ch+=256;
        bd*=sz; sz/=6.0;
        double mx=x+sz*3, my=y+sz*2.5;
        for (string str : Char[ch]) {
            if (str.size()==1) {
                int val = ((str[0]>='a')&&(str[0]<='z'))?str[0]-'a':26+str[0]-'0';
                double sx=x+sz*double(val/5), sy=y+sz*double(val%5);
                if ((th)||(sc)) {
                    double dis = sqrt((sx-mx)*(sx-mx)+(sy-my)*(sy-my));
                    dis = dis*(1.0+sc);
                    if (dis>0.01) {
                        double tt = atan2(sy-my,sx-mx);
                        sx=mx+dis*cos(tt+th); sy=my+dis*sin(tt+th);
                    }
                }
                double dx=bd*0.5, dy=bd*0.5;
                glBegin(GL_POLYGON);
                Plot(sx+dx, sy+dy, clr);
                Plot(sx+dx, sy-dy, clr);
                Plot(sx-dx, sy-dy, clr);
                Plot(sx-dx, sy+dy, clr);
                glEnd();
                continue;
            }
            for (int i=1; i<str.size(); ++i) {
                int val = ((str[i-1]>='a')&&(str[i-1]<='z'))?str[i-1]-'a':26+str[i-1]-'0';
                double sx=x+sz*double(val/5), sy=y+sz*double(val%5);
                val = ((str[i]>='a')&&(str[i]<='z'))?str[i]-'a':26+str[i]-'0';
                double ex=x+sz*double(val/5), ey=y+sz*double(val%5);
                if ((th)||(sc)) {
                    double dis = sqrt((sx-mx)*(sx-mx)+(sy-my)*(sy-my));
                    dis = dis*(1.0+sc);
                    if (dis>0.01) {
                        double tt = atan2(sy-my,sx-mx);
                        sx=mx+dis*cos(tt+th); sy=my+dis*sin(tt+th);
                    }
                    swap(sx,ex); swap(sy,ey);
                    dis = sqrt((sx-mx)*(sx-mx)+(sy-my)*(sy-my));
                    dis = dis*(1.0+sc);
                    if (dis>0.01) {
                        double tt = atan2(sy-my,sx-mx);
                        sx=mx+dis*cos(tt+th); sy=my+dis*sin(tt+th);
                    }
                    swap(sx,ex); swap(sy,ey);
                }
                double dx=ex-sx, dy=ey-sy, len=sqrt(dx*dx+dy*dy);
                double rat = bd/len*0.2;
                sx-=rat*dx; sy-=rat*dy;
                ex+=rat*dx; ey+=rat*dy;
                dx=sy-ey; dy=ex-sx;
                rat = 0.5*bd/sqrt((sx-ex)*(sx-ex)+(sy-ey)*(sy-ey));
                dx*=rat; dy*=rat;
                glBegin(GL_POLYGON);
                Plot(sx+dx, sy+dy, clr);
                Plot(ex+dx, ey+dy, clr);
                Plot(ex-dx, ey-dy, clr);
                Plot(sx-dx, sy-dy, clr);
                glEnd();
            }
        }
    }
    void PaintStrL(string str, double x, double y, double sz, int clr, double bd=0.15, double dis=1.0) {
        dis *= sz;
        for (char ch : str) {
            PaintChar(int(ch), x, y, sz, clr, bd);
            y += dis;
        }
    }
    void PaintStrR(string str, double x, double y, double sz, int clr, double bd=0.15, double dis=1.0, bool sp=false, double th=0.0, double sc=0.0) {
        if (sp) {
            dis=1.5; bd=0.1;
        }
        dis *= sz;
        reverse(str.begin(), str.end());
        int oo = sp;
        for (char ch : str) {
            if (sp) Rectangle(x+oo*sz*0.1-sz*0.2,y-sz*0.2,sz*1.5,sz,0xFF3333); 
            PaintChar(int(ch), x+oo*sz*0.1, y, sz, (sp)?0xFFFFFF:clr, bd, th, sc);
            y -= dis;
            oo *= -1;
        }
    }
    void PaintStrM(string str, double x, double y, double sz, int clr, double bd=0.15, double dis=1.0) {
        dis *= sz;
        y -= dis*0.5*double(str.size()-1)-sz*0.5;
        for (char ch : str) {
            PaintChar(int(ch), x, y, sz, clr, bd);
            y += dis;
        }
    }
    bool CheckActive() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) return true;
            }
        }
        return false;
    }
    bool CheckPlace(int x, int y) {
        if ((min(x,y)<1)||((x>LX)||(y>LY))) return true;
        return ((B[x][y])&&(!C[x][y]));
    }
    bool CheckFill(int x, int y) {
        if ((min(x,y)<1)||((x>LX)||(y>LY))) return true;
        return B[x][y];
    }
    int QueryFloor() {
        int res = 0;
        for (ll x : Floor) {
            if (Score>=x) ++res;
        }
        return res;
    }
    int QueryHeight() {
        for (int i=LX; i; --i) {
            for (int j=1; j<=LY; ++j) {
                if ((B[i][j])&&(!C[i][j])) return i;
            }
        }
        return 0;
    }
    int RollPiece() {
        if (BagSz!=Bag.size()) {
            BagSz=Bag.size(); HisSeq.clear();
        }
        if (!BagSz) return 4;
        int res = 0;
        for (int i=0; i<Rol; ++i) {
            int x = gen()%BagSz;
            res=x; bool ok=true;
            for (int y : HisSeq) {
                if (x==y) {
                    ok=false; break;
                }
            }
            if (ok) break;
        }
        HisSeq.push_back(res);
        while (HisSeq.size()>His) HisSeq.pop_front();
        return Bag[res];
    }
    bool CheckSpawn(int _Pid, int _Dir, int Inc=0) {
        ClassPiece P = Piece[_Pid][_Dir];
        int SX=DX-1+P.SDel, SY=(LY-P.LY)/2+1;
        SY = max(1,min(LY-P.LY+1,SY));
        SX = max(2,min(LX,SX))+Inc;
        for (int i=0; i<P.LX; ++i) {
            for (int j=0; j<P.LY; ++j) {
                if ((CheckPlace(SX+i,SY+j))&&(P.B[i][j])) return false;
            }
        }
        return true;
    }
    bool Spawn(int _Pid, int _Dir, bool Clutch=false) {
        Flipped = false;
        RotEffVal = 0.0;
        DX += DXDel;
        LqC = 0;
        GTime=FTime=0;
        while ((Bl.size())&&(Bl.front()+3000LL<clock())) {
            if (rnd(100)<_SegMess) LstHole=RollHole(_Luck);
            Bl.pop(); AddGarbage(2,RollGarb());
        }
        ll curtm=clock(); DXDel=AllSpinGarb.size()+Bl.size();
        int Mins = int((curtm-begtm-BegDelay)/60000LL);
        if ((Plrs>1)&&(QuickPlay)) {
            if (Mins>=8) DXDel+=(ModExpert<2)?2:3;
            if (Mins>=10) DXDel+=(ModExpert<2)?3:5;
            if (Mins>=12) DXDel+=(ModExpert<2)?5:12;
        }
        DX -= DXDel;
        ClassPiece P = Piece[_Pid][_Dir];
        //if (LY<P.LY) return false;
        int SX=DX-1+P.SDel, SY=(LY-P.LY)/2+1;
        SY = max(1,min(LY-P.LY+1,SY));
        SX = max(2,min(LX,SX));
        int Inc = 0;
        if (Clutch) {
            while ((SX+Inc<LX+5)&&(!CheckSpawn(_Pid,_Dir,Inc))) ++Inc;
            SX += Inc;
        }
        for (int i=0; i<P.LX; ++i) {
            for (int j=0; j<P.LY; ++j) {
                if ((CheckPlace(SX+i,SY+j))&&(P.B[i][j])) return false;
            }
        }
        if (Inc) {
            double asz = sz*0.7;
            sprintf(buf, "+ %d +", Inc);
            TQu.push_back({-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0004,buf,0xFFFFFF});
        }
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) {
                    B[i][j]=C[i][j]=0; LE[i][j]=10000;
                }
            }
        }
        for (int i=0; i<P.LX; ++i) {
            for (int j=0; j<P.LY; ++j) {
                if (P.B[i][j]) {
                    C[SX+i][SY+j]=1; B[SX+i][SY+j]=_Pid;
                }
            }
        }
        for (int i=1; i<=LY; ++i) PieceCol[i]=false;
        Pid=_Pid; Dir=_Dir;
        DrdLeft = DRD;
        savx=savy=tavx=tavy=-100.0;
        return true;
    }
    bool CheckUp() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if ((C[i][j])&&(CheckPlace(i+1,j))) return false;
            }
        }
        return true;
    }
    bool MoveUp() {
        if (!CheckUp()) return false;
        for (int i=LX; i>1; --i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i-1][j]) {
                    B[i][j]=B[i-1][j]; C[i][j]=1;
                    B[i-1][j]=C[i-1][j]=0;
                }
            }
        }
        MiniSpin = false;
        return true;
    }
    bool CheckDown() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if ((C[i][j])&&(CheckPlace(i-1,j))) return false;
            }
        }
        return true;
    }
    bool MoveDown() {
        if (!CheckDown()) return false;
        for (int i=1; i<LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i+1][j]) {
                    B[i][j]=B[i+1][j]; C[i][j]=1;
                    B[i+1][j]=C[i+1][j]=0;
                }
            }
        }
        MiniSpin = false;
        return true;
    }
    bool DeepDrop() {
        int dd = 0;
        for (int d=1; d<=LX; ++d) {
            bool ok = true;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (!C[i][j]) continue;
                    if (CheckPlace(i-d,j)) {
                        ok=false; break;
                    }
                }
                if (!ok) break;
            }
            if (ok) {
                dd=d; break;
            }
        }
        if (!dd) return false;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (!C[i][j]) continue;
                C[i-dd][j]=true; C[i][j]=false;
                B[i-dd][j]=B[i][j]; B[i][j]=0;
            }
        }
        MiniSpin = false;
        return true;
    }
    bool CheckLeft() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if ((C[i][j])&&(CheckPlace(i,j-1))) return false;
            }
        }
        return true;
    }
    bool MoveLeft() {
        if (!CheckLeft()) {
            if ((MoveEff)&&(sz>15)&&(!Bot)) DropKY=max(-sz*2,DropKY-sz);
            if (DropKY>sz*2) DropKY=sz*2;
            if (DropKY<-sz*2) DropKY=-sz*2;
            return false;
        }
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j+1]) {
                    B[i][j]=B[i][j+1]; C[i][j]=1;
                    B[i][j+1]=C[i][j+1]=0;
                }
            }
        }
        MiniSpin = false;
        return true;
    }
    bool CheckRight() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if ((C[i][j])&&(CheckPlace(i,j+1))) return false;
            }
        }
        return true;
    }
    bool MoveRight() {
        if (!CheckRight()) {
            if ((MoveEff)&&(sz>15)&&(!Bot)) DropKY=min(sz*2,DropKY+sz);
            if (DropKY>sz*2) DropKY=sz*2;
            if (DropKY<-sz*2) DropKY=-sz*2;
            return false;
        }
        for (int i=1; i<=LX; ++i) {
            for (int j=LY; j; --j) {
                if (C[i][j-1]) {
                    B[i][j]=B[i][j-1]; C[i][j]=1;
                    B[i][j-1]=C[i][j-1]=0;
                }
            }
        }
        MiniSpin = false;
        return true;
    }
    bool ResetDec = false;
    int QueryLen() {
        int res = 0;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<LY; ++j) {
                if (D[i][j]!=D[i][j+1]) ++res;
                if ((i<LX)&&(D[i][j]!=D[i+1][j])) ++res;
            }
            if (!D[i][1]) ++res;
            if (!D[i][LY]) ++res;
        }
        for (int j=1; j<=LY; ++j) {
            if (!D[1][j]) ++res;
            if (!D[LX][j]) ++res;
        }
        return res;
    }
    bool Rotate(int NewDir, int NewPid=0) {
        ResetDec = false;
        int del = (Dir-NewDir+4)&3;
        if (!NewPid) NewPid=Pid;
        if ((NewDir<0)||(NewDir>3)||(!Pid)) return false;
        int FstX=0, FstY=0;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) {
                    FstX=i; FstY=j; break;
                }
            }
            if (FstX) break;
        }
        if (!FstX) return false;
        if (((LqOS)||(LqC>=17))&&(!Bot)&&(Pid==4)&&(NewPid==4)&&(((!CheckLeft())&&(!CheckRight()))||((LqOS)&&((!CheckUp())||(!CheckDown())||(!CheckLeft())||(!CheckRight()))))) {
            vector<pair<int,int> > CLst;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (!C[i][j]) continue;
                    if ((C[i+1][j])&&(C[i][j+1])&&(!C[i+1][j+1])) continue;
                    if ((C[i+1][j])&&(C[i][j-1])&&(!C[i+1][j-1])) continue;
                    if ((C[i-1][j])&&(C[i][j+1])&&(!C[i-1][j+1])) continue;
                    if ((C[i-1][j])&&(C[i][j-1])&&(!C[i-1][j-1])) continue;
                    if ((C[i-1][j])&&(C[i+1][j])) continue;
                    if ((C[i][j-1])&&(C[i][j+1])) continue;
                    CLst.push_back(make_pair(i,j));
                }
            }
            set<pair<pair<int,int>,pair<int,int> > > st;
            pair<pair<int,int>,pair<int,int> > Bst = make_pair(make_pair(0,0),make_pair(0,0));
            st.insert(Bst);
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    D[i][j] = (B[i][j]>0);
                    if (!C[i][j]) continue;
                    for (int ii=-1; ii<=1; ++ii) {
                        for (int jj=-1; jj<=1; ++jj) {
                            if (abs(ii)+abs(jj)!=1) continue;
                            int x=i+ii, y=j+jj;
                            if ((min(x,y)<1)||(x>LX)||(y>LY)) continue;
                            if (B[x][y]) continue;
                            for (pair<int,int> o : CLst) {
                                if (make_pair(i,j)!=o) st.insert(make_pair(make_pair(x,y),o));
                            }
                        }
                    }
                }
            }
            pair<int,int> Rec = make_pair(99999999,0);
            int len = QueryLen();
            for (pair<pair<int,int>,pair<int,int> > o : st) {
                //printf("(%d,%d),(%d,%d)\n",o.first.first,o.first.second,o.second.first,o.second.second);
                if (o.first.first) {
                    D[o.first.first][o.first.second] = 1;
                    D[o.second.first][o.second.second] = 0;
                }
                int val = 0;
                if (((Dir+3)&3)==NewDir) val=(o.first.second-o.second.second)*100+o.first.second;
                if (((Dir+2)&3)==NewDir) val=(o.first.first-o.second.first)*100+o.first.first;
                if (((Dir+1)&3)==NewDir) val=(o.second.second-o.first.second)*100-o.first.second;
                val = val*100+o.first.first;
                pair<int,int> Now = make_pair(val,QueryLen());
                if (!o.first.first) Now=make_pair(99999999,0);
                if (Now<=Rec) {
                    Rec=Now; Bst=o;
                }
                if (o.first.first) {
                    D[o.first.first][o.first.second] = 0;
                    D[o.second.first][o.second.second] = 1;
                }
            }
            if (Bst.first.first) {
                pair<pair<int,int>,pair<int,int> > o = Bst;
                B[o.first.first][o.first.second]=Pid; C[o.first.first][o.first.second]=true;
                B[o.second.first][o.second.second]=0; C[o.second.first][o.second.second]=false;
                Dir = 0;
                ResetRem=max(0,ResetRem-1); ResetDec=true;
                MiniSpin = false;
                if ((!CheckUp())&&(!CheckDown())&&(!CheckLeft())&&(!CheckRight())) {
                    double x=0.0, y=0.0; int bn=0;
                    for (int i=1; i<=LX; ++i) {
                        for (int j=1; j<=LY; ++j) {
                            if (C[i][j]) {
                                ++bn; x+=double(i); y+=double(j);
                            }
                        }
                    }
                    x=x/double(bn)-0.5; y=y/double(bn)+0.5;
                    double dx=sz*double(DX-x), dy=sz*double(y-1);
                    double th = rndf()*acos(-1.0)*2.0;
                    for (int i=0; i<10; ++i) {
                        th += acos(-1.0)*2.0/10.0;
                        PQu.push_back({dx,dy,sin(th)*0.1,cos(th)*0.1,0,0,sz*0.15,0.006,rndf()*acos(-1.0)*2.0,5,Mix(Piece[(Flipped)?Flip[Pid]:Pid][0].clr,0xFFFFFF,0.7)});
                    }
                    if (SpinEff) {
                        if (del==1) DropRot+=0.1;
                        if (del==3) DropRot-=0.1;
                    }
                }
                if ((CheckLeft())||(CheckRight())||(CheckDown())) LqC=0;
                return true;
            }
        }
        int SX=FstX-Piece[Pid][Dir].FstX, SY=FstY-Piece[Pid][Dir].FstY;
        ClassPiece P = Piece[NewPid][NewDir];
        bool flag = false;
        int beg=Dir; if (beg&1) beg^=2;
        int en=NewDir; if (en&1) en^=2;
        bool fst = true;
        for (pair<int,int> KT : Kick[Pid][beg][en]) {
            if ((ResetLim)&&(!ResetRem)&&((KT.second>Shift[Pid][en].second-Shift[Pid][beg].second)||(Pid!=NewPid))&&(!Bot)) break;
            SX+=KT.second; SY+=KT.first;
            bool ok = true;
            int iid=0, did=0;
            for (int i=P.LX-1; i>=0; --i) {
                for (int j=0; j<P.LY; ++j) {
                    ++iid;
                    if ((P.B[i][j])&&(CheckPlace(SX+i,SY+j))) {
                        did=iid; ok=false; break;
                    }
                }
                if (!ok) break;
            }
            if ((KickTable=="ars")&&(fst)&&(did%3==2)&&((Pid==2)||(Pid==3)||(Pid==5))&&(!Bot)) break;
            fst = false;
            if (ok) {
                if (((KT.second>Shift[Pid][en].second-Shift[Pid][beg].second)||(Pid!=NewPid))&&(!Bot)) {
                    ResetRem=max(0,ResetRem-1); if ((KickTable=="ars")&&(ResetRem)) ResetRem=max(ResetRem-999,1);
                    ResetDec = true;
                }
                flag=true; break;
            }
            else {
                SX-=KT.second; SY-=KT.first;
            }
        }
        if (!flag) return false;
        MiniSpin = false;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) B[i][j]=C[i][j]=0;
            }
        }
        for (int i=0; i<P.LX; ++i) {
            for (int j=0; j<P.LY; ++j) {
                if (P.B[i][j]) {
                    B[SX+i][SY+j]=NewPid; C[SX+i][SY+j]=1;
                }
            }
        }
        if (Pid!=NewPid) Flipped^=1;
        Dir = NewDir;
        Pid = NewPid;
        double bavx=0.0, bavy=0.0;
        bool ckd = CheckDown();
        if (RotEff) {
            int tot=0, totx=0, toty=0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        totx+=i; toty+=j; ++tot;
                    }
                }
            }
            if (tot) {
                bavx = double(totx)/double(max(tot,1))-0.5+DXDel;
                bavy = double(toty)/double(max(tot,1))-0.5;
                if ((DropEff)&&(ckd)) bavx-=max(0.0,min(1.0,double(DropTime)/double(max(1,DropL))));
                if ((GarbageType!="fall")&&(GarbRise)) bavx-=double(max(0,min(GarbRise-LastGarb,GarbRise)))/double(GarbRise);
            }
        }
        if (del==1) RotEffVal-=acos(-1.0)*0.5;
        if (del==3) RotEffVal+=acos(-1.0)*0.5;
        if (del==2) {
            if (RotType==1) RotEffVal-=acos(-1.0);
            else RotEffVal+=acos(-1.0);
        }
        if (del) {
            double nx = bavx-savx;
            double ny = bavy-savy;
            savx = (savx+bavx)*0.5;
            savy = (savy+bavy)*0.5;
            if (del==1) {
                savx+=ny*0.5; savy-=nx*0.5;
            }
            if (del==3) {
                savx-=ny*0.5; savy+=nx*0.5;
            }
        }
        if (Pid==4) {
            if (((KickTable=="default")||(KickTable=="extend")||(KickTable=="asc+"))&&((!CheckLeft())&&(!CheckRight())&&(!CheckDown()))) ++LqC;
            else LqC=0;
        }
        else LqC=0;
        if ((!CheckUp())&&(!CheckDown())&&(!CheckLeft())&&(!CheckRight())) {
            double x=0.0, y=0.0; int bn=0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        ++bn; x+=double(i); y+=double(j);
                    }
                }
            }
            x=x/double(bn)-0.5; y=y/double(bn)+0.5;
            double dx=sz*double(DX-x), dy=sz*double(y-1);
            double th = rndf()*acos(-1.0)*2.0;
            for (int i=0; i<10; ++i) {
                th += acos(-1.0)*2.0/10.0;
                PQu.push_back({dx,dy,sin(th)*0.1,cos(th)*0.1,0,0,sz*0.15,0.006,rndf()*acos(-1.0)*2.0,5,Mix(Piece[(Flipped)?Flip[Pid]:Pid][0].clr,0xFFFFFF,0.7)});
            }
            if (SpinEff) {
                if (del==1) DropRot+=0.1;
                if (del==3) DropRot-=0.1;
            }
        }
        else if (!CheckDown()) {
            bool hp=false, ok=true; int nc=0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (!C[i][j]) continue;
                    if (int(C[i-1][j])+int(C[i+1][j])+int(C[i][j-1])+int(C[i][j+1])+int(C[i-1][j-1])+int(C[i-1][j+1])+int(C[i+1][j-1])+int(C[i+1][j+1])<3) continue;
                    if (int(CheckFill(i-1,j-1))+int(CheckFill(i+1,j-1))+int(CheckFill(i-1,j+1))+int(CheckFill(i+1,j+1))<3) ok=false;
                    if (int(CheckPlace(i-1,j-1))+int(CheckPlace(i+1,j-1))+int(CheckPlace(i-1,j+1))+int(CheckPlace(i+1,j+1))<3) ++nc;
                    hp = true;
                }
            }
            if ((!hp)||(nc>1)||(del==2)) ok=false;
            if (SpinRule=="easy") ok=true;
            if (ok) {
                MiniSpin = true;
                double x=0.0, y=0.0; int bn=0;
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if (C[i][j]) {
                            ++bn; x+=double(i); y+=double(j);
                        }
                    }
                }
                x=x/double(bn)-0.5; y=y/double(bn)+0.5;
                double dx=sz*double(DX-x), dy=sz*double(y-1);
                double th = rndf()*acos(-1.0)*2.0;
                for (int i=0; i<5; ++i) {
                    th += acos(-1.0)*2.0/5.0;
                    PQu.push_back({dx,dy,sin(th)*0.1,cos(th)*0.1,0,0,sz*0.1,0.006,rndf()*acos(-1.0)*2.0,5,Mix(Piece[(Flipped)?Flip[Pid]:Pid][0].clr,0xFFFFFF,0.7)});
                }
            }
        }
        return true;
    }
    int RollHole(int Luck=_Luck, bool NoSame=false) {
        if (!Luck) {
            if ((LstHole<1)||(LstHole>LY)) return rnd(LY)+1;
            if (NoSame) {
                int x = rnd(LY-1)+1;
                return (x==LstHole)?LY:x;
            }
            return rnd(LY)+1;
        }
        vector<int> Ord(LY,0), W(LY,0);
        int Height = 0;
        int GarbPos = 0;
        for (int i=1; i<=LX; ++i) {
            bool Garb = false;
            for (int j=1; j<=LY; ++j) {
                if (CheckPlace(i,j)) Height=i;
                if (B[i][j]==154) Garb=true;
            }
            if (Garb) {
                for (int j=1; j<=LY; ++j) {
                    if (!B[i][j]) GarbPos=j;
                }
            }
        } 
        for (int j=1; j<=LY; ++j) {
            Ord[j-1] = j;
            int Hole = 0;
            for (int i=1; i<=LX; ++i) {
                if (!CheckPlace(i,j)) {
                    Hole=i; break;
                }
            }
            HoleEval[j] = Height-Hole;
            if (GarbPos) HoleEval[j]+=5*abs(GarbPos-j);
        }
        shuffle(Ord.begin(), Ord.end(), rng);
        stable_sort(Ord.begin(), Ord.end(), [](int x, int y) {
            return HoleEval[x]>HoleEval[y];
        });
        int SW = 0;
        for (int i=0; i<LY; ++i) {
            W[i]=max(0,90+Luck*(10-i*2)); if ((NoSame)&&(Ord[i]==LstHole)) W[i]=0;
            SW += W[i];
        }
        if (!SW) {
            if ((LstHole<1)||(LstHole>LY)) return rnd(LY)+1;
            if (NoSame) {
                int x = rnd(LY-1)+1;
                return (x==LstHole)?LY:x;
            }
            return rnd(LY)+1;
        }
        int Pick = rnd(SW);
        for (int i=0; i<LY; ++i) {
            if (Pick<W[i]) return Ord[i];
            Pick -= W[i];
        }
        return 1;
    }
    lll RollGarb() {
        if (!ClearTemplate.empty()) return ClearTemplate[(TemplatePos++)%ClearTemplate.size()];
        if ((LstHole<1)||(LstHole>LY)) LstHole=RollHole(_Luck);
        lll gb = (lll(1)<<(LY+1))-1-(lll(1)<<LstHole);
        if (ModHold==2) {
            if (LstHole==1) gb&=~(lll(1)<<(LstHole+1));
            else gb&=~(lll(1)<<(LstHole-1));
        }
        if (GarbageShape=="full") gb=(lll(1)<<(LY+1))-1;
        if (GarbageShape=="empty") gb=0;
        if (GarbageShape=="random") {
            for (int i=1; i<=LY; ++i) {
                if (rnd(2)) gb&=~(lll(1)<<i);
            }
        }
        if (GarbageShape=="bubble") gb^=(lll(1)<<(LY+1))-1;
        if (GarbageShape=="board") {
            LstHole ^= 1;
            gb = (lll(1)<<(LY+1))-1;
            for (int i=1; i<=LY; ++i) {
                if ((i+LstHole)&1) gb&=~(lll(1)<<i);
            }
        }
        if ((!rnd(3))&&(ModDivergence==1)) gb&=~(lll(2)<<rnd(LY));
        if (ModDivergence==2) {
            for (int i=0; i<6; ++i) gb&=~(lll(2)<<rnd(LY));
        }
        if (GarbageShape=="copy") {
            gb = lll(0);
            for (int i=1; i<=LY; ++i) {
                if (CheckPlace(1,i)) gb|=(lll(1)<<i);
            }
            if (ActiveGarb.size()) gb=ActiveGarb.back().second;
            if (Rec.size()) gb=Rec.back().second.first;
        }
        return gb;
    }
    int Spin, SemiSpin; double ravx=0.0, ravy=0.0;
    void Lock() {
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) PieceCol[j]=true;
            }
        }
        savx=savy=tavx=tavy=-100.0;
        if ((DropKX<=sz*15)&&(MoveEff)) DropKX+=sz*3;
        if ((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate")) InChain=true;
        if ((Arcade)&&(Level%100!=99)&&((Zen)||(Level!=998))) ++Level;
        Spin = ((!CheckUp())&&(!CheckDown())&&(!CheckLeft())&&(!CheckRight()));
        SemiSpin = false;
        if (Spin) {
            bool ex=false, sw=false, a3=false, ew=false;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    int td=0, te=0;
                    for (int ii=-1; ii<=1; ++ii) {
                        for (int jj=-1; jj<=1; ++jj) {
                            int dis = abs(ii)+abs(jj);
                            if ((dis==1)&&((!CheckPlace(i+ii,j+jj)&&(C[i+ii][j+jj])))) ++td;
                            if ((dis==1)&&((!CheckPlace(i+ii,j+jj)&&(!B[i+ii][j+jj])))) ++te;
                        }
                    }
                    if ((C[i][j])&&(te>1)) ex=true;
                    if ((C[i][j])&&(te>2)) a3=true;
                    if ((!B[i][j])&&(td>1)) sw=true;
                    if ((!C[i][j])&&(td>1)) ew=true;
                }
            }
            SemiSpin = (((ex)&&((sw)||(!ew)))||(a3));
        }
        if (!Complete) ++SumPiece;
        int totx=0, toty=0, tot=0;
        for (int j=1; j<=LY; ++j) {
            bool ok = false;
            for (int i=LX-1; i; --i) {
                if (C[i+1][j]) ok=true;
                if ((B[i][j]==151)&&(ok)) {
                    for (int jj=1; jj<=LY; ++jj) {
                        B[i][jj]=151; LE[i][jj]=10000;
                    }
                }
                else ok=false;
            }
        }
        int Lines = 0;
        vector<lll> Shape;
        for (int i=1; i<=LX; ++i) {
            if (i<=RoundHeight) continue;
            bool ok=true; lll gb=lll(0);
            for (int j=1; j<=LY; ++j) {
                if ((!B[i][j])||(B[i][j]==153)) ok=false;
                if (!C[i][j]) gb|=(lll(1)<<j);
            }
            if (ok) {
                ++Lines; Shape.push_back(gb);
            }
        }
        if (Lines) {
            if (GarbageShape=="arcade") reverse(Shape.begin(),Shape.end());
            ClearShape = Shape;
        }
        ++PartID;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) {
                    totx+=i; toty+=j; ++tot;
                    C[i][j]=0; LE[i][j]=10000; ID[i][j]=PartID;
                    if (Flipped) B[i][j]=Flip[B[i][j]];
                }
            }
        }
        memset(C, 0, sizeof(C));
        avx = double(totx)/double(max(tot,1));
        avy = double(toty)/double(max(tot,1));
        ravx = sz*double(DX-avx)+sz*0.5+KX;
        ravy = sz*double(avy-1)+sz*0.5+KY;
        AreLeft = (Lines)?LCD:ARE;
        for (int i=VanishHeight+1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (B[i][j]) {
                    double dx=sz*double(DX-i)+sz*0.5, dy=sz*double(j-1)+sz*0.5;
                    #define sq(beg, ss, clr) PQu.push_back({dx,dy,vx,vy,0.001,0,sz*0.5*ss,0.002,theta,4,clr})
                    double vx = -0.7+0.2*(rnd(10000)*0.0001);
                    double vy = 0.2*(rnd(10000)*0.0001-0.5);
                    double theta = acos(-1.0)*rndf();
                    int clr = Mix(Piece[B[i][j]][0].clr,0xFFFFFF,0.7);
                    sq(0, 1, clr);
                    #undef sq
                    B[i][j]=C[i][j]=LE[i][j]=ID[i][j]=0;
                }
            }
        }
        if ((Next.size())&&(!CheckSpawn(Next[0],InitFacing))) AreLeft=max(AreLeft,DeathARE);
        DcdLeft=DCD; HcdLeft=HCD; DrdLeft=DRD;
    }
    void HardDrop() {
        while (CheckDown()) {
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        double dx=sz*double(DX-i)+sz*rndf(), dy=sz*double(j-1)+sz*rndf();
                        PQu.push_back({dx,dy,-1,0,0,0,2,0.01,rndf()*acos(-1.0),4,Mix(0xFFFFFF,Piece[B[i][j]][0].clr,0.3)});
                    }
                }
            }
            MoveDown(); if ((!QuickPlay)&&(!Complete)) Score+=2;
        }
        Lock();
    }
    bool Dig = false;
    bool RVis[111][55]; int RBel[111][55];
    vector<pair<int,int> > Group;
    void RDfs(int x, int y) {
        RVis[x][y] = true;
        Group.push_back(make_pair(x,y));
        if (ClearGravity=="separate") return;
        for (int ii=-1; ii<=1; ++ii) {
            for (int jj=-1; jj<=1; ++jj) {
                if (abs(ii)+abs(jj)!=1) continue;
                int nx=x+ii, ny=y+jj;
                if ((!B[nx][ny])||(RVis[nx][ny])) continue;
                if ((ClearGravity=="cascade")&&(ID[nx][ny]!=ID[x][y])) continue;
                RDfs(nx, ny);
            }
        }
    }
    bool PieceCol[55];
    int RemoveLines() {
        int res=0; Dig=false;
        int low = 0;
        for (int i=1; i<=LX; ++i) {
            if (i<=RoundHeight) continue;
            bool ok=true, garb=false;
            for (int j=1; j<=LY; ++j) {
                if (!CheckPlace(i,j)) ok=false;
                if (B[i][j]==153) ok=false;
                if (B[i][j]>150) garb=true;
            }
            if (!ok) continue;
            if (garb) {
                Dig=true; if (!Complete) ++SumDig;
            }
            for (int j=1; j<=LY; ++j) {
                double dx=sz*double(DX-i-res)+sz*0.5, dy=sz*double(j-1)+sz*0.5;
                PQu.push_back({dx,dy,-0.7+0.2*(rnd(10000)*0.0001),0.2*(rnd(10000)*0.0001-0.5),0.003,0,sz*0.12,0.001,rnd(10000)*0.0002*acos(-1.0),12,((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate"))?0x99FFFF:Piece[B[i][j]][0].clr});
            }
            ++res; if (!low) low=i;
            if (ClearGravity!="default") {
                for (int j=1; j<=LY; ++j) B[i][j]=C[i][j]=LE[i][j]=ID[i][j]=0;
                continue;
            }
            for (int j=i; j<LX; ++j) {
                for (int k=1; k<=LY; ++k) {
                    B[j][k]=B[j+1][k]; C[j][k]=C[j+1][k]; LE[j][k]=LE[j+1][k]; ID[j][k]=ID[j+1][k];
                }
            }
            for (int j=1; j<=LY; ++j) B[LX][j]=C[LX][j]=LE[LX][j]=ID[LX][j]=0;
            --i;
        }
        if ((res)&&((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate"))) {
            for (int i=1; i<=LX; ++i) {
                RVis[i][0]=RVis[i][LY+1]=true;
                for (int j=1; j<=LY; ++j) {
                    RVis[i][j]=false; RVis[j][0]=RVis[j][LX+1]=true;
                    PrePos[i][j] = i;
                }
            }
            if (ClearGravity=="separate") {
                for (int i=1; i<low; ++i) {
                    for (int j=1; j<=LY; ++j) RVis[i][j]=true;
                }
            }
            vector<vector<pair<int,int> > > Groups;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if ((B[i][j])&&(!RVis[i][j])) {
                        Group.clear(); RDfs(i,j);
                        sort(Group.begin(), Group.end());
                        Groups.push_back(Group);
                    }
                }
            }
            for (;;) {
                memset(RBel, 0, sizeof(RBel));
                for (int i=0; i<Groups.size(); ++i) {
                    for (pair<int,int> o : Groups[i]) RBel[o.first][o.second]=i+1;
                }
                vector<int> ok;
                for (int i=0; i<Groups.size(); ++i) {
                    bool curr = true;
                    for (pair<int,int> o : Groups[i]) {
                        if ((o.first==1)||((B[o.first-1][o.second])&&(!RBel[o.first-1][o.second]))||((RBel[o.first-1][o.second])&&(RBel[o.first-1][o.second]!=RBel[o.first][o.second]))) {
                            curr=false; break;
                        }
                    }
                    if (curr) ok.push_back(i);
                }
                if (ok.empty()) break;
                for (int i : ok) {
                    for (pair<int,int> o : Groups[i]) {
                        int x=o.first, y=o.second;
                        B[x-1][y]=B[x][y]; LE[x-1][y]=LE[x][y]; ID[x-1][y]=ID[x][y];
                        B[x][y]=LE[x][y]=ID[x][y]=0;
                        PrePos[x-1][y] = PrePos[x][y];
                    }
                    for (int j=0; j<Groups[i].size(); ++j) --Groups[i][j].first;
                }
            }
        }
        return res;
    }
    void GiveScore(int x, bool Ignore=false) {
        if (Complete) return;
        if (!QuickPlay) return;
        if ((Odoo)&&(!Ignore)) x*=2;
        if ((Ignore)&&(ModExpert==2)) {
            x = x*(CurFloor*CurFloor+CurFloor+10)/20;
            Score=max(Floor[max(0,CurFloor-1)],Score-ll(x)); return;
        }
        if ((CurFloor<Floor.size())&&(Score>=Floor[CurFloor])) {
            ++CurFloor; FloorTm=0;
            sprintf(buf, "Floor %d", CurFloor);
            double asz = sz*0.12*double(LY);
            TQu.push_back({sz*0.2*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.00006,buf,0xFFCCCC});
            sprintf(buf, "%lld m", Floor[CurFloor-1]/1000LL);
            asz = sz*0.1*double(LY);
            TQu.push_back({sz*0.3*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.1,0.00003,buf,0xFFCCCC});
        }
        ll pre = Score;
        Score += (x*(Acc+1))/4;
        int rem = x*(Acc+1)%4;
        if (rnd(4)<rem) ++Score;
        if (!Ignore) {
            int del = int(Score-pre);
            if (!del) return;
            double asz = sz*0.08*double(LY);
            sprintf(buf, "+%lld.%lld", del/1000, del/100%10);
            double remtm = sqrt(max(0.0,double(del)*4.0/double(Acc+1)))/30.0;
            TQu.push_back({sz*0.95*double(DX+2),sz*0.5*double(LY)-asz*0.7,asz,0.2,min(0.0003,max(0.00002,0.001/remtm)),buf,0x99FFFF});
        }
    }
    void EText(string str, int clr) {
        double asz = sz*0.06*double(LY);
        TQu.push_back({sz*0.95*double(DX+2)+asz,sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0003,str,clr});
    }
    int B2BClr(int x) {
        vector<pair<int,int> > lst={{4,0x00FFCC},{13,0xFFFF00},{31,0xFF0000},{45,0xDF3782},{70,0xAF2FFF},{90,0x0080FF},
        {130,0x66CCFF},{150,0x99FFFF},{220,0xE5E59C}};
        for (int i=1; i<lst.size(); ++i) {
            if ((lst[i-1].first<=x)&&(x<=lst[i].first)) return Mix(lst[i].second,lst[i-1].second,double(x-lst[i-1].first)/double(lst[i].first-lst[i-1].first));
        }
        if (x<=lst[0].first) return lst[0].second;
        return lst.back().second;
    }
    int QueryLev() {
        if (Arcade) return 0;
        int res = LevBase;
        if (LevLine) {
            int x=SumLine, val=LevLine;
            while (res<100) {
                if (x<val) break;
                x-=val; val+=LevLineInc;
                ++res;
            }
        }
        if (LevTime) {
            int x=int((clock()-begtm-BegDelay)/1000LL), val=LevTime;
            while (res<100) {
                if (x<val) break;
                x-=val; val+=LevTimeInc;
                ++res; 
            }
        }
        if (LevPiece) {
            int x=SumPiece, val=LevPiece;
            while (res<100) {
                if (x<val) break;
                x-=val; val+=LevPieceInc; 
                ++res;
            }
        }
        if (LevAttack) {
            int x=SumPiece, val=LevAttack;
            while (res<100) {
                if (x<val) break;
                x-=val; val+=LevAttackInc; 
                ++res;
            }
        }
        return max(0,min(100,max(res,LevStart)));
    }
    void PaintText(int tm) {
        #warning text
        ll timer = max(0LL,clock()-begtm-BegDelay);
        double tsz=sz*0.6, tx=sz*max(DX,22);
        if (max(Life,Stock)) {
            tx += tsz*4.7;
            sprintf(buf, "/ %d", Stock+1);
            tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, 0xFF6666);
            sprintf(buf, "%d", Life+1);
            tx-=tsz*1.5; PaintStrR(buf,tx,-tsz*3.5,tsz,0xFF6666);
            tx-=tsz*1.2; PaintStrR("LIFE", tx, -tsz*3.5, tsz*0.8, TextColor);
            tx -= tsz;
        }
        sprintf(buf, "%.2f /m", double(SumAttack)*60000.0/double(timer));
        tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
        if ((QuickPlay)&&(Plrs>1)) {
            sprintf(buf, "Rnk #%d", VSRnk);
            PaintStrL(buf, tx+tsz*0.2, sz*LY+tsz*1.5, tsz*0.6, StatColor);
        }
        else if (QuickPlay) {
            sprintf(buf, "Floor %d", QueryFloor());
            PaintStrL(buf, tx+tsz*0.2, sz*LY+tsz*1.5, tsz*0.6, StatColor);
        }
        else if (Plrs>2) {
            sprintf(buf, "%.2f VS", double(SumAttack+SumDig)*100000.0/double(timer));
            PaintStrL(buf, tx+tsz*0.2, sz*LY+tsz*1.5, tsz*0.6, StatColor);
        }
        else if (Arcade) {
            sprintf(buf, "/ %d", (Zen)?100*(Level/100+1):min(999,100*(Level/100+1)));
            PaintStrL(buf, tx+tsz*0.2, sz*LY+tsz*1.5, tsz*0.6, StatColor);
        }
        else if ((Plrs==1)&&(!Zen)) {
            sprintf(buf, "%.2f /p", double(Score)/max(1,SumPiece));
            PaintStrL(buf, tx+tsz*0.2, sz*LY+tsz*1.5, tsz*0.6, StatColor);
        }
        sprintf(buf, "%d", (SumAttack<TarAttack)?TarAttack-SumAttack:SumAttack);
        tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, (TarAttack)?((SumAttack>=TarAttack)?0x00FFCC:0xFDD000):StatColor);
        if ((Plrs>2)&&(!QuickPlay)) {
            sprintf(buf, "%2d", VSRnk);
            PaintStrL(buf, tx, sz*LY+tsz*1.5, tsz, StatColor);
            sprintf(buf, " /%2d", PlrsCnt);
            PaintStrL(buf, tx+tsz*0.6, sz*LY+tsz*4.5, tsz*0.6, StatColor);
            sprintf(buf, " /%2d", Plrs);
            PaintStrL(buf, tx-tsz, sz*LY+tsz*4.5, tsz*0.6, TextColor);
        }
        else if ((Plrs==2)&&(!QuickPlay)) {
            sprintf(buf, "%.2f", double(SumAttack+SumDig)*100000.0/double(timer));
            PaintStrL(buf, tx, sz*LY+tsz*1.5, tsz, StatColor);
        }
        else {
            if (Score<=DisScore) DisScore=Score;
            else {
                ll del = Score-DisScore;
                del = min(del,max(1LL,del/10LL));
                DisScore += del;
            }
            ll dd = (DisScore<ll(TarScore))?ll(TarScore)-DisScore:DisScore;
            if (QuickPlay) sprintf(buf, "%lld.%02lld", dd/1000LL, dd/10LL%100LL);
            else if (Arcade) sprintf(buf, "%d", (Zen)?Level:min(999,Level));
            else sprintf(buf, "%lld", dd);
            PaintStrL(buf, tx, sz*LY+tsz*1.5, tsz, (TarScore)?((DisScore>=ll(TarScore))?0x00FFCC:0xFDD000):StatColor);
        }
        tx-=tsz*1.2; PaintStrR("ATTACK", tx, -tsz*3.5, tsz*0.8, TextColor);
        if ((Plrs>2)&&(!QuickPlay)) PaintStrL("RANK", tx, sz*LY+tsz*1.5, tsz*0.8, TextColor);
        else if ((Plrs==2)&&(!QuickPlay)) PaintStrL("VS SCORE", tx, sz*LY+tsz*1.5, tsz*0.8, TextColor);
        else if (Arcade) PaintStrL("LEVEL", tx, sz*LY+tsz*1.5, tsz*0.8, TextColor);
        else PaintStrL("SCORE", tx, sz*LY+tsz*1.5, tsz*0.8, TextColor);
        tx -= tsz;
        sprintf(buf, "%.2f /m", double(SumLine)*60000.0/double(timer));
        tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
        sprintf(buf, "%d", (SumLine<TarLine)?TarLine-SumLine:SumLine);
        tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, (TarLine)?((SumLine>=TarLine)?0x00FFCC:0xFDD000):StatColor);
        tx-=tsz*1.2; PaintStrR("LINE", tx, -tsz*3.5, tsz*0.8, TextColor);
        tx -= tsz;
        sprintf(buf, "%.2f /s", double(SumPiece)*1000.0/double(timer));
        tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
        sprintf(buf, "%d", (SumPiece<TarPiece)?TarPiece-SumPiece:SumPiece);
        tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, (TarPiece)?((SumPiece>=TarPiece)?0x00FFCC:0xFDD000):StatColor);
        tx-=tsz*1.2; PaintStrR("PIECE", tx, -tsz*3.5, tsz*0.8, TextColor);
        ll _tmr = timer;
        if ((TarTime)&&(_tmr<ll(TarTime))) timer=ll(TarTime)-_tmr;
        tx -= tsz;
        sprintf(buf, ".%03d",timer%1000);
        tx-=tsz*1.5; PaintStrR(buf, tx+tsz*0.2, -tsz*3.5, tsz*0.8, (TarTime)?((_tmr>=ll(TarTime))?0x00FFCC:0xFDD000):StatColor);
        sprintf(buf, "%02d:%02d",timer/60000,timer/1000%60);
        PaintStrR(buf, tx, -tsz*6.5, tsz, (TarTime)?((_tmr>=ll(TarTime))?0x00FFCC:0xFDD000):StatColor);
        timer = _tmr;
        tx-=tsz*1.2; PaintStrR("TIME", tx, -tsz*3.5, tsz*0.8, TextColor);
        if ((Plrs>2)||(QuickPlay)) {
            tx -= tsz;
            sprintf(buf, "%d KO\'s", KO);
            tx-=tsz; if (Plrs>1) PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
            if (QuickPlay) sprintf(buf,"%d",Acc);
            else sprintf(buf,"%d",SKO);
            tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, StatColor);
            tx-=tsz*1.2; PaintStrR((QuickPlay)?"BOOST":"BADGE", tx, -tsz*3.5, tsz*0.8, TextColor);
        }
        else if (Plrs==2) {
            tx -= tsz;
            sprintf(buf, "of %d", RoundTot);
            tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
            sprintf(buf, "%d", Wins);
            tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, StatColor);
            tx-=tsz*1.2; PaintStrR("POINT", tx, -tsz*3.5, tsz*0.8, TextColor);
        }
        else if (Arcade) {
            tx -= tsz;
            int gr = max(0,SegGrade[min(int(SegGrade.size())-1,Grade)]+SumCool-SumRegret+min(8,InvisGrade/100)); 
            if (ArcadeInvis) sprintf(buf,"+ %d.%02d +",InvisGrade/100,InvisGrade%100);
            else if (InvisTm)sprintf(buf, "+ GAME CLEAR +", Grade);
            else sprintf(buf, "+ %d +", Grade);
            tx-=tsz; PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, StatColor);
            tx-=tsz*1.5; PaintStrR(GradeName[min(int(GradeName.size())-1,gr)], tx, -tsz*3.5, tsz, StatColor);
            tx-=tsz*1.2; PaintStrR("GRADE", tx, -tsz*3.5, tsz*0.8, TextColor);
        }
        else if ((LevStart)||(LevBase)||(LevLine)||(LevTime)||(LevPiece)||(LevAttack)) {
            tx -= tsz;
            sprintf(buf, "%d", QueryLev());
            tx-=tsz*1.5; PaintStrR(buf, tx, -tsz*3.5, tsz, StatColor);
            tx-=tsz*1.2; PaintStrR("LEVEL", tx, -tsz*3.5, tsz*0.8, TextColor);
        }
        tx = sz*4.0;
        SpinTm = max(((ModSpin)&&(SpinType==LstAct.first))?7500:0,SpinTm-tm*((SpinDis)?50:3));
        int bg = Mix(0xFFFFFF,0x000000,BackgroundRatio);
        double rat = double(SpinTm)/15000.0;
        rat *= rat;
        sprintf(buf, "%c-Spin", PName[SpinType]);
        bool sp = ((AllSpinGarbOper)&&(SpinType==LstAct.first));
        double spin = acos(-1.0)*max(rat-0.9,0.0)*10.0;
        if ((sp)||((Bot)&&(OperTime<100))) spin=0.0;
        if ((SpinType)&&(SpinTm)) {
            if (SpinFull==2) PaintStrR(buf, tx, -tsz*3.5, tsz, Mix(Piece[SpinType][0].clr,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, spin);
            else if (SpinFull==1) {
                sprintf(buf, "Semi %c-Spin", PName[SpinType]);
                PaintStrR(buf, tx+tsz*0.1, -tsz*3.5, tsz*0.8, Mix(Piece[SpinType][0].clr,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, spin);
            }
            else {
                PaintStrR("Mini", tx-tsz*0.4, -tsz*3.5, tsz*0.7, Mix(Piece[SpinType][0].clr,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, spin);
                PaintStrR(buf, tx+tsz*0.5, -tsz*3.5, tsz*0.7, Mix(Piece[SpinType][0].clr,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, spin);
            }
        }
        tx += tsz*2.0;
        ClearTm = max(((ModSpin)&&(ClearType==LstAct.second))?5000:0,ClearTm-tm*3);
        bg = Mix(0xFFFFFF,0x000000,BackgroundRatio);
        rat = double(ClearTm)/10000.0;
        rat *= rat;
        spin = acos(-1.0)*max(rat-0.9,0.0)*10.0;
        double scale = max(rat-0.8,0.0);
        if ((sp)||((Bot)&&(OperTime<100))) spin=0.0;
        if (ClearType<4) scale=0.0;
        sp = ((AllSpinGarbOper)&&(ClearType==LstAct.second));
        if (ClearTm) {
            if (ClearWType) {
                sprintf(buf, "%d-WIDE", ClearWType);
                PaintStrR(buf, tx, -tsz*3.5, tsz*0.8, Mix((ClearColor)?Mix(0xFFFFFF,Piece[ClearColor][0].clr,0.5):0xFFFFFF,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, (ClearColor)?spin:0, scale);
                PaintStrR(LCW[ClearType], tx+tsz, -tsz*3.5, tsz*1.2, Mix((ClearColor)?Mix(0xFFFFFF,Piece[ClearColor][0].clr,0.5):0xFFFFFF,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, (ClearColor)?spin:0, scale);
            }
            else PaintStrR(LCW[ClearType], tx, -tsz*3.5, tsz*1.5, Mix((ClearColor)?Mix(0xFFFFFF,Piece[ClearColor][0].clr,0.5):0xFFFFFF,bg,rat), 0.05+0.1*rat, 1.5-0.5*rat, sp, (ClearColor)?spin:0, scale);
        }
        tx += tsz*2.5;
        ComboTm = max((ComboType)?7500:0,ComboTm-tm*((ComboType)?10:50));
        rat = double(ComboTm)/10000.0;
        scale = max(rat-0.8,0.0);
        if ((!ComboType)||((Bot)&&(OperTime<100))) scale=0.0;
        if ((ComboRule=="c2")&&(ComboType)) rat=double(min(5000,ComboRem))/5000.0*0.6+0.4;
        else if (ComboRule=="c2") {
            rat=min(rat,0.4); ComboTm=min(ComboTm,4000);
        } 
        sprintf(buf, "%d Combo", ComboType);
        PaintStrR(buf, tx, -tsz*3.5, tsz, Mix((ComboType)?Mix(0xFFFFFF,0x39C5BB,(double(min(21,ComboType)-1)/20.0)):0x888888,bg,min(rat,0.75)/0.75), 0.05+0.1*rat, 1.5-0.5*rat, 0, 0,scale);
        tx += tsz*1.8;
        B2BTm = max((B2BType)?7500:0,B2BTm-tm*((B2BType)?10:50));
        rat = double(B2BTm)/10000.0;
        scale = max(rat-0.8,0.0);
        if ((!B2BType)||((Bot)&&(OperTime<100))) scale=0.0;
        if (B2BRule=="techmino") {
            sprintf(buf, "B%dB %d%%", (B2BType>80)?3:((B2BType>=5)?2:bool(B2B)), B2BType);
            int clr = 0x888888;
            if (B2BType>=5) clr=0xFF6666;
            if (B2BType>80) clr=0x9999FF;
            PaintStrR(buf, tx, -tsz*3.5, tsz, Mix(clr,bg,min(rat,0.75)/0.75), 0.05+0.1*rat, 1.5-0.5*rat, 0, 0, scale);
        }
        else {
            sprintf(buf, "B2B x%d", B2BType);
            double ra = 1.0;
            if ((B2BRule=="surge")&&(B2BType>3)) ra=pow(double(min(300,B2BType)-2),0.05);
            PaintStrR((B2BRule=="default")?"Back to Back":buf, tx, -tsz*3.5, tsz*ra, Mix((B2BType)?(((B2BType>3)&&(B2BRule=="surge"))?B2BClr(B2BType):0xFDD000):0x888888,bg,min(rat,0.75)/0.75), (1.0+scale)*0.05+0.1*rat, 1.5-0.5*rat, 0, 0, scale);
        }
    }
    #warning paint
    void Paint(int tm) {
        bool ckd = CheckDown();
        if (RotEff) {
            int tot=0, totx=0, toty=0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        totx+=i; toty+=j; ++tot;
                    }
                }
            }
            if (tot) {
                tavx = double(totx)/double(max(tot,1))-0.5+DXDel;
                tavy = double(toty)/double(max(tot,1))-0.5;
                if ((DropEff)&&(ckd)) tavx-=max(0.0,min(1.0,double(DropTime)/double(max(1,DropL))));
                if ((GarbageType!="fall")&&(GarbRise)) tavx-=double(max(0,min(GarbRise-LastGarb,GarbRise)))/double(GarbRise);
            }
            else tavx=tavy=savx=savy=-100.0;
        }
        DX += DXDel;
        tm *= 2;
        int brd = Mix(0xFFFFFF,0x000000,BoardRatio);
        if (isz!=Ssz) {
            double del = fabs(isz-Ssz);
            double val = min(del,max(del*0.0008*tm,tm*0.002));
            if (isz>Ssz) isz-=val;
            else isz+=val;
        }
        DropKX = max(0.0,DropKX*double(1000-tm*10)/1000.0);
        DropKY = DropKY*double(1000-tm*10)/1000.0;
        DropRot = DropRot*double(1000-tm*2)/1000.0;
        SKX += DropKX;
        SKY += DropKY;
        if (KX!=SKX) {
            double del = fabs(KX-SKX);
            double val = min(del,max(del*0.001*tm,tm*0.01));
            if (KX>SKX) KX-=val;
            else KX+=val;
        }
        if (KY!=SKY) {
            double del = fabs(KY-SKY);
            double val = min(del,max(del*0.001*tm,tm*0.01));
            if (KY>SKY) KY-=val;
            else KY+=val;
        }
        if (Rot!=DropRot) {
            double del = fabs(Rot-DropRot);
            double val = min(del,max(del*0.00001*tm,tm*0.0001));
            if (Rot>DropRot) Rot-=val;
            else Rot+=val;
        }
        if (fabs(RotEffVal)>=0.001) {
            double del = fabs(RotEffVal);
            double val = min(del,max(del*0.001*tm,tm*0.01));
            if (RotEffVal>0.0) RotEffVal-=val;
            else RotEffVal+=val;
        }
        if (tavx>=-99.0) {
            if ((savx<-99.0)||(fabs(RotEffVal)<0.001)) savx=tavx;
            if (savx!=tavx) {
                double del = fabs(savx-tavx);
                double val = max(min(del,max(del*0.01*tm,tm*0.01)),del-1.0);
                if (savx>tavx) savx-=val;
                else savx+=val;
            }
        }
        else savx=-100.0;
        if (tavy>=-99.0) {
            if ((savy<-99.0)||(fabs(RotEffVal)<0.001)) savy=tavy;
            if (savy!=tavy) {
                double del = fabs(savy-tavy);
                double val = max(min(del,max(del*0.01*tm,tm*0.01)),del-1.0);
                if (savy>tavy) savy-=val;
                else savy+=val;
            }
        }
        else savy=-100.0;
        SKX -= DropKX;
        SKY -= DropKY;
        tm /= 2;
        PaintText(tm);
        int DropLen = 3321;
        for (int j=1; j<=LY; ++j) {
            int lst = 0;
            for (int i=1; i<=LX; ++i) {
                if (C[i][j]) DropLen=min(DropLen,i-lst-1);
                else if (B[i][j]) lst=i;
            }
        }
        sz = isz;
        //sz=floor(sz); if (int(sz)&1) sz+=1.0;
        deque<pair<int,pair<int,int> > > rec; deque<int> ps;
        int ActiveTot=0;
        for (pair<int,int> o : ActiveGarb) {
            rec.push_back(make_pair(o.first,make_pair(o.second,-1LL))); ActiveTot+=o.first;
            ps.push_back(0);
        }
        for (pair<int,pair<lll,ll> > o : Rec) {
            rec.push_back(o); ps.push_back((int(clock()-o.second.second)<Passthrough)&&(Passthrough));
        }
        int RecTot=0; for (pair<int,pair<lll,ll> > o : rec) RecTot+=o.first;
        int Mins = int((clock()-begtm-BegDelay)/60000LL);
        int AggCap = 12;
        if (Mins>=3) AggCap+=4;
        if (Mins>=5) AggCap+=4;
        if (Mins>=7) AggCap+=4;
        int Agg = AggCap;
        int Dg = 0;
        int RecHeight = QueryHeight()+ActiveGarb.size();
        for (pair<int,pair<lll,ll> > o : Rec) RecHeight+=o.first; 
        if ((RecHeight+7>DX)&&(!ModExpert)) Dg+=6;
        if ((ModSpin==2)||(ModMess==2)||(ModDivergence==2)) {
            int GarbC = 0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (B[i][j]==154) {
                        ++GarbC; break;
                    }
                }
            }
            Dg += min(GarbC,5)*2;
        }
        Dg = min(Dg,AggCap);
        for (int i=1; i<=max(DX,24); ++i) {
            if ((i<=10)&&(Arcade)) {
                int clr = 0x555555;
                if (i-1<=Level/100) clr=0xCCCCCC;
                if (SegSta[i-1]>0) clr=0x66CCFF;
                if (SegSta[i-1]<0) clr=0xEE0000;
                Rectangle(sz*(double(DX)-0.5*double(i)), -10, sz*0.5-3, 3, clr);
            }
            if ((i<=24)&&(QuickPlay)) {
                int clr = 0x555555;
                if (i<=AggCap) clr=0xCCCCCC;
                if (i<=Agg) clr=0xFDD000;
                if (i<=Agg-AggDec) clr=0xEE0000;
                if (i<=Dg) clr=0xFFAAAA;
                if ((AggDec)&&(i==Agg-AggDec+1)) {
                    double rat = min(1.0,max(0.0,double(AggTm)/double(max(1,DecDis[min(int(DecDis.size()-1),QueryFloor())]))));
                    clr = Mix(0xFFA500,0xFDD000,rat);
                }
                Rectangle(sz*(double(DX)-0.5*double(i)), -10, sz*0.5-3, 3, clr);
            }
            if ((i<=8)&&(QuickPlay)) {
                int clr = 0x555555;
                if ((i==1)&&(ModHold)) clr=0xEE82EE;
                if ((i==2)&&(ModMess)) clr=0xFFA500;
                if ((i==3)&&(ModGravity)) clr=0xFDD000;
                if ((i==4)&&(ModStrength)) clr=0xEE0000;
                if ((i==5)&&(ModDivergence)) clr=0x0080FF;
                if ((i==6)&&(ModInvisible)) clr=0x9999FF;
                if ((i==7)&&(ModSpin)) clr=0x00FFCC;
                if ((i==8)&&(ModExpert)) clr=0xFFFF00;
                Rectangle(sz*(double(DX)-0.5*double(i)), -18, sz*0.5-3, 3, clr);
                clr = 0;
                if ((i==1)&&(ModHold==2)) clr=0xEE82EE;
                if ((i==2)&&(ModMess==2)) clr=0xFFA500;
                if ((i==3)&&(ModGravity==2)) clr=0xFDD000;
                if ((i==4)&&(ModStrength==2)) clr=0xEE0000;
                if ((i==5)&&(ModDivergence==2)) clr=0x0080FF;
                if ((i==6)&&(ModInvisible==2)) clr=0x9999FF;
                if ((i==7)&&(ModSpin==2)) clr=0x00FFCC;
                if ((i==8)&&(ModExpert==2)) clr=0xFFFF00;
                if (clr) Rectangle(sz*(double(DX)-0.5*double(i)),-22,sz*0.5-3,3,clr);
            }
            if (i<=Cy.size()) {
                int base = 0xFFE211;
                if (Cy[i-1].second==1) base=0xEE0000;
                if (Cy[i-1].second==2) base=0x0080FF;
                if (Cy[i-1].second==3) base=0x00FFCC;
                if (Cy[i-1].second==4) base=0xEE82EE;
                if (Cy[i-1].second==5) base=Mix(0x000000,0x33EE00,0.1);
                if (Cy[i-1].second==6) base=0x66CCFF;
                if (Cy[i-1].second==7) base=0xFFA500;
                Rectangle(sz*double(DX-i)+2, sz*double(LY)+6, sz-7, 3, base);
            }
            if ((i<=7)&&(Odoo)) {
                int base = 0x000000;
                if (i==1) base=0xEE0000;
                if (i==2) base=0x0080FF;
                if (i==3) base=0x00FFCC;
                if (i==4) base=0xEE82EE;
                if (i==5) base=Mix(0x000000,0x33EE00,0.1);
                if (i==6) base=0x66CCFF;
                if (i==7) base=0xFFA500;
                double rat = 0.0;
                if (EV[i]) rat=min(1.0,0.2+double(EV[i])/200000.0*0.8);
                Rectangle(sz*double(DX-i), sz*double(LY)+2, sz-3, 3, Mix(base,0x555555,rat));
            }
            if (i>DX) continue;
            for (int j=1; j<=LY; ++j) {
                int clr=GridColor; if (i+2>DX) clr=BufferColor;
                if ((Style=="classic")||(Style=="arcade")) clr=brd;
                if ((i==SelX)&&(j==SelY)) clr=0x39C5BB;
                Square(sz*double(DX-i),sz*double(j-1),sz,clr);
                Square(sz*double(DX-i)+sz*0.05,sz*double(j-1)+sz*0.05,sz*0.9,brd);
            }
            if (i>RecTot) {
                Rectangle(sz*double(DX-i),-5,sz-3*sz/20.0,3,(i<=GarbageGap+ActiveTot)?SlotColor:OverSlotColor); continue;
            }
            bool flag=false, active=false, avail=false; int cur=0;
            ll curt=clock(); int clr=0;
            bool Pass = false;
            int oid = 0;
            for (pair<int,pair<lll,ll> > o : rec) {
                if (cur+1==i) flag=true;
                cur += o.first;
                if (cur>=i) {
                    if (o.second.second<0LL) active=true;
                    else if (curt-ll(GarbDelay)>=o.second.second) avail=true;
                    else {
                        double rat = min(1.0,max(0.0,double(curt-o.second.second)/double(max(1,GarbDelay))));
                        clr = Mix(0xFFA500,0xFFE211,rat);
                    }
                    if (oid<ps.size()) Pass=ps[oid];
                    break;
                }
                ++oid;
            }
            clr = (active)?0xDF3782:(((avail)?((i<=ActiveTot+GarbageGap)?0xEE0000:0xFF6666):clr));
            if (Pass) clr=Mix(0xFFFFFF,clr,0.6);
            Rectangle(sz*double(DX-i), -5, (flag)?sz-3:sz, 3, clr);
        }
        int bg = Mix(0xFFFFFF,0x000000,BackgroundRatio);
        if (!RotEff) savx=savy=tavx=tavy=-100.0;
        for (int i=1; i<=GarbagePreview; ++i) {
            if (i>RecTot) break;
            int cur=0; lll gb=lll(0);
            for (pair<int,pair<lll,ll> > o : rec) {
                cur += o.first;
                if (cur>=i) {
                    gb=o.second.first; break;
                }
            }
            for (int j=1; j<=LY; ++j) {
                if ((GarbageType!="bomb")&&(!(gb&(lll(1)<<j)))) continue;
                int clr = Mix(Mix(0xFFFFFF,0x000000,BackgroundRatio),Piece[154][0].clr,double(i-1)/double(GarbagePreview));
                if (GarbageType=="bomb") clr=(gb&(lll(1)<<j))?0x444444:0xFFFF99;
                if ((GarbageType=="solid")&&(gb&(lll(1)<<j))) clr=0x444444;
                #define sq(beg, ss, clr) Square(sz*0.4+sz*double(DX-(1-i))+beg*sz,sz*double(j-1)+beg*sz,sz*ss,clr)
                #define rec(begx, begy, sx, sy, clr) Rectangle(sz*0.4+sz*double(DX-(1-i))+sz*begx,sz*double(j-1)+sz*begy,sz*sx,sz*sy,clr)
                if (sz<6) {
                    sq(0,1,clr); continue;
                }
                if (Style=="classic") {
                    sq(0, 1, brd);
                    sq(0.1, 0.8, clr);
                    sq(0.1, 0.1, Mix(0xFFFFFF,clr,0.5));
                    sq(0.2, 0.2, Mix(0xFFFFFF,clr,0.5));
                    sq(0.3, 0.1, clr);
                    continue;
                }
                if (Style=="arcade") {
                    clr = Mix(0x000000,clr,0.3);
                    sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                    sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                    sq(0.1, 0.8, clr);
                    rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                    rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                    rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                    rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                    rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                    rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                    continue;
                }
                if (Style=="simple") {
                    sq(0, 1, clr);
                    continue;
                }
                sq(0, 1, Mix(0xFFFFFF,clr,0.1));
                sq(0.1, 0.9, Mix(0x000000,clr,0.2));
                sq(0.1, 0.8, clr);
                sq(0.2, 0.6, Mix(0x000000,clr,0.05));
                sq(0.25, 0.5, Mix(0x000000,clr,0.1));
                sq(0.3, 0.4, Mix(0x000000,clr,0.15));
                #undef sq
                #undef rec
            }
        }
        bool invis = ((ArcadeInvis)||(ModInvisible));
        bool Active = false;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) Active=true;
            }
        }
        int FullLines = 0;
        int seekh=0, seekr=3;
        for (int i=LX; i; --i) {
            for (int j=1; j<=LY; ++j) {
                if (B[i][j]==154) {
                    if (--seekr==0) seekh=i;
                    break;
                }
            }
            if (!seekr) break;
        }
        seekh += DXDel;
        int oid = 0;
        for (int __=0; __<((RotEff)?2:1); ++__) {
            for (int i=((Zen)&&((!GarbagePreview)||((!ActiveGarb.size())&&(!Rec.size()))))?-11:1; i<=LX; ++i) {
                if (!i) continue;
                bool ok = true;
                if (i>DXDel) {
                    for (int j=1; j<=LY; ++j) {
                        if (!B[i-DXDel][j]) ok=false;
                        if (C[i-DXDel][j]) ok=false;
                        if (B[i-DXDel][j]==153) ok=false;
                        }
                        if (i-DXDel<=RoundHeight) ok=false;
                    if (ok) ++FullLines;
                }
                else ok=false;
                for (int j=1; j<=((i<0)?10:LY); ++j) {
                    int cB = (i>DXDel)?B[i-DXDel][j]:((i>DXDel-AllSpinGarb.size())?152:153);
                    int cC = (i>DXDel)?C[i-DXDel][j]:0;
                    int cLE = (i>DXDel)?LE[i-DXDel][j]:0;
                    if ((cC)&&(Flipped)) cB=Flip[cB];
                    if (i<0) {
                        ++oid; cB=154; cC=cLE=0;
                        if (Piece[oid][0].clr) cB=oid;
                        if (!Piece[oid][0].clr) cB=0;
                        if (oid>106) cB=150+oid-106;
                    }
                    if (((!RotEff)||(!__))&&(i<=DX)&&(RoundHeight)&&(i-DXDel<=RoundHeight)) Square(sz*double(DX-i)+sz*0.1,sz*double(j-1)+sz*0.1,sz*0.8,RoundColor);
                    if (((!RotEff)||(!__))&&(i<=DX)&&(i>VanishHeight)) Square(sz*double(DX-i)+sz*0.1,sz*double(j-1)+sz*0.1,sz*0.8,VanishColor);
                    if (((!RotEff)||(!__))&&(i<=DX)&&(DropLen+i<=LX)&&(C[DropLen+i-DXDel][j])&&(ShowShadow)&&(ModHold<2)) Square(sz*double(DX-i)+sz*0.1,sz*double(j-1)+sz*0.1,sz*0.8,ShadowColor);
                    //if (PieceCol[j]) Square(sz*double(DX-i)+sz*0.1,sz*double(j-1)+sz*0.1,sz*0.8,0x666600);
                    if ((cC!=__)&&(RotEff)) continue;
                    if (!cB) continue;
                    if ((invis)&&(!cLE)&&(!cC)&&((cB<=150)||((ModInvisible==2)&&(cB>150)&&(i<seekh)))) continue;
                    int clr = Piece[cB][0].clr;
                    if ((!cC)&&(cLE)) {
                        clr = Mix(((invis)&&((cB<=150)||((ModInvisible==2)&&(cB>150)&&(i<seekh))))?brd:0xFFFFFF,clr,(((invis)&&((cB<=150)||((ModInvisible==2)&&(cB>150)&&(i<seekh))))?10000-cLE:cLE)*(((invis)&&((cB<=150)||((ModInvisible==2)&&(cB>150))))?0.0001:0.00005));
                        if (i>DXDel) LE[i-DXDel][j]=max(0,cLE-tm*((ArcadeInvis==1)?2:40));
                    }
                    //if ((cC)&&(cB)) clr=Mix(0xFFFFFF,clr,0.1);
                    double rat = 0.0;
                    if ((LCD)&&(ok)&&(!Active)) clr=Mix(clr,((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate"))?0x99FFFF:bg,pow(double(max(0,min(LCD,AreLeft)))/double(LCD),0.3));
                    if ((cC)&&(ckd)&&(DropEff)) rat=max(0.0,min(1.0,double(DropTime)/double(max(1,DropL))));
                    else if ((LCD)&&(ClearGravity=="default")&&(!Active)&&(!ok)&&(FullLines)) rat=FullLines*double(max(0,min(LCD,LCD-AreLeft)))/double(LCD);
                    if ((GarbageType!="fall")&&(GarbRise)&&(i>DXDel)) rat+=double(max(0,min(GarbRise-LastGarb,GarbRise)))/double(GarbRise);
                    if (((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate"))&&(i>DXDel)&&(PrePos[i-DXDel][j])&&(!Active)&&(InChain)&&(LCD)) rat-=double(max(0,min(LCD,AreLeft)))/double(LCD)*double(PrePos[i-DXDel][j]-(i-DXDel));
                    if ((cB==154)&&(GarbageType=="fall")) rat-=double(LX-i)*double(max(0,cLE))/20000.0;
                    double lrat = max(0.0,min(1.0,double(DropTime)/double(max(1,LockL))));
                    if (ckd) lrat=0.0;
                    #define sq(beg, ss, clr) Square(sz*double(DX-i)+rat*sz+sz*beg,sz*double(j-1)+sz*beg,sz*ss,clr)
                    #define rec(begx, begy, sx, sy, clr) Rectangle(sz*double(DX-i)+rat*sz+sz*begx,sz*double(j-1)+sz*begy,sz*sx,sz*sy,clr)
                    if (sz<6) {
                        sq(0, 1, (cC)?Mix(0xFFFFFF,clr,0.1):clr); continue;
                    }
                    if (cC) {
                        if (RotEff) UseRotEff=true;
                        double rr = 0.4-0.2*lrat;
                        double rb = 0.05+0.05*lrat;
                        if (Style=="classic") {
                            sq(0, 1, brd);
                            sq(0.1, 0.8, clr);
                            sq(0.2, 0.6, Mix(clr,0xFFFFFF,lrat*0.8));
                            sq(0.1, 0.1, 0xFFFFFF);
                            sq(0.2, 0.2, 0xFFFFFF);
                            sq(0.3, 0.1, Mix(clr,0xFFFFFF,lrat*0.8));
                            UseRotEff = false;
                            continue;
                        }
                        if (Style=="arcade") {
                            sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                            sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                            sq(0.1, 0.8, clr);
                            rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                            rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                            rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                            rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                            rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                            rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                            UseRotEff = false;
                            continue;
                        }
                        if (Style=="simple") {
                            sq(0, 1, Mix(0xFFFFFF,clr,rr*0.2));
                            UseRotEff = false;
                            continue;
                        }
                        sq(0, 1, Mix(0xFFFFFF,clr,rr));
                        sq(0.1, 0.9, Mix(0x000000,clr,rb));
                        sq(0.1, 0.8, clr);
                        sq(0.2, 0.65, Mix(0xFFFFFF,clr,rr));
                        sq(0.2, 0.6, Mix(0x000000,clr,rb*0.5));
                        sq(0.3, 0.4, Mix(0xFFFFFF,clr,rr));
                        sq(0.35, 0.3, clr);
                        UseRotEff = false;
                    }
                    else if (cB<=150) {
                        if (Style=="classic") {
                            sq(0, 1, brd);
                            sq(0.1, 0.8, clr);
                            sq(0.1, 0.1, 0xFFFFFF);
                            sq(0.2, 0.2, 0xFFFFFF);
                            sq(0.3, 0.1, clr);
                            continue;
                        }
                        if (Style=="arcade") {
                            clr = Mix(0x000000,clr,0.3);
                            sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                            sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                            sq(0.1, 0.8, clr);
                            rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                            rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                            rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                            rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                            rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                            rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                            continue;
                        }
                        if (Style=="simple") {
                            sq(0, 1, clr);
                            continue;
                        }
                        sq(0, 1, Mix(0xFFFFFF,clr,0.1));
                        sq(0.1, 0.9, Mix(0x000000,clr,0.2));
                        sq(0.1, 0.8, clr);
                        sq(0.2, 0.65, Mix(0xFFFFFF,clr,0.2));
                        sq(0.2, 0.6, Mix(0x000000,clr,0.05));
                        sq(0.3, 0.4, Mix(0xFFFFFF,clr,0.2));
                        sq(0.35, 0.3, clr);
                    }
                    else {
                        if (Style=="classic") {
                            sq(0, 1, brd);
                            sq(0.1, 0.8, clr);
                            sq(0.1, 0.1, Mix(0xFFFFFF,clr,0.5));
                            sq(0.2, 0.2, Mix(0xFFFFFF,clr,0.5));
                            sq(0.3, 0.1, clr);
                            continue;
                        }
                        if (Style=="arcade") {
                            clr = Mix(0x000000,clr,0.3);
                            sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                            sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                            sq(0.1, 0.8, clr);
                            rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                            rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                            rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                            rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                            rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                            rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                            continue;
                        }
                        if (Style=="simple") {
                            sq(0, 1, clr);
                            continue;
                        }
                        sq(0, 1, Mix(0xFFFFFF,clr,0.1));
                        sq(0.1, 0.9, Mix(0x000000,clr,0.2));
                        sq(0.1, 0.8, clr);
                        sq(0.2, 0.6, Mix(0x000000,clr,0.05));
                        sq(0.25, 0.5, Mix(0x000000,clr,0.1));
                        sq(0.3, 0.4, Mix(0x000000,clr,0.15));
                    }
                    #undef sq
                    #undef rec
                }
            }
        }
        for (int i=0; i<AllSpinGarb.size(); ++i) {
            sprintf(buf, "%d", AllSpinGarb[i].first);
            for (int j=1; j<=LY; ++j) {
                if (AllSpinGarb[i].second&(lll(1)<<j)) continue;
                PaintStrM(buf,sz*double(DX-(DXDel-i))+sz*0.2,sz*double(j-1)+sz*0.05,sz*0.6,0xFFCCFF);
            }
        }
        ClassPiece P = Piece[(Next.size())?Next[0]:0][InitFacing];
        int SX=DX-1+P.SDel, SY=(LY-P.LY)/2+1;
        SY = max(1,min(LY-P.LY+1,SY));
        SX = max(2,min(LX,SX));
        double rat = double(max(0,min(5,5-(DX-2-QueryHeight()))))*0.2;
        for (int ii=0; ii<P.LX; ++ii) {
            for (int jj=0; jj<P.LY; ++jj) {
                if (!P.B[ii][jj]) continue;
                int i=SX+ii, j=SY+jj;
                PaintStrM("*",sz*double(DX-i)+sz*0.15,sz*double(j-1)-sz*0.3,sz,0xFF0000,rat*0.2);
            }
        }
        rat = double(max(0,min(5,5-(VanishHeight-2-QueryHeight()))))*0.2;
        if (rat>0.1) {
            for (int i=1; i<=LY; ++i) {
                PaintStrM("*",sz*double(DX-VanishHeight-1)+sz*0.15,sz*double(i-1)-sz*0.3,sz,VanishColor,rat*0.2);
            }
        }
        rat = max(0.0,min(1.0,double(DropTime)/double(max(1,LockL))));
        if (CheckDown()) rat=0.0;
        rat = 1.0-rat;
        Rectangle(sz*double(DX),0.0,sz*0.2,sz*LY,0xEEEEEE);
        Rectangle(sz*double(DX),0.0,sz*0.2,sz*LY*rat,0xFDD000);
        rat = 1.0-max(0.0,min(1.0,double(GTime)/double(max(1,GLockL))));
        if (GLockL<99999999) Rectangle(sz*double(DX)+sz*0.2*1.0/3.0,0.0,sz*0.2*2.0/3.0,sz*LY*rat,0xEE82EE);
        rat = 1.0-max(0.0,min(1.0,double(FTime)/double(max(1,FLockL))));
        if (FLockL<99999999) Rectangle(sz*double(DX)+sz*0.2*2.0/3.0,0.0,sz*0.2*1.0/3.0,sz*LY*rat,0xEE0000);
        rat = max(0.0,min(1.0,double(ResetRem)/double(max(1,ResetLim))));
        if (!ResetLim) rat=0.0;
        Rectangle(sz*0.2+sz*double(DX),0.0,sz*0.2,sz*LY,0xDDDDDD);
        Rectangle(sz*0.2+sz*double(DX),0.0,sz*0.2,sz*LY*rat,0xFFA500);
        if (Bot) Rectangle(sz*double(DX),0.0,sz*0.4,sz*LY,0xDEDEDE);
        if (QuickPlay) {
            vector<int> clr = {
            0x888888,0xC23A30,0x006098,0xEE0000,0x008E9C,
            0xA6217F,0xD29700,0xF6C582,0x009B6B,0x8FC13F,
            0x009BC0,0xED796B,0x995D35,0xFFE211,0xD5A7A1,
            0x5B2C68,0x76A32E,0x39C5BB,0x86001A,0xEE82EE,
            0x203864,0x73E9DB,0xFFCCCC,0x9999FF,0xE40077,
            0xE46022,0xB35A20,0xD97DAD,0x395C00,0xFF5353,
            0xC6E002,0x999900,0x006666,0xFFFF00,0xA29BBB,
            0x0080FF,0x66CCFF,0xCB35BD,0x00DEB4,0xB9A567,
            0xFFFFFF};
            double rat = max(0.0,min(1.0,double(AccRnk)/double(4000*60*(Acc+1))));
            Rectangle(sz*0.4+sz*double(DX),0.0,sz*0.2,sz*LY,clr[min(int(clr.size()-1),Acc)]);
            Rectangle(sz*0.4+sz*double(DX),sz*LY*(1.0-rat)*0.5,sz*0.2,sz*LY*rat,clr[min(int(clr.size()-1),Acc+1)]);
        }
        if (Arcade) {
            vector<int> clr = {
            0x888888,0xC23A30,0x006098,0xEE0000,0x008E9C,
            0xA6217F,0xD29700,0xF6C582,0x009B6B,0x8FC13F,
            0x009BC0,0xED796B,0x995D35,0xFFE211,0xD5A7A1,
            0x5B2C68,0x76A32E,0x39C5BB,0x86001A,0xEE82EE,
            0x203864,0x73E9DB,0xFFCCCC,0x9999FF,0xE40077,
            0xE46022,0xB35A20,0xD97DAD,0x395C00,0xFF5353,
            0xC6E002,0x999900,0x006666,0xFFFF00,0xA29BBB,
            0x0080FF,0x66CCFF,0xCB35BD,0x00DEB4,0xB9A567,
            0xFFFFFF};
            if (Grade>20) clr[0]=0xFFFFFF;
            double rat = max(0.0,min(1.0,double(GradeRnk)/1000.0));
            Rectangle(sz*0.4+sz*double(DX),0.0,sz*0.2,sz*LY,clr[Grade%40]);
            Rectangle(sz*0.4+sz*double(DX),sz*LY*(1.0-rat)*0.5,sz*0.2,sz*LY*rat,clr[(Grade+1)%40]);
        }
        double msz = sz*0.8;
        SX=0; SY=0;
        if (Hold) {
            if (Piece[Hold][0].LX<=3) SX=1;
            if (Piece[Hold][0].LX<=1) SX=2;
            if (Piece[Hold][0].LY<=3) SY=1;
            if (Piece[Hold][0].LY<=1) SY=2;
        }
        if (HoldRule) {
            Rectangle(10, -sz*3-msz*4.5, msz*4.0, msz*6.0, brd);
            for (int i=0; i<5; ++i) {
                for (int j=0; j<5; ++j) {
                    int clr = brd;
                    if (min(4-i-SX,4-j-SY)>=0) {
                        if (Piece[Hold][InitFacing].B[4-i-SX][4-j-SY]) clr=((HoldEnable)&&(HoldRule))?Piece[Hold][InitFacing].clr:0x888888;
                    }
                    if (clr==brd) continue;
                    #define sq(beg, ss, clr) Square(msz*double(i)+10+msz*beg,msz*0.5*double(!(Piece[Hold][0].LY&1))-sz*3-msz*double(j)+msz*beg,msz*ss,clr)
                    #define rec(begx, begy, sx, sy, clr) Rectangle(msz*double(i)+10+msz*begx,msz*0.5*double(!(Piece[Hold][0].LY&1))-sz*3-msz*double(j)+msz*begy,msz*sx,msz*sy,clr)
                    //Square(msz*double(i+d*5)+10, msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j), msz*0.9, Mix(0xFFFFFF,clr,0.5));
                    //Square(msz*double(i+d*5)+10, msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j), msz*0.8, clr);
                    if (Style=="classic") {
                        sq(0, 1, brd);
                        sq(0.1, 0.8, clr);
                        sq(0.2, 0.6, ((HoldEnable)&&(HoldRule))?0xFFFFFF:0xCCCCCC);
                        sq(0.1, 0.1, ((HoldEnable)&&(HoldRule))?0xFFFFFF:0xCCCCCC);
                        continue;
                    }
                    if (Style=="arcade") {
                        sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                        sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                        sq(0.1, 0.8, clr);
                        rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                        rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                        rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                        rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                        rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                        rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                        continue;
                    }
                    if (Style=="simple") {
                        sq(0, 1, clr);
                        continue;
                    }
                    sq(0, 1, Mix(0xFFFFFF,clr,0.1));
                    sq(0.1, 0.9, Mix(0x000000,clr,0.2));
                    sq(0.1, 0.8, clr);
                    sq(0.2, 0.65, Mix(0xFFFFFF,clr,0.2));
                    sq(0.2, 0.6, Mix(0x000000,clr,0.05));
                    sq(0.3, 0.4, Mix(0xFFFFFF,clr,0.2));
                    sq(0.35, 0.3, clr);
                    #undef sq
                    #undef rec
                }
            }
        }
        for (int d=0; d<ViewNxt; ++d) {
            Rectangle(-msz*1+10+msz*double(d*5), sz*double(LY+1)-msz*0.5, msz*4.0, msz*6.0, brd);
            if (Next.size()<=d) break;
            int cur = Next[d];
            SX=SY=0;
            if (Piece[cur][InitFacing].LY<=3) SY=1;
            if (Piece[cur][InitFacing].LY<=1) SY=2;
            for (int i=-2; i<3; ++i) {
                for (int j=0; j<5; ++j) {
                    int clr = brd;
                    if (min(2-i-SX,j-SY)>=0) clr=(Piece[cur][InitFacing].B[2-i-SX][j-SY])?Piece[cur][InitFacing].clr:brd;
                    if (clr==brd) continue;
                    #define sq(beg, ss, clr) Square(msz*double(i+d*5)+10+msz*beg,msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j)+msz*beg,msz*ss,clr)
                    #define rec(begx, begy, sx, sy, clr) Rectangle(msz*double(i+d*5)+10+msz*begx,msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j)+msz*begy,msz*sx,msz*sy,clr)
                    //Square(msz*double(i+d*5)+10, msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j), msz*0.9, Mix(0xFFFFFF,clr,0.5));
                    //Square(msz*double(i+d*5)+10, msz*0.5*double(!(Piece[cur][0].LY&1))+sz*double(LY+1)+msz*double(j), msz*0.8, clr);
                    if (Style=="classic") {
                        sq(0, 1, brd);
                        sq(0.1, 0.8, clr);
                        sq(0.2, 0.6, 0xFFFFFF);
                        sq(0.1, 0.1, 0xFFFFFF);
                        continue;
                    }
                    if (Style=="arcade") {
                        sq(0, 1, Mix(0xFFFFFF,clr,0.5));
                        sq(0.1, 0.9, Mix(0x000000,clr,0.5));
                        sq(0.1, 0.8, clr);
                        rec(0.3, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.05));
                        rec(0.4, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.1));
                        rec(0.5, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.15));
                        rec(0.6, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.2));
                        rec(0.7, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.25));
                        rec(0.8, 0.1, 0.1, 0.8, Mix(0x000000,clr,0.3));
                        continue;
                    }
                    if (Style=="simple") {
                        sq(0, 1, clr);
                        continue;
                    }
                    sq(0, 1, Mix(0xFFFFFF,clr,0.1));
                    sq(0.1, 0.9, Mix(0x000000,clr,0.2));
                    sq(0.1, 0.8, clr);
                    sq(0.2, 0.65, Mix(0xFFFFFF,clr,0.2));
                    sq(0.2, 0.6, Mix(0x000000,clr,0.05));
                    sq(0.3, 0.4, Mix(0xFFFFFF,clr,0.2));
                    sq(0.35, 0.3, clr);
                    #undef sq
                    #undef rec
                }
            }
        }
        if (RecTot>=min(DX-2,15)) {
            sprintf(buf, "-%d", RecTot);
            double asz = sz*double(LY)*0.1;
            TQu.push_back({-sz*0.1*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,6,buf,0xFF9999});
        }
        DX -= DXDel;
    }
    void PaintParticle(int tm, int tars) {
        DX += DXDel;
        ll del = clock()-begtm;
        sprintf(buf, "%d Targeting You", tars);
        if ((Plrs>2)&&(!Over)) PaintStrM(buf,sz*double(DX+1),sz*0.5*double(LY-1),sz*0.5,(tars<2)?((!tars)?0xAAAAAA:0xCCCCCC):((tars<6)?0xFFA500:0xEE0000));
        if ((Plrs>2)&&(!Over)) PaintStrM(ATKN[AtkType],sz*double(DX+2),sz*0.5*double(LY-1),sz*0.5,0xDF3782);
        int pcnt = 0;
        double rat = double(max(1,tm));
        for (int i=0; i<PQu.size(); ++i) {
            Particle o = PQu[i];
            Poly(o.x, o.y, o.sz*sz/15.0, o.n, o.clr, o.th);
            o.x+=o.vx*rat; o.y+=o.vy*rat;
            o.vx+=o.ax*rat; o.vy+=o.ay*rat;
            o.sz -= o.de*rat*0.5;
            if ((Bot)&&((sz<10)||(OperTime<5))&&(o.clr>=0)) o.sz=-1.0;
            if (o.sz>0.0) PQu[pcnt++]=o;
        }
        while (PQu.size()>pcnt) PQu.pop_back();
        int tcnt = 0;
        for (int i=0; i<TQu.size(); ++i) {
            FloatText o = TQu[i];
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
            o.bd -= o.de*rat*0.5;
            if ((Bot)&&(sz<10)&&(o.clr>=0)) o.bd=-1.0;
            if (o.bd>0.0) TQu[tcnt++]=o;
        }
        while (TQu.size()>tcnt) TQu.pop_back();
        if ((BeFrom)&&(!Over)) PaintStrM(string(1,1),sz*double(DX)*0.3,-0.15*sz*double(LY),sz*0.8*double(LY),0xDF3782,0.06);
        if ((BeTo)&&(!Over)) PaintStrM(string(1,2),sz*double(DX)*0.3,-0.15*sz*double(LY),sz*0.8*double(LY),0xFDD000,0.06);
        if (Complete) {
            double asz = sz*0.12*double(LY);
            FloatText o = FloatText({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,6,"Complete",0xCCFFCC});
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
            sprintf(buf, "Press %s to Retry", KeyName(KEY_RETRY).c_str());
            asz = sz*0.06*double(LY);
            o = FloatText({sz*0.6*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,6,buf,0xFFFFFF});
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
        }
        if (((Plrs==1)||(QuickPlay))&&(!Complete)&&(!Zen)&&(Over)) {
            double asz = sz*0.12*double(LY);
            FloatText o = FloatText({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,6,"Game Over",0xFFCCCC});
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
            sprintf(buf, "Press %s to Retry", KeyName(KEY_RETRY).c_str());
            asz = sz*0.06*double(LY);
            o = FloatText({sz*0.6*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,6,buf,0xFFFFFF});
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
        }
        DX -= DXDel;
    }
    vector<char> GetKey(int tm) {
        if ((Bot)&&((fabs(SKY-DropKY)<0.01)&&(Plrs>1))) return vector<char>();
        vector<char> res;
        for (char ch : KeyList) {
            if ((Bot)&&(ch!=KEY_RETRY)&&(ch!=KEY_UNDO)) continue;
            bool nw = CheckKey(ch);
            if (UseDas[ch]) {
                if (!KeySta[ch]) {
                    if (nw) {
                        KeySta[ch]=true; res.push_back(ch); KeyTime[ch]=0;
                    }
                }
                else {
                    if (!nw) {
                        KeySta[ch]=KeyDas[ch]=false; KeyTime[ch]=0;
                    }
                    else {
                        KeyTime[ch]+=tm; int val=(KeyDas[ch])?((ch==KEY_DOWN)?0:ARR):((ch==KEY_DOWN)?SDDAS:DAS);
                        if (KeyTime[ch]>=val) {
                            KeyTime[ch]-=val; KeyDas[ch]=true;
                            if (!DcdLeft) res.push_back(ch);
                        }
                    }
                }
                if ((nw)&&(!((ch==KEY_DOWN)?SDDAS:DAS))) KeyDas[ch]=true;
            }
            else {
                if ((nw)&&(!KeySta[ch])) res.push_back(ch);
                KeySta[ch] = nw;
            }
        }
        return res;
    }
    set<ClassSta> st; map<ClassSta,string> mp;
    bool CheckPos(ClassSta o) {
        int p=o.p, d=o.d, x=o.x, y=o.y;
        for (int i=0; i<Piece[p][d].LX; ++i) {
            for (int j=0; j<Piece[p][d].LY; ++j) {
                if ((Piece[p][d].B[i][j])&&(CheckPlace(x+i,y+j))) return false;
            }
        }
        return true;
    }
    void bfs(int p, int d, int x, int y) {
        ClassSta o = (ClassSta){p,d,x,y};
        if (!CheckPos(o)) return;
        queue<ClassSta> q; q.push(o); st.insert(o);
        while (!q.empty()) {
            o=q.front(); q.pop();
            ClassSta nw=o; --nw.x;
            if ((!st.count(nw))&&(CheckPos(nw))) {
                mp[nw] = mp[o]+KEY_DOWN;
                st.insert(nw); q.push(nw);
            }
            if ((!DropL)&&(CheckPos(nw))) continue;
            nw=o; --nw.y;
            if ((!st.count(nw))&&(CheckPos(nw))&&(AllowMove)) {
                mp[nw] = mp[o]+KEY_LEFT;
                st.insert(nw); q.push(nw);
            }
            nw=o; ++nw.y;
            if ((!st.count(nw))&&(CheckPos(nw))&&(AllowMove)) {
                mp[nw] = mp[o]+KEY_RIGHT;
                st.insert(nw); q.push(nw);
            }
            for (int i=0; i<4; ++i) {
                if (i==o.d) continue;
                int beg=o.d; if (beg&1) beg^=2;
                int en=i; if (i&1) en^=2;
                char ch = KEY_180;
                if (i==((o.d+1)&3)) ch=KEY_CW;
                if (i==((o.d+3)&3)) ch=KEY_CCW;
                if (i==((o.d+RotType)&3)) ch=KEY_ROT;
                if (!AllowRot) continue;
                if ((ch==KEY_180)&&(!AllowHalf)) continue;
                if (((ch==KEY_CW)||(ch==KEY_CCW))&&(!Allow2Rot)) continue;
                for (pair<int,int> KT : Kick[p][beg][en]) {
                    nw=o; nw.d=i; nw.x+=KT.second; nw.y+=KT.first;
                    if (CheckPos(nw)) {
                        if (!st.count(nw)) {
                            mp[nw] = mp[o]+ch;
                            st.insert(nw); q.push(nw);
                        }
                        else if (((Plr==2)||(Plr==3)||(Plr==5)||(Plr==6))&&(ch!=KEY_180)) {
                            char lst=0; if (mp[nw]!="") lst=mp[nw].back();
                            if ((lst!=KEY_CW)&&(lst!=KEY_CCW)) mp[nw]=mp[o]+ch;
                        }
                        break;
                    }
                }
            }
        }
    }
    void AddGarbage(int x, lll pos) {
        x = min(x,LX);
        if (GarbageType=="fall") {
            for (int i=1; i<=LY; ++i) {
                if (!(pos&(lll(1)<<i))) continue;
                int pp = 1;
                for (int j=1; j<=LX; ++j) {
                    if ((B[j][i])&&(!C[j][i])) pp=j+1;
                }
                int rem = x;
                for (int j=pp; j<=LX; ++j) {
                    if (!rem) break;
                    if (B[j][i]) continue;
                    B[j][i]=154; LE[j][i]=20000; --rem; ID[j][i]=++PartID;
                }
            }
            return;
        }
        LastGarb = 0;
        for (int i=LX; i>x; --i) {
            for (int j=1; j<=LY; ++j) {
                B[i][j]=B[i-x][j]; C[i][j]=C[i-x][j]; LE[i][j]=LE[i-x][j]; ID[i][j]=ID[i-x][j];
            }
        }
        for (int i=1; i<=min(x,LX); ++i) {
            ++PartID;
            for (int j=1; j<=LY; ++j) {
                C[i][j]=0; B[i][j]=154*bool(pos&(lll(1)<<j));
                if (GarbageType=="bomb") B[i][j]=(B[i][j])?153:151;
                if (GarbageType=="solid") B[i][j]=(B[i][j])?153:0;
                if (B[i][j]) LE[i][j]=20000;
                else LE[i][j]=0;
                ID[i][j] = (B[i][j])?PartID:0;
            }
        }
        for (int i=VanishHeight+1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if ((B[i][j])&&(!C[i][j])) {
                    double dx=sz*double(DX-i)+sz*0.5, dy=sz*double(j-1)+sz*0.5;
                    #define sq(beg, ss, clr) PQu.push_back({dx,dy,vx,vy,0.001,0,sz*0.5*ss,0.002,theta,4,clr})
                    double vx = -0.7+0.2*(rnd(10000)*0.0001);
                    double vy = 0.2*(rnd(10000)*0.0001-0.5);
                    double theta = acos(-1.0)*rndf();
                    int clr = Mix(Piece[B[i][j]][0].clr,0xFFFFFF,0.7);
                    sq(0, 1, clr);
                    #undef sq
                    B[i][j]=C[i][j]=LE[i][j]=ID[i][j]=0;
                }
            }
        }
    }
    int ClearGarbage(int x) {
        x = max(x,0);
        while (x) {
            bool ok = false;
            for (int i=1; i<=LY; ++i) ok|=(B[1][i]>150);
            if (!ok) break;
            for (int i=1; i<LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    B[i][j]=B[i+1][j]; C[i][j]=C[i+1][j]; LE[i][j]=LE[i+1][j]; ID[i][j]=ID[i+1][j];
                }
            }
            for (int i=1; i<=LY; ++i) B[LX][i]=C[LX][i]=LE[LX][i]=ID[LX][i]=0;
            --x;
        }
        return x;
    }
    void ClearAll(int seed, bool Over=true) {
        DropL=BaseDropL; LockL=BaseLockL; LstLev=LqC=0; WasteRem=WasteLim;
        savx=savy=tavx=tavy=-100.0; GTime=FTime=0; ClearShape.clear();
        memset(C, 0, sizeof(C));
        for (int i=1; i<=7; ++i) ED[i]=EV[i]=0;
        EcCD=BnCD=ScTm=OgTm=0; while (!Bl.empty()) Bl.pop();
        while (!Cy.empty()) Cy.pop_front();
        Complete=InChain=AllSpinGarbOper=Flipped=false; ChainLine=0;
        FloorTm=RecIncTm=0;
        Life=Stock; Tar=-1;
        DX+=DXDel; DXDel=AggTm=AggDec=LstHole=AreLeft=InitHold=InitRot=ComboRem=0;
        Level=SumCool=SumRegret=CurSeg=Seg70=Seg100=ArcadeInvis=InvisGrade=0;
        HisSeq.clear(); InvisTm=0;
        AllSpinGarb.clear(); LstAct=make_pair(-1,-1);
        for (int i=0; i<12; ++i) SegSta[i]=0;
        Grade=GradeRnk=GradeDecTm=0;
        for (int i=0; i<55; ++i) {
            ComboCol[i]=0; PieceCol[i]=false;
        }
        if (Bag.empty()) Bag=DefaultBag;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                double dx=sz*double(DX-i)+sz*0.5, dy=sz*double(j-1)+sz*0.5;
                if (B[i][j]) {
                    if (Over) {
                        #define sq(beg, ss, clr) PQu.push_back({dx,dy,vx,vy,0.001,0,sz*0.5*ss,0.002,theta,4,clr})
                        double vx = -0.7+0.2*(rnd(10000)*0.0001);
                        double vy = 0.2*(rnd(10000)*0.0001-0.5);
                        double theta = acos(-1.0)*rndf();
                        int clr = Mix(Piece[B[i][j]][0].clr,0xFFFFFF,0.7);
                        sq(0, 1, clr);
                        #undef sq
                    }
                }
                B[i][j]=C[i][j]=ID[i][j]=0;
            }
        }
        Combo=B2B=LastGarb=ComboTm=B2BTm=ComboType=B2BType=PCTime=CurFloor=0; LstReady=999;
        SumPiece=SumLine=SumAttack=SumDig=KO=SKO=0; Acc=AccRnk=AccProtect=0;
        if ((!Zen)||(QuickPlay)) Score=DisScore=0LL;
        while (Rec.size()) Rec.pop_front();
        while (ActiveGarb.size()) ActiveGarb.pop_front();
        while (Atk.size()) Atk.pop();
        gen = mt19937(seed); Next.clear(); Hold=Spin=0;
        while (Next.size()<=10) {
            if (!Sequence) {
                Next.push_back(RollPiece()); continue;
            }
            vector<int> vec;
            for (int i : Bag) vec.push_back(i);
            if (Sequence==1) {
                shuffle(vec.begin(), vec.end(), gen);
                for (int i=0; i<Ext; ++i) vec.push_back(vec[i]);
                shuffle(vec.begin(), vec.end(), gen);
            }
            for (int i : vec) Next.push_back(i);
        }
        Oper.clear();
        DropTime=0; ResetRem=max(1,ResetLim); MiniSpin=false;
        begtm = clock();
        LastGarb = GarbRise;
        if (ModDivergence==2) {
            for (int i=1; i<=min(LX,12); ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (!((i+j)&1)) B[i][j]=26;
                }
            }
        }
        else if (ModMess==2) {
            for (int i=1; i<=min(LX,12); ++i) {
                for (int j=1; j<=LY; ++j) {
                    int x=(i-1)%4, y=(j-1)%5;
                    x=min(x,4-x); y=min(y,4-y);
                    if (min(x,y)==1) B[i][j]=154;
                }
            }
        }
        else if (ModSpin==2) {
            for (int i=0; i<10; ++i) {
                LstHole = RollHole(_Luck,true);
                Rec.push_back(make_pair(1,make_pair((lll(1)<<(LY+1))-1-(lll(1)<<LstHole),0LL)));
            }
        }
        else if (ModInvisible==2) {
            for (int i=0; i<3; ++i) {
                LstHole = RollHole(_Luck,true);
                Rec.push_back(make_pair(1,make_pair((lll(1)<<(LY+1))-1-(lll(1)<<LstHole),0LL)));
            }
        }
        LstHole = RollHole(_Luck);
        for (int i=0; i<min(LX,StartHeight); ++i) {
            if (rnd(100)<_SegMess) LstHole=RollHole(_Luck);
            AddGarbage(1, RollGarb());
        }
    }
    deque<char> Oper; int D[111][55],G[111][55]; bool SetSpin=true;
    bool CheckD(int x, int y) {
        if ((min(x,y)<1)||(x>LX)||(y>LY)) return true;
        return D[x][y];
    }
    bool CheckF(int x, int y) {
        if ((min(x,y)<1)||(x>LX)||(y>LY)) return true;
        return D[x][y]==1;
    }
    bool CheckDPos(ClassSta o) {
        int p=o.p, d=o.d, x=o.x, y=o.y;
        for (pair<int,int> oo : DDP[o.p][o.d]) {
            if (CheckD(x+oo.first,y+oo.second)) return false;
        }
        return true;
    }
    void Victory() {
        double asz = sz*0.12*double(LY);
        TQu.push_back({sz*0.5*double(DX)-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.25,0.0001,"VICTORY",0xFFA500}); 
        TQu.push_back({sz*0.5*double(DX)-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.1,0.00005,"VICTORY",0xFFE211});
        sprintf(buf, "%d Points", Wins);
        TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0001,string(buf),0xFFFFFF});
        TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.1,0.00005,string(buf),0x0080FF});
    }
    double MdRate = 0.0;
    bool DV[4][111][75]; vector<ClassSta> VV; int LI=0;
    bool CheckNw(ClassSta o) {
        if (DV[o.d][o.x+10][o.y+10]) return false;
        if (o.x>LI) return false;
        return CheckDPos(o);
    }
    void Mark(ClassSta o) {
        DV[o.d][o.x+10][o.y+10]=true; VV.push_back(o);
    }
    bool Ddfs(ClassSta o) {
        stack<ClassSta> stk; stk.push(o); Mark(o);
        while (stk.size()) {
            o=stk.top(); stk.pop();
            int p=o.p, d=o.d, x=o.x, y=o.y;
            if (x>LI) continue;
            ClassSta nw=o; --o.x;
            if (CheckNw(nw)) {
                Mark(nw); stk.push(nw);
            }
            nw=o; ++o.y;
            if ((CheckNw(nw))&&(AllowMove)) {
                Mark(nw); stk.push(nw);
            }
            nw=o; --o.y;
            if ((CheckNw(nw))&&(AllowMove)) {
                Mark(nw); stk.push(nw);
            }
            for (int i=0; i<4; ++i) {
                if (i==d) continue;
                if (!AllowRot) continue;
                if ((i==((d+2)&3))&&(!AllowHalf)) continue;
                if ((i==((d+(2^RotType))&3))&&(!Allow2Rot)) continue;
                int beg=d, en=i;
                if (beg&1) beg^=2;
                if (en&1) en^=2;
                for (pair<int,int> KT : Kick[p][beg][en]) {
                    nw=o; nw.d=i; nw.x+=KT.second; nw.y+=KT.first;
                    if (CheckNw(nw)) {
                        Mark(nw); stk.push(nw);
                    }
                    if (CheckPos(nw)) break;
                }
            }
        }
        return true;
    }
    void ScreenEffect(double ss, double de, int clr, int pp=1) {
        for (int i=1; i<=DX; ++i) {
            for (int j=1; j<=LY; ++j) {
                double dx=sz*double(DX-i)+sz*rndf(), dy=sz*double(j-1)+sz*rndf();
                if (!rnd(pp)) PQu.push_back({dx,dy,0.05,0,0,0,ss,de,rndf()*acos(-1.0),6,clr});
            }
        }
    }
    void LockEff(int clr, double ss, int n, double ve) {
        double dx=sz*double(DX-avx), dy=sz*double(avy-1);
        double th = rndf()*acos(-1.0)*2.0;
        for (int i=0; i<n; ++i) {
            th += acos(-1.0)*2.0/double(n);
            PQu.push_back({dx,dy,sin(th)*ve,cos(th)*ve,0,0,ss,0.006,rndf()*acos(-1.0)*2.0,5,clr});
        }
    }
    #warning frame
    void Frame(int tm, int tars, bool PermitAI=false) {
        if (DefaultRot=="ccw") RotType=3;
        else RotType=1;
        for (int i=1; i<=7; ++i) {
            if ((i==7)&&(EV[5])&&(!EV[1])) {
                EV[i] = max(0,EV[i]-20*tm);
                continue;
            }
            EV[i] = max(0,EV[i]-tm*ED[i]);
        }
        DcdLeft = max(0,DcdLeft-tm);
        HcdLeft = max(0,HcdLeft-tm);
        DrdLeft = max(0,DrdLeft-tm);
        if (DcdLeft>5000) DcdLeft=min(DcdLeft,DCD);
        if (HcdLeft>5000) HcdLeft=min(HcdLeft,HCD);
        if ((SelX>0)&&(SelX>DXDel)&&(SelX<=DXDel+LX)&&(SelY<=LY)) {
            int x=SelX-DXDel, y=SelY;
            if ((CheckKey(VK_LBUTTON))&&(!_fstl)) {
                if (!C[x][y]) {
                    B[x][y] = AddTp;
                    LE[x][y]=10000; ID[x][y]=++PartID;
                    if (!CheckDown()) DropTime=0;
                }
            }
            if (CheckKey(VK_RBUTTON)) {
                if (!C[x][y]) {
                    if (!CheckDown()) DropTime=0;
                    B[x][y]=LE[x][y]=ID[x][y]=0;
                }
            }
        }
        else if ((SelX<0)&&(SelY<=10)&&(Zen)) {
            int oo = (11+SelX)*10+SelY;
            int dy = (oo>106)?150+oo-106:oo;
            if (CheckKey(VK_LBUTTON)) {
                if (Piece[dy][0].clr) AddTp=dy;
            }
            if (CheckKey(VK_RBUTTON)) {
                if (Piece[dy][0].clr) Next.push_front(dy);
                else Next.push_front(0);
                ++ForceWaste;
            }
        }
        if (Bot) ResetLim=max(1,ResetLim);
        UndoCD = max(0,UndoCD-tm);
        if (Bag.empty()) Bag=DefaultBag;
        if (Over) {
            begtm += ll(tm);
            vector<char> chs = GetKey(tm);
            for (char x : chs) {
                if (x==KEY_RETRY) ForceAbort=true;
                if (x==KEY_UNDO) Undo=true;
            }
            return;
        }
        if (Complete) begtm+=ll(tm);
        else if ((TarPiece)||(TarLine)||(TarAttack)||(TarScore)||(TarTime)) {
            Complete = true;
            if (clock()-begtm-BegDelay<ll(TarTime)) Complete=false;
            if (SumLine<TarLine) Complete=false;
            if (SumAttack<TarAttack) Complete=false;
            if (SumPiece<TarPiece) Complete=false;
            if (Score<ll(TarScore)) Complete=false;
        }
        int cursec = max(0,int((BegDelay-clock()+begtm+999LL)/1000LL));
        if (cursec<LstReady) {
            int asz = sz*0.28*double(LY);
            sprintf(buf,"%d",cursec); LstReady=cursec;
            if (!cursec) sprintf(buf,"GO");
            TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.3,0.0009,string(buf),0xFFFFFF});
            TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0006,string(buf),0xFDD000});
        }
        if (clock()-begtm<BegDelay) {
            Rec.clear(); ActiveGarb.clear();
            vector<char> chs = GetKey(tm);
            for (char x : chs) {
                if (x==KEY_RETRY) ForceAbort=true;
            }
            return;
        }
        if (!Arcade) {
            DropL=BaseDropL; LockL=BaseLockL;
            int lv = min(100,QueryLev());
            if (lv!=LstLev) {
                LstLev = lv;
                sprintf(buf, "Level %d", lv);
                double asz = sz*0.12*double(LY);
                TQu.push_back({sz*0.2*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0006,buf,0xFFCCCC});
            }
            if (lv) {
                if (lv>=MasterBeg) {
                    vector<int> LockR = {300,295,276,252,228,204,175,168,156,150,132,115,114,108,102,96,85,84,78,72,66,55};
                    LockL *= double(LockR[min(lv-MasterBeg,int(LockR.size())-1)])/300.0;
                    DropL = 0;
                }
                else {
                    if (LevelRule=="div") DropL/=(1.0+0.001*double(Diff)*double(lv));
                    else if (LevelRule=="dec") DropL*=max(0.0,1.0-0.001*double(Diff)*double(lv));
                    else if (LevelRule=="exp") DropL*=pow(max(0.0,1.0-0.001*double(Diff)),double(lv));
                    else DropL*=pow(max(0.0,0.8-0.001*double(Diff)*double(lv)),lv)/0.8; 
                }
            }
        }
        while ((Cy.size())&&((Cy.front().first+10000LL<clock())||(Cy.size()>8))) Cy.pop_front();
        if (Odoo) {
            if ((EV[5])&&(EV[7])&&(!EV[1])) RoundHeight=99;
            else RoundHeight=0;
        }
        else {
            for (int i=1; i<=7; ++i) EV[i]=0;
        }
        if (ForceOver) {
            while (Atk.size()) Atk.pop();
            while (Rec.size()) Rec.pop_front();
            Over=true; ForceOver=false;
            return;
        }
        if (GarbageMode=="instant") {
            int rem=GarbageGap; ll curtm=clock();
            while ((Rec.size())&&(Rec.front().second.second+ll(GarbDelay)<curtm)&&(rem)) {
                int val = min(rem,Rec.front().first);
                rem -= val;
                if (GarbRise) ActiveGarb.push_back(make_pair(val,Rec.front().second.first));
                else {
                    AddGarbage(val, Rec.front().second.first); MoveDown();
                }
                Rec.front().first-=val; if (!Rec.front().first) Rec.pop_front();
            }
        }
        int gbc = 0;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (B[i][j]>150) {
                    ++gbc; break;
                }
            }
        }
        LastGarb += tm;
        if ((gbc<StaticHeight)&&(LastGarb>GarbRise)) {
            if ((GarbageShape!="board")&&(rnd(100)<_SegMess)||(LstHole<1)||(LstHole>LY)) LstHole=RollHole(_Luck);
            AddGarbage(1, RollGarb());
            if (!GarbRise) MoveDown();
            ++gbc;
        }
        if (Arcade) {
            if ((!Zen)&&(Level==999)) Level=1000;
            if (ArcadeInvis) InvisTm+=tm;
            int lev = Level/100;
            double asz = sz*0.1*double(LY);
            if (ArcadeRound) RoundHeight=((lev&1)&&(lev>1))?10:0;
            if (lev>CurSeg) {
                if ((Seg100>RegretTm[min(int(RegretTm.size())-1,CurSeg)])&&(!Zen)) {
                    if (CurSeg<10) {
                        SegSta[CurSeg]=-1; ++SumRegret;
                    }
                    TQu.push_back({sz*0.95*double(DX+2),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.00003,"REGRET",0xEE0000});
                }
                else if (Seg70<=CoolTm[min(int(CoolTm.size())-1,CurSeg)]) {
                    if (CurSeg<10) {
                        SegSta[CurSeg]=1; ++SumCool;
                    }
                    else if (Zen) ++SumCool;
                    TQu.push_back({sz*0.95*double(DX+2),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.00003,"COOL!",0x66CCFF});
                }
                ++CurSeg; Seg70=Seg100=0;
            }
            if ((!ArcadeInvis)&&(!Zen)&&(!InvisTm)&&(Level>999)) {
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) B[i][j]=C[i][j]=LE[i][j]=0;
                }
                AreLeft = 3000;
                ArcadeInvis = ((SumCool>8)&&(Grade>=27))?2:1;
            }
            if ((InvisTm>60000)&&(ArcadeInvis)) {
                InvisGrade += (ArcadeInvis==2)?160:50;
                ArcadeInvis = 0;
                double asz = sz*0.16*double(LY);
                Complete = true;
                TQu.push_back({sz*0.5*double(DX)-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0002,"STAGE",0xFDD000}); 
                TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0002,"CLEAR",0xFDD000});
            }
            if (Level%100<70) Seg70+=tm;
            Seg100 += tm;
            lev += SumCool;
            ARE = ArcadeAre[min(int(ArcadeAre.size()-1),lev)];
            LCD = ArcadeLcd[min(int(ArcadeLcd.size()-1),lev)];
            if (!Zen) LockL=ArcadeLock[min(int(ArcadeLock.size()-1),lev)];
            DropL = 99999999;
            for (pair<int,int> o : ArcadeGrav) {
                if (Level>=o.first) {
                    if (o.second>=5120) DropL=0;
                    else DropL=12800/o.second/3;
                }
            }
            if ((InvisTm)&&(!ArcadeInvis)) {
                DropL=1000; LockL=500;
            }
        }
        if ((!AreLeft)&&(Combo<2)) GradeDecTm+=tm;
        if (GradeDecTm>GradeDec[min(int(GradeDec.size())-1,Grade)]) {
            GradeDecTm -= GradeDec[min(int(GradeDec.size())-1,Grade)];
            GradeRnk = max(0,GradeRnk-1);
        }
        if (QuickPlay) {
            ll dis = 6000LL;
            for (ll x : Floor) {
                if (Score<x) dis=min(dis,x-Score);
            }
            if (ModExpert==2) dis=6000LL;
            ll rat = max(0LL,dis-1000LL);
            GiveScore((tm*rat+4999LL)/5000LL, true);
            while (AccRnk>4000*(Acc+1)*60) {
                AccRnk-=4000*(Acc+1)*60; ++Acc;
                AccProtect = 5000;
            }
            if (!AccProtect) AccRnk=max(0,AccRnk-((ModExpert)?5:3)*tm*((Acc+1)*(Acc+1)+Acc+1));
            if ((!AccRnk)&&(Acc)) {
                --Acc; AccRnk=4000*(Acc+1)*60;
            }
            int flr = QueryFloor();
            vector<int> delay = {2500,2500,2250,2000,1750,1500,1250,1000,750,500,250};
            if (ModExpert) delay={1100,1100,1000,900,800,700,600,500,400,300,200};
            GarbDelay = delay[min(int(delay.size())-1,flr)]*2;
            if ((ModHold==2)||(ModMess==2)||(ModGravity==2)||(ModStrength==2)
            ||(ModDivergence==2)||(ModInvisible==2)||(ModSpin==2)) GarbDelay=min(GarbDelay,2500);
            if ((ModMess==2)||(ModStrength==2)||(ModDivergence==2)) GarbDelay=2500;
            DropL = int(floor(1000.0/60.0/(1.0/30.0+double(flr-1)*0.03)));
            if (ModGravity==1) {
                vector<int> lck = {30,30,29,28,27,26,24,22,20,18,16};
                DropL/=10; LockL=lck[min(flr,int(lck.size())-1)]*50/3;
            }
            if (ModGravity==2) {
                vector<int> lck = {24,24,22,20,18,16,15,14,13,12,11};
                DropL=0; LockL=lck[min(flr,int(lck.size())-1)]*50/3;
            }
            if (!Zen) {
                LockL=max(200,520-20*flr); if (ModGravity==2) LockL=LockL*2/3;
            }
            if (ModExpert==2) {
                if (FloorTm>=60000) RecIncTm+=tm;
                FloorTm += tm;
            }
        }
        EcCD = max(0,EcCD-tm);
        BnCD = max(0,BnCD-tm);
        ScTm = max(0,ScTm-tm);
        OgTm = max(0,OgTm-tm);
        if ((!EcCD)&&(min(EV[2],EV[4])>40000)&&(!EV[6])) {
            EV[2]-=40000; EV[4]-=40000;
            ++ForceWaste; EcCD=1000;
        }
        if ((!BnCD)&&(EV[1])&&(EV[5])) {
            int dd = 1;
            for (int i=2; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (CheckPlace(i,j)) dd=i;
                }
            }
            int x=rnd(dd)+1, y=rnd(LY);
            if (!C[x][y]) B[x][y]=LE[x][y]=ID[x][y]=0;
            BnCD = 500;
        }
        if ((EV[2])&&(EV[6])) {
            for (int i=0; i<256; ++i) KeyDas[i]=false;
        }
        if (ComboRule=="c2") {
            ComboRem = max(0,ComboRem-tm);
            if (!ComboRem) {
                if (ComboType) ComboTm=4000;
                Combo=ComboType=0;
                //for (int i=1; i<=LY; ++i) ComboCol[i]=0;
            }
        }
        AccProtect = max(0,AccProtect-tm);
        if (AreLeft>5000) AreLeft=min(AreLeft,max(DeathARE,max(ARE,LCD)));
        if (AreLeft) {
            AreLeft = max(0,AreLeft-tm);
            vector<char> chs = GetKey(tm);
            for (char ch : chs) {
                if ((ch==KEY_HOLD)&&(HoldRule)&&((!InitHold)||(HoldRule==2))) {
                    ++InitHold; InitRot=0; 
                }
                if (ch==KEY_RESET) InitRot=0;
                if (ch==KEY_ROT) InitRot+=RotType;
                if (ch==KEY_CW) InitRot+=1;
                if (ch==KEY_180) InitRot+=2;
                if (ch==KEY_CCW) InitRot+=3;
                InitRot &= 3;
                if ((ch==KEY_UNDO)&&(Zen)&&(!UndoCD)) Undo=true; 
                if (ch==KEY_RETRY) ForceAbort=true;
            }
            return;
        }
        if (ForceWaste) {
            bool ok = false;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        B[i][j]=C[i][j]=0; ok=true;
                    }
                }
            }
            --ForceWaste; Spin=MiniSpin=SemiSpin=false;
            Oper.clear();
        }
        if ((CheckActive())&&(ForceLock)) {
            ForceLock=false; Lock();
        }
        VisTm += tm;
        if ((ModInvisible==1)&&(VisTm>=5000)) {
            VisTm = 0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if ((B[i][j])&&(B[i][j]<=150)&&(!C[i][j])) LE[i][j]=10000;
                }
            }
        }
        int totx=0, toty=0, tot=0;
        for (int i=1; i<=LX; ++i) {
            for (int j=1; j<=LY; ++j) {
                if (C[i][j]) {
                    totx+=i; toty+=j; ++tot;
                }
            }
        }
        if (tot) {
            int avx = double(totx)/double(max(tot,1));
            int avy = double(toty)/double(max(tot,1));
            ravx = sz*double(DX-avx)+sz*0.5+KX;
            ravy = sz*double(avy-1)+sz*0.5+KY;
        }
        int ttm = ((EV[2])&&(EV[6]))?tm/5+(rnd(5)<tm%5):tm;
        if (!Bot) {
            if (!DrdLeft) DropTime+=ttm;
            if ((GTime)&&(GLockL<99999999)) GTime+=ttm;
            if (FLockL<99999999) FTime+=ttm;
        }
        else OperDis+=ttm;
        while (Next.size()<=10) {
            if (!Sequence) {
                Next.push_back(RollPiece()); continue;
            }
            vector<int> vec;
            for (int i : Bag) vec.push_back(i);
            if (Sequence==1) {
                shuffle(vec.begin(), vec.end(), gen);
                for (int i=0; i<Ext; ++i) vec.push_back(vec[i]);
                shuffle(vec.begin(), vec.end(), gen);
            }
            for (int i : vec) Next.push_back(i);
        }
        if (LastGarb<GarbRise) {
            if (CheckDown()) DropTime+=tm*DropL/max(1,GarbRise);
        }
        if (ActiveGarb.size()) {
            if (LastGarb>GarbRise) {
                AddGarbage(1, ActiveGarb.front().second);
                //MoveDown();
                if (!(--ActiveGarb.front().first)) ActiveGarb.pop_front();
                LastGarb = 0;
            }
        }
        if (!CheckActive()) {
            HoldEnable=true; int NewLines=RemoveLines();
            int Lines = NewLines+ChainLine;
            if (!NewLines) {
                InChain=false; ChainLine=0;
            }
            int CbW = 0;
            if ((ComboRule=="multipler")||(ComboRule=="aquamino")) {
                int mx = -999;
                for (int i=1; i<=LY; ++i) {
                    if (PieceCol[i]) ComboCol[i]=-4;
                    else ComboCol[i]=min(0,ComboCol[i]+1);
                }
                int mnp=LY+1, mxp=0;
                for (int i=1; i<=LY; ++i) {
                    if (ComboCol[i]<0) {
                        ++CbW; mnp=min(mnp,i); mxp=max(mxp,i);
                    }
                }
                CbW = max(CbW,mxp-mnp+1);
                if ((!Combo)||(CbW<2)||(CbW>4)||(!Lines)) CbW=0;
            }
            if (Arcade) Level+=min(6,Lines+max(0,Lines-2));
            if (ArcadeInvis) {
                int x = 0;
                if (Lines>0) x=4;
                if (Lines>1) x=8;
                if (Lines>2) x=12;
                if (Lines>3) x=26;
                if (ArcadeInvis==2) {
                    x=x*5/2; if (Lines>3) x=100;
                }
                InvisGrade += x;
            }
            else if (!InvisTm) GradeRnk+=min(4,1+Level/250)*GradeBonus[min(Lines,4)][min(int(GradeBonus[min(Lines,4)].size())-1,Grade)]*(ComboMul[min(Lines,4)][min(int(ComboMul[min(Lines,4)].size())-1,Combo)]+10);
            if (GradeRnk>=1000) {
                ++Grade; GradeRnk=0;
            }
            if ((SpinRule=="allfull")||(ModSpin)||(Odoo)) {
                if (Spin) SemiSpin=false;
            }
            else if (SpinRule=="allsemi") {
                if ((Spin)&&(Pid!=6)) SemiSpin=true; 
            }
            else if (SpinRule=="allmini") {
                if ((Spin)&&(Pid!=6)) {
                    Spin=SemiSpin=false; MiniSpin=true;
                }
                else if ((!Spin)&&(Pid!=6)) MiniSpin=false; 
            }
            else if (SpinRule=="tspin") {
                if (Pid!=6) Spin=SemiSpin=MiniSpin=false;
            }
            else if (SpinRule=="default") {
                if (Pid!=6) Spin=SemiSpin=MiniSpin=false;
                if ((Spin)&&(SemiSpin)) {
                    Spin=SemiSpin=false; MiniSpin=true;
                }
            }
            else if (SpinRule=="minionly") {
                if (Spin) {
                    Spin=SemiSpin=false; MiniSpin=true;
                }
            }
            else if (SpinRule=="none") Spin=SemiSpin=MiniSpin=false;
            if (SpinRule=="easy") {
                SemiSpin = false;
                if (MiniSpin) {
                    MiniSpin=false; Spin=true;
                }
                if ((Spin)&&(!Lines)) {
                    Spin=false; MiniSpin=true;
                } 
            }
            if ((ModHold==2)||((EV[6])&&(EV[5])&&(!EV[1]))) {
                if (Spin) {
                    MiniSpin=true; Spin=SemiSpin=false;
                }
            }
            if ((Spin)||(MiniSpin)) {
                SpinType=Pid; SpinDis=0; SpinTm=15000; SpinFull=(Spin)?((SemiSpin)?1:2):0;
                if (Flipped) SpinType=Flip[SpinType];
            }
            else if (Lines) SpinDis=1;
            if ((ModSpin==2)&&(!Spin)&&(!MiniSpin)) Lines=min(Lines,1);
            if ((ModSpin)&&((Spin)||(Lines))) {
                pair<int,int> CurAct = make_pair(((Spin)||(MiniSpin))?Pid:0,Lines);
                if (CurAct==LstAct) {
                    AllSpinGarbOper = true;
                    for (int i=0; i<((ModSpin==2)?20:1); ++i) {
                        lll gb = (lll(1)<<(LY+1))-lll(1);
                        gb &= ~(lll(1)<<RollHole(_Luck));
                        if (AllSpinGarb.size()<999) AllSpinGarb.push_back(make_pair(5+QueryFloor(),gb));
                    }
                }
                else {
                    AllSpinGarbOper = false;
                    LstAct = CurAct;
                    for (int i=0; i<AllSpinGarb.size(); ++i) --AllSpinGarb[i].first;
                    while ((!AllSpinGarb.empty())&&(AllSpinGarb.front().first<1)) {
                        AddGarbage(1,AllSpinGarb.front().second); AllSpinGarb.pop_front();
                        LastGarb = GarbRise;
                    }
                }
            }
            if (!Complete) SumLine+=Lines;
            int Attack = (Lines>1)?(1<<Lines-2):0;
            int Defence=0, Heal=0, PrevB2B=B2B;
            if (Lines>4) Attack=Lines;
            if (BaseRule=="asc") {
                if (Lines==4) --Attack;
            }
            if (BaseRule=="classic") Attack=(Lines>2)?Lines-1:0;
            if (BaseRule=="equal") Attack=Lines;
            if (BaseRule=="arcade") Attack=(Lines>2)?Lines:0;
            if (BaseRule=="none") Attack=0;
            if ((Lines)&&(Spin)) Attack=Lines*2-int(SemiSpin);
            if ((Lines>1)&&(!Spin)&&(MiniSpin)&&(Pid==6)&&(ModHold<2)&&(SpinRule!="minionly")&&(!Odoo)) Attack=Lines*2+1;
            if ((Lines)&&(tars>1)&&(TargetBonus!="none")&&(Plrs>2)&&(!QuickPlay)) {
                if ((TargetBonus!="defensive")&&(AtkType==6)) Attack+=tars*2-3;
                else if (TargetBonus!="99") Defence+=tars*2-3;
            }
            if ((!Combo)&&(Lines==1)&&(ComboRule!="none")&&(!Spin)&&(!MiniSpin)&&(QuickPlay)&&(!ModExpert)
            &&(ModHold<2)&&(ModMess<2)&&(ModGravity<2)&&(ModStrength<2)&&(ModDivergence<2)
            &&(ModInvisible<2)&&(ModSpin<2)) Attack=1;
            int ComboAttack=0, Surge=0;
            bool AC=bool(Lines), HAC=bool(Lines)&&(!Dig);
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (B[i][j]) {
                        AC=false; if (B[i][j]<=150) HAC=false;
                    }
                }
            }
            if ((ACRule!="extend")&&(ACRule!="techmino")) HAC=false;
            if (ACRule=="none") AC=false;
            int Advanced=0, Scr=0;
            if (Lines) {
                ComboRem = max(0,ComboRem+ComboBase[min(int(ComboBase.size())-1,Combo)]+Lines*ComboBonus[min(int(ComboBonus.size())-1,Combo)]);
                if (((Lines>1)||(!Arcade))&&(!InChain)) ++Combo;
                ClearType=Lines; if (NewLines) ClearTm=10000;
                ClearWType = CbW;
                if (ComboRule=="none") {
                    Combo=0; for (int i=1; i<=LY; ++i) ComboCol[i]=0;
                }
                if (Spin) ClearColor=(Flipped)?Flip[Pid]:Pid;
                else ClearColor=0;
                if ((Combo>1)||((Combo)&&(ComboRule=="c2"))) {
                    ComboType=Combo-(ComboRule!="c2"); ComboTm=10000;
                }
                vector<int> lst;
                if (ComboRule=="multipler") {
                    lst = {2,4,6,9,11};
                    if (CbW==2) lst={2,6,16,20};
                    if (CbW==3) lst={2,7,18,22};
                    if (CbW==4) lst={3,9,21,25};
                }
                if (ComboRule=="aquamino") {
                    lst = {3,6,9,12,15,18};
                    if (CbW==2) lst={3,6,11,15,19};
                    if (CbW==3) lst={3,8,15};
                    if (CbW==4) lst={3,9,18};
                }
                if (ComboRule=="io") lst={2,6,16,20};
                if (ComboRule=="default") lst={2,4,6,9,11};
                if (ComboRule=="friends") lst={2,5,5,7,12};
                if (ComboRule=="expert") lst={2,5,7,9,12};
                if (ComboRule=="battle") lst={1,3,5,7};
                if (ComboRule=="99") lst={1,3,5,7,10};
                if (ComboRule=="ppt") lst={2,4,6,8,13};
                if (ComboRule=="effect") lst={2,4,7,13};
                if (ComboRule=="zone") lst={2,4,12};
                if (ComboRule=="c2") lst={1,4,6,7,7,8,8,9,9,10};
                for (int o : lst) {
                    if (Combo>o) ++ComboAttack;
                }
                if ((ComboRule!="io")&&(ComboRule!="multipler")&&(ComboRule!="techmino")) Attack+=ComboAttack;
                if (Combo>1) LockEff(0x39C5BB,sz*0.15,3+min(35,Combo-2),0.03);
                Advanced = (Spin)||(Lines>3)||(MiniSpin)||(((AC)||(HAC))&&((ACRule=="quickplay")||(ACRule=="league")||(B2BRule=="techmino")));
                if (InChain) Advanced=false;
                if (Spin) {
                    Scr=400*(Lines+1); if (SemiSpin) Scr>>=1;
                }
                else if (MiniSpin) Scr=max(100,200*Lines);
                else if (Lines) {
                    Scr=Lines*200-100; if (Lines>3) Scr+=(Lines-3)*100;
                }
                if ((Advanced)&&(B2BRule!="none")) {
                    if (B2BRule=="techmino") {
                        if ((Spin)||(MiniSpin)) B2B=min(100,B2B+vector<int>({0,5,10,18,80,100})[min(Lines,5)]/((Spin)?1:2));
                        else if (Lines>3) B2B=min(100,B2B+vector<int>({0,0,0,0,15,20})[min(Lines,5)]);
                        if ((PCTime)&&((AC)||(HAC))) B2B=min(100,B2B+80);
                    }
                    else {
                        ++B2B; if (((AC)||(HAC))&&(ACRule=="quickplay")) ++B2B;
                    }
                    if (B2BRule=="default") B2B=min(B2B,2);
                    if (B2B>1) {
                        B2BType=B2B-1; B2BTm=10000; 
                    }
                    if ((Spin)||(Lines>3)||(MiniSpin)) {
                        if (B2BRule=="techmino") {
                            if (PrevB2B>80) {
                                Attack=max(Attack+1,Attack*3/2); ++Defence; Scr*=2;
                            }
                            else if (PrevB2B>=5) {
                                ++Attack; Scr=Scr*3/2;
                            }
                        }
                        else {
                            if (B2B>1) {
                                ++Attack; Scr=Scr*3/2;
                            }
                            if (B2BRule=="chain") {
                                if (B2B>3) ++Attack;
                                if (B2B>8) ++Attack;
                                if (B2B>24) ++Attack;
                                if (B2B>67) ++Attack;
                            }
                        }
                    }
                    int clr=0xF3BDBD;
                    if (B2B>1) clr=0xFFE211;
                    if ((B2B>4)&&(B2BRule=="surge")) clr=B2BClr(B2B-1);
                    if (B2BRule=="techmino") swap(B2B,PrevB2B);
                    LockEff(clr, (B2B>1)?sz*0.25:sz*0.15, (B2BRule=="techmino")?(2+B2B/5):(B2B>1)?(3+min(35,B2B-2)):2, 0.04);
                    if (B2BRule=="techmino") swap(B2B,PrevB2B);
                }
                else if (!InChain) {
                    if (B2BRule=="techmino") B2B=max(0,B2B-25);
                    else {
                        Surge=max(0,B2B-1); B2B=0;
                    }
                }
                Scr += (Combo-1)*50;
            }
            else {
                if (ComboRule=="c2") {
                    if (!InChain) ComboRem=max(0,ComboRem-390);
                    if (!ComboRem) {
                        if (ComboType) ComboTm=4000;
                        Combo=ComboType=0;
                        //for (int i=1; i<=LY; ++i) ComboCol[i]=0;
                    }
                }
                else if (!InChain) {
                    Combo=ComboType=0;
                    //for (int i=1; i<=LY; ++i) ComboCol[i]=0;
                }
                if (B2BRule=="techmino") {
                    if ((Spin)||(MiniSpin)) B2B=min(100,B2B+2);
                    else if (B2B>80) B2B=max(80,B2B-2);
                }
                if (Spin) {
                    if (SemiSpin) Scr=200;
                    else Scr=400;
                }
                else if (MiniSpin) Scr=100;
            }
            if ((B2BRule=="techmino")&&((PrevB2B!=B2B)||(((PrevB2B)||(B2B))&&(Lines)))) {
                B2BType=B2B; B2BTm=10000;
            }
            if ((ComboRule=="multipler")||(ComboRule=="io")||(ComboRule=="techmino")) {
                if ((Lines>1)||(ComboRule!="techmino")) Attack=max(ComboAttack,Attack*(4+min(max(0,Combo-1),(ComboRule=="techmino")?12:(((ComboRule=="io")||(CbW<2))?99999999:((CbW==2)?12:((CbW==3)?8:5)))))/4);
                else Attack=max(ComboAttack,Attack*(10+min(max(0,Combo-1),12)*3)/10);
            }
            if ((Combo>3)&&(ComboRule=="techmino")) ++Attack;
            if ((Dig)&&(Advanced)) {
                if (GarbageBonus=="default") ++Defence;
                if (GarbageBonus=="io") ++Attack;
            }
            if (Surge) {
                B2BType=0; B2BTm=10000;
            }
            if ((Surge>3)&&(B2BRule=="surge")) {
                Attack+=Surge; LockEff(0xFFFFFF,sz*0.15,15,0.2);
            }
            else if (Surge) {
                LockEff(0xFF6666,sz*0.15,3,0.04); Surge=0;
            }
            if ((AC)||(HAC)) ++PCTime;
            if (AC) {
                ScreenEffect(sz*0.1,0.005,0xFFE211,3); Scr+=3500;
                if (ACRule=="extend") {
                    Attack+=LY; Defence+=2;
                }
                else if (ACRule=="default") Attack+=LY;
                else if (ACRule=="techmino") {
                    Attack+=min(16,6+PCTime*2); Defence+=2;
                }
                else if (ACRule=="quickplay") Attack+=3;
                else if (ACRule=="league") Attack+=5;
                else if (ACRule=="99") Attack+=4;
                else if (ACRule=="arcade") Attack<<=1;
                double asz = sz*0.16*double(LY);
                TQu.push_back({sz*0.5*double(DX)-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0002,"ALL",0xFDD000}); 
                TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0002,"CLEAR",0xFDD000});
            }
            else if (HAC) {
                ScreenEffect(sz*0.05,0.005,0xFFE211,3); Scr+=2000;
                if (ACRule=="extend") {
                    int Bonus = min(LY/2,(LY+2)/3);
                    Attack+=Bonus; Heal+=min(4,LY-Bonus);
                }
                else if (ACRule=="techmino") {
                    Attack+=min(12,2+PCTime*2); Defence+=2;
                }
                double asz = sz*0.16*double(LY);
                TQu.push_back({sz*0.5*double(DX)-asz*1.5,sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0004,"HALF",0xFDD000}); 
                TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0004,"CLEAR",0xFDD000});
            }
            ll curtm = clock();
            int Mins = int((curtm-begtm)/30000LL);
            if ((Mins>=6)&&(Plrs>1)&&(!QuickPlay)) Attack=Attack*min(15,Mins)/6;
            if (BadgeBonus=="default") {
                int Bonus = 0;
                if (SKO>=2) ++Bonus;
                if (SKO>=4) ++Bonus;
                if (SKO>=8) ++Bonus;
                if (SKO>=16) ++Bonus;
                if (SKO>=32) ++Bonus;
                if (SKO>=64) ++Bonus;
                Attack += Attack*Bonus/15+(rnd(15)<(Attack*Bonus%15));
            }
            if (BadgeBonus=="99") {
                int Bonus = 0;
                if (SKO>=2) ++Bonus;
                if (SKO>=6) ++Bonus;
                if (SKO>=14) ++Bonus;
                if (SKO>=30) ++Bonus;
                Attack += Attack*Bonus/4+(rnd(4)<(Attack*Bonus%4));
            }
            if (InChain) Attack=Defence=Heal=0;
            if (!Complete) SumAttack+=Attack;
            if (SumPiece<OpenerPhrase) {
                if (OpenerBonus=="default") Defence+=Attack;
                if ((OpenerBonus=="io")&&((Attack<<1)<=ActiveGarb.size()+Rec.size())) Defence+=Attack;
            }
            if (GarbageCancel=="dig") {
                Heal+=Attack; Attack=0;
            }
            int preHeal=Heal; Heal=ClearGarbage(Heal);
            SumDig += preHeal-Heal;
            int Cancel=preHeal-Heal; Attack+=Heal;
            if ((Cancel)&&(DisAtk)) {
                sprintf(buf, "+%d", Cancel);
                double px=sz*(DX-avx), py=sz*avy, rat=min(10.0,1.0+double(Cancel-1)*0.1);
                double th=rndf()*acos(-1.0)*2.0; px+=sin(th)*sz*3.0; py+=cos(th)*sz*3.0;
                TQu.push_back((FloatText){px,py,sz*rat,0.4,0.0011/min(3.0,rat),string(buf),Mix(0x000000,0xA4FF00,0.2)});
                TQu.push_back((FloatText){px,py,sz*rat,0.3,0.001/min(3.0,rat),string(buf),0xFFFFFF});
            }
            if (ModStrength==1) Attack<<=1;
            Cancel = 0;
            while ((ActiveGarb.size())&&(Defence)&&(ModDivergence<2)&&(GarbageCancel!="none")) {
                int val=min(Defence,ActiveGarb.front().first);
                Defence-=val; ActiveGarb.front().first-=val; Cancel+=val;
                if (!ActiveGarb.front().first) ActiveGarb.pop_front();
            }
            while ((Rec.size())&&(Defence)&&(ModDivergence<2)&&(GarbageCancel!="none")) {
                int val=min(Defence,Rec.front().first); Defence-=val; Cancel+=val;
                Rec.front().first-=val; if (!Rec.front().first) Rec.pop_front();
            }
            if ((Cancel)&&(DisAtk)) {
                if (!ModExpert) AccRnk+=150*Cancel*60;
                sprintf(buf, "-%d", Cancel);
                double px=sz*(DX-avx), py=sz*avy, rat=min(10.0,1.0+double(Cancel-1)*0.1);
                double th=rndf()*acos(-1.0)*2.0; px+=sin(th)*sz*3.0; py+=cos(th)*sz*3.0;
                TQu.push_back((FloatText){px,py,sz*rat,0.4,0.0011/min(3.0,rat),string(buf),0xFAAFBE});
                TQu.push_back((FloatText){px,py,sz*rat,0.3,0.001/min(3.0,rat),string(buf),0xFFFFFF});
            }
            if ((Defence)&&(DisAtk)) {
                sprintf(buf, "-%d", Defence);
                double px=sz*(DX-avx), py=sz*avy, rat=min(10.0,1.0+double(Cancel-1)*0.1);
                double th=rndf()*acos(-1.0)*2.0; px+=sin(th)*sz*3.0; py+=cos(th)*sz*3.0;
                TQu.push_back((FloatText){px,py,sz*rat,0.1,0.00025/min(3.0,rat),string(buf),0xCCCCCC});
            }
            int E = 0;
            if (Odoo) {
                if (Lines>3) E=3;
                if ((Spin)||(MiniSpin)) {
                    if (Pid==4) {
                        for (int _=0; _<max(1,Lines); ++_) Cy.push_back(make_pair(clock(),0));
                    }
                    if (Pid==7) E=1;
                    if (Pid==2) E=2;
                    if (Pid==6) E=4;
                    if (Pid==5) E=5;
                    if (Pid==1) E=6;
                    if (Pid==3) E=7;
                }
                if (!QuickPlay) Attack>>=1;
                if ((Lines>1)||((Lines)&&(Combo>2))) Attack=max(1,Attack);
            }
            if ((E)&&(!Attack)) Atk.push(make_pair(0,E));
            Cancel = 0;
            while ((ActiveGarb.size())&&(Attack)&&(ModDivergence<2)&&(GarbageCancel!="none")) {
                int val=min(Attack,ActiveGarb.front().first);
                Attack-=val; ActiveGarb.front().first-=val; Cancel+=val;
                if (!ActiveGarb.front().first) ActiveGarb.pop_front();
            }
            while ((Rec.size())&&(Attack)&&(ModDivergence<2)&&(GarbageCancel!="none")) {
                if ((Passthrough)&&(int(curtm-Rec.front().second.second)<Passthrough)) break;
                int val=min(Attack,Rec.front().first); Attack-=val; Cancel+=val;
                Rec.front().first-=val; if (!Rec.front().first) Rec.pop_front();
            }
            if ((Cancel)&&(DisAtk)) {
                if (!ModExpert) AccRnk+=150*Cancel*60;
                sprintf(buf, "%d", Cancel);
                double px=sz*(DX-avx), py=sz*avy, rat=min(10.0,1.0+double(Cancel-1)*0.1);
                double th=rndf()*acos(-1.0)*2.0; px+=sin(th)*sz*3.0; py+=cos(th)*sz*3.0;
                int clr = 0xAAAAAA;
                if (Surge) clr=0x00FFCC;
                else if ((Spin)||(MiniSpin)) clr=Piece[Pid][0].clr;
                else if (Combo>1) clr=0x39C5BB;
                if (Odoo) {
                    clr = 0xAAAAAA;
                    if (E==1) clr=0xEE0000;
                    if (E==2) clr=0x0080FF;
                    if (E==3) clr=0x00FFCC;
                    if (E==4) clr=0xEE82EE;
                    if (E==5) clr=Mix(0x000000,0x33EE00,0.1);
                    if (E==6) clr=0x66CCFF;
                    if (E==7) clr=0xFFA500;
                }
                TQu.push_back((FloatText){px,py,sz*rat,0.4,0.0011/min(3.0,rat),string(buf),clr});
                TQu.push_back((FloatText){px,py,sz*rat,0.3,0.001/min(3.0,rat),string(buf),0xFFFFFF});
            }
            if (ModStrength==1) Attack>>=1;
            if ((Attack)&&(DisAtk)) {
                sprintf(buf, "%d", Attack);
                double px=sz*(DX-avx), py=sz*avy, rat=min(10.0,1.0+double(Attack-1)*0.1);
                double th=rndf()*acos(-1.0)*2.0; px+=sin(th)*sz*3.0; py+=cos(th)*sz*3.0;
                int clr = 0xAAAAAA;
                if (Surge) clr=0x00FFCC;
                else if ((Spin)||(MiniSpin)) clr=Piece[Pid][0].clr;
                else if (Combo>1) clr=0x39C5BB;
                if (Odoo) {
                    clr = 0xAAAAAA;
                    if (E==1) clr=0xEE0000;
                    if (E==2) clr=0x0080FF;
                    if (E==3) clr=0x00FFCC;
                    if (E==4) clr=0xEE82EE;
                    if (E==5) clr=Mix(0x000000,0x33EE00,0.1);
                    if (E==6) clr=0x66CCFF;
                    if (E==7) clr=0xFFA500;
                }
                TQu.push_back((FloatText){px,py,sz*rat,0.4,0.0011/min(3.0,rat),string(buf),(B2B>1)?0xFDD000:0xFFFFFF});
                TQu.push_back((FloatText){px,py,sz*rat,0.3,0.001/min(3.0,rat),string(buf),clr});
            }
            if (QuickPlay) {
                GiveScore(Attack*1000); AccRnk+=1050*Attack*60;
            }
            else if (!Complete) Score+=Scr*min(40,1+QueryLev());
            int Segs = (Surge)?3:1;
            if ((!QuickPlay)&&(Plrs>2)&&(AtkType==6)) Segs=max(Segs,100); 
            for (int i=Segs; i; --i) {
                if (!Attack) break;
                Atk.push(make_pair((Attack+i-1)/i,E)); Attack-=(Attack+i-1)/i;
            }
            if (((!Lines)&&(GarbageMode=="combo"))||(GarbageMode=="lock")||((!Attack)&&(GarbageMode=="attack"))) {
                int rem = GarbageGap;
                while ((Rec.size())&&(Rec.front().second.second+ll(GarbDelay)<curtm)&&(rem)) {
                    int val = min(rem,Rec.front().first);
                    rem -= val;
                    if (GarbRise) ActiveGarb.push_back(make_pair(val,Rec.front().second.first));
                    else AddGarbage(val, Rec.front().second.first);
                    Rec.front().first-=val; if (!Rec.front().first) Rec.pop_front();
                }
            }
            if (!ModExpert) {
                if (Lines>1) AccRnk+=2050*60;
                else if (Lines) AccRnk+=1050*60;
            }
            if ((NewLines)&&((ClearGravity=="sticky")||(ClearGravity=="cascade")||(ClearGravity=="separate"))) {
                InChain=true; ChainLine=Lines; AreLeft=LCD; 
            }
            else {
                while (InitHold--) {
                    if (Hold) swap(Next.front(),Hold);
                    else if (Next.size()>1) {
                        Hold=Next.front(); Next.pop_front(); 
                    }
                }
                bool suc = false;
                bool cl = bool(Lines);
                if (ClutchRule=="always") cl=true;
                if (ClutchRule=="none") cl=false;
                if (CheckSpawn(Next.front(),(InitRot+InitFacing)&3)) suc=Spawn(Next.front(),(InitRot+InitFacing)&3,cl);
                else suc=Spawn(Next.front(),InitFacing,cl);
                InitHold=InitRot=0;
                int seed = time(0);
                if (suc) {
                    Next.pop_front(); if (Zen) Storage=true;
                }
                else if (Life) {
                    while (Rec.size()) Rec.pop_front();
                    while (Bl.size()) Bl.pop();
                    while (ActiveGarb.size()) ActiveGarb.pop_front();
                    for (int i=1; i<=7; ++i) EV[i]=0;
                    --Life;
                    for (int i=1; i<=LX; ++i) {
                        for (int j=1; j<=LY; ++j) {
                            if (B[i][j]) {
                                double dx=sz*double(DX-i)+sz*0.5, dy=sz*double(j-1)+sz*0.5;
                                #define sq(beg, ss, clr) PQu.push_back({dx,dy,vx,vy,0.001,0,sz*0.5*ss,0.002,theta,4,clr})
                                double vx = -0.7+0.2*(rnd(10000)*0.0001);
                                double vy = 0.2*(rnd(10000)*0.0001-0.5);
                                double theta = acos(-1.0)*rndf();
                                int clr = Mix(Piece[B[i][j]][0].clr,0xFFFFFF,0.7);
                                sq(0, 1, clr);
                                #undef sq
                            }
                            B[i][j]=C[i][j]=LE[i][j]=0; 
                        }
                    }
                    if (Zen) Storage=true; 
                }
                else {
                    while (Atk.size()) Atk.pop();
                    while (Rec.size()) Rec.pop_front();
                    while (ActiveGarb.size()) ActiveGarb.pop_front();
                    Over = true;
                    return;
                }
                DropTime=0; ResetRem=max(1,ResetLim);
                if (!suc) return;
            }
        }
        else memset(PrePos,0,sizeof(PrePos));
        if ((Bot)&&(CheckActive())&&(Oper.empty())&&(PermitAI)) {
            ++UseAI;
            st.clear(); mp.clear();
            int fx=0, fy=0;
            for (int i=1; i<=LX; ++i) {
                for (int j=1; j<=LY; ++j) {
                    if (C[i][j]) {
                        fx=i; fy=j; break;
                    }
                }
                if (fx) break;
            }
            bfs(Pid, InitFacing, fx-Piece[Pid][InitFacing].FstX, fy-Piece[Pid][InitFacing].FstY);
            int pp = (Hold)?Hold:Next.front();
            int SX=DX-1+Piece[pp][InitFacing].SDel, SY=(LY-Piece[pp][InitFacing].LY)/2+1;
            SY = max(1,min(LY-Piece[pp][InitFacing].LY+1,SY));
            SX = max(1,min(LX,SX));
            if ((Pid!=pp)&&(HoldEnable)&&(HoldRule)) bfs(pp,InitFacing,SX,SY);
            string rstr; int MaxEval=-1000000000; ClassSta best;
            bool ee = true;
            int _stas=0, _stas2=0;
            for (ClassSta o : st) {
                if (st.count((ClassSta){o.p,o.d,o.x-1,o.y})) continue;
                ++_stas;
                int Height=0, NewHeight=0;
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        D[i][j]=((B[i][j])&&(!C[i][j]));
                        if (D[i][j]) Height=i;
                    }
                }
                NewHeight = Height;
                for (int i=0; i<Piece[o.p][o.d].LX; ++i) {
                    for (int j=0; j<Piece[o.p][o.d].LY; ++j) {
                        if (Piece[o.p][o.d].B[i][j]) {
                            D[o.x+i][o.y+j]=2; NewHeight=max(NewHeight,o.x+i);
                        }
                    }
                }
                bool sU=false, sD=false, sL=false, sR=false;
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if (D[i][j]!=2) continue;
                        if ((i==1)||(D[i-1][j]==1)) sD=true;
                        if ((i==LX)||(D[i+1][j]==1)) sU=true;
                        if ((j==1)||(D[i][j-1]==1)) sL=true;
                        if ((j==LY)||(D[i][j+1]==1)) sR=true;
                    }
                }
                #warning eval
                int Eval = 0;
                if ((Plr==2&&0)&&(Height+8<DX)) {
                    bool ff = false;
                    int mx=0, bel=1;
                    for (int j=1; j<=LY; ++j) {
                        int cnt = 0;
                        for (int i=1; i<=LX; ++i) {
                            if (!B[i][j]) ++cnt;
                        }
                        if (cnt>=mx) {
                            mx=cnt; bel=j;
                        }
                    }
                    for (int i=1; i<=LX; ++i) {
                        for (int j=1; j<=LY; ++j) {
                            if ((D[i][j]==2)&&(j==bel)) ff=true;
                        }
                    }
                    if (ff) Eval-=10;
                }
                for (int i=1; i<=LY; ++i) G[LX+1][i]=1;
                for (int i=LX; i; --i) {
                    for (int j=1; j<=LY; ++j) {
                        if (D[i][j]) G[i][j]=0;
                        else G[i][j]=G[i+1][j];
                    }
                    for (int j=2; j<=LY; ++j) {
                        if (!D[i][j]) G[i][j]|=G[i][j-1];
                    }
                    for (int j=LY-1; j; --j) {
                        if (!D[i][j]) G[i][j]|=G[i][j+1];
                    }
                }
                bool ook = false;
                if (Plr==4) {
                    int cnt = 0;
                    for (int i=1; i<=LX; ++i) {
                        bool f1=false, f2=true;
                        for (int j=1; j<=LY; ++j) {
                            if (D[i][j]==2) f1=true;
                            if (G[i][j]) f2=false;
                        }
                        if ((f1)&&(f2)) ++cnt;
                    }
                    if (cnt>3) ook=true;
                }
                int Tsc=0, Tsn=0;
                vector<int> Exist(155,0);
                for (int i=0; i<min(int(Next.size()),6); ++i) Exist[Next[i]]=max(Exist[Next[i]],6-i);
                if (Hold) Exist[Hold^Pid^o.p]=6;
                for (int i : Bag) ++Exist[i];
                if (Plr==6) {
                    for (int i=0; i<155; ++i) {
                        if (Exist[i]<4) Exist[i]=0;
                    }
                }
                int bubline=0, gbrem=5, ckli=0; bool iso=false, cel=false;
                for (int i=LX; i; --i) {
                    bool ce=false, gb=false;
                    for (int j=1; j<=LY; ++j) {
                        if (B[i][j]>150) gb=true;
                        if ((i+1<LX)&&(!D[i][j])&&(!D[i+1][j])&&(D[i+2][j])) ce=true;
                    }
                    if ((gb)&&(gbrem)) {
                        --gbrem; continue; 
                    }
                    int tt = 0;
                    for (int j=1; j<=LY; ++j) {
                        if ((D[i][j])||(!G[i][j])) ++tt;
                        if ((!D[i][j])&&(!G[i][j])) {
                            ++bubline; tt=-1; break;
                        }
                    }
                    if ((tt>=0)&&(ce)&&(iso)) ++bubline;
                    if (ce) cel=true;
                    if (tt>=LY-1) iso=true;
                    if (ce) ckli=max(ckli,i);
                }
                int c2w = 0;
                for (int i=2; i<=LX; ++i) {
                    for (int j=1; j<LY; ++j) {
                        if ((G[i][j])&&(!D[i][j])&&(!D[i][j+1])&&(!D[i-1][j])&&(!D[i-1][j+1])
                        &&(CheckD(i,j-1))&&(CheckD(i,j+2))&&(CheckD(i-1,j-1))&&(CheckD(i-1,j+2))) ++c2w;
                    }
                }
                //if (Plr==5) Eval-=2*max(0,c2w-2);
                if (ee) {
                    ee = false;
                    if (bubline<2||(Height+7<DX&&B2B)) SetSpin=true;
                    if (bubline>((Bag.size()<10)?5:5)||Height+6>=DX) SetSpin=false;
                    //SetSpin = ((Height<=10)||(bubline<3))&&(Height<=15);
                }
                if (ModSpin==2) SetSpin=true;
                //if ((Plr==6)&&(KickTable=="asc")&&(Height+10>DX)) SetSpin=false;
                int bk=0, mTsn=0, mTsc=0, cn=0, dif=0, MxSp=0;
                vector<int> IsBub(LX+1,0), Fill(LX+1,0), PFill(LX+1,0), CurV(LX+1,0), ExtScr(LX+1,0), NxtScr(LX+1,0);
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if ((!D[i][j])&&(!G[i][j])) IsBub[i]=true;
                        //if ((!SetSpin)&&(i<LX)&&(!D[i][j])&&(D[i+1][j])) IsBub[i]=true;
                        if (D[i][j]) {
                            ++Fill[i]; ++PFill[i];
                        }
                    }
                    //if ((!SetSpin)&&(i<LX)&&(IsBub[i+1])) IsBub[i]=true;
                }
                for (int j=1; j<=LY; ++j) {
                    for (int i=LX; i; --i) {
                        if (D[i][j]) break;
                        ++PFill[i];
                    }
                }
                bool Mini=true, hp=false; int nc=0;
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if (D[i][j]!=2) continue;
                        if (int(D[i-1][j]==2)+int(D[i+1][j]==2)+int(D[i][j-1]==2)+int(D[i][j+1]==2)
                        +int(D[i-1][j-1]==2)+int(D[i-1][j+1]==2)+int(D[i+1][j-1]==2)+int(D[i+1][j+1]==2)<3) continue;
                        if (int(CheckF(i-1,j-1))+int(CheckF(i+1,j-1))+int(CheckF(i-1,j+1))+int(CheckF(i+1,j+1))<3) Mini=false;
                        if (int(CheckD(i-1,j-1))+int(CheckD(i+1,j-1))+int(CheckD(i-1,j+1))+int(CheckD(i+1,j+1))<3) ++nc;
                        hp = true;
                    }
                }
                if ((!hp)||(nc>1)) Mini=false;
                if ((mp[o].empty())||((mp[o].back()!=KEY_CW)&&(mp[o].back()!=KEY_CCW))) Mini=false;
                int SpinScr=0, spid=0, ExtraScr=0;
                int Land=0, Lines=0, Ero=0, pn=0;
                for (int i=1; i<=LX; ++i) {
                    bool ok=true; int ins=0;
                    for (int j=1; j<=LY; ++j) {
                        if (!D[i][j]) ok=false;
                        if (B[i][j]==153) ok=false;
                        if (D[i][j]==2) {
                            ++ins; Land=i;
                        }
                    }
                    if (i<=RoundHeight) ok=false;
                    if (ok) {
                        ++Lines; Ero+=ins;
                    }
                    else {
                        ++pn; for (int j=1; j<=LY; ++j) D[pn][j]=D[i][j];
                    }
                }
                for (int i=1; i<155; ++i) {
                    if ((Plr!=6)||(!Exist[i])||(Height+8>DX)) continue;
                    //if (!SetSpin) continue;
                    //if ((!(sU*sD*sL*sR))&&(Lines)&&(SetSpin)) continue;
                    int CurSp=0, ImeSp=0;
                    SX=DX-1+Piece[i][InitFacing].SDel, SY=(LY-Piece[i][InitFacing].LY)/2+1;
                    SY = max(1,min(LY-Piece[i][InitFacing].LY+1,SY));
                    SX = max(1,min(LX,SX));
                    LI = Height+2;
                    SX = min(SX,LI);
                    Ddfs((ClassSta){i,InitFacing,SX,SY});
                    //VV.clear(); continue;
                    for (ClassSta vv : VV) {
                        ++_stas2; int d=vv.d, x=vv.x, y=vv.y;
                        //if (x>20) printf("p=%d x=%d y=%d d=%d\n",i,x,y,d);
                        bool ff = (!CheckDPos((ClassSta){i,d,x-1,y}))&&(!CheckDPos((ClassSta){i,d,x+1,y}))&&(!CheckDPos((ClassSta){i,d,x,y-1}))&&(!CheckDPos((ClassSta){i,d,x,y+1}));
                        if (ff) {
                            ++spid; int Cert=0, Prob=0, Tot=0;
                            for (pair<int,int> pp : DDP[i][d]) {
                                int nx = x+pp.first;
                                ++Fill[nx]; ++PFill[nx];
                                if (Fill[nx]==LY) ++Cert;
                                if (PFill[nx]==LY) ++Prob;
                                if (CurV[nx]<spid) {
                                    CurV[nx]=spid; ++Tot; //if (!IsBub[nx]) ++Prob;
                                }
                            }
                            if ((Cert)&&(!ff)) ExtraScr+=Cert*5;
                            if (!ff) Cert=Prob=0;
                            int Er=0; for (pair<int,int> pp : DDP[i][d]) Er+=int(Fill[x+pp.first]==LY);
                            int sn=0, se=0;
                            int vv = 100;//(Height+12<DX)?200:100;
                            vv = 100-5*bubline;
                            vv = max(0,vv);
                            sn = vv*Er*(Prob+Cert);
                            se = vv*Er*(Prob+Cert)/2;///4;
                            //if ((!Cert)&&(Exist[i]==7)&&(!SetSpin)) Prob=0;
                            sn = sn*max(1,Exist[i]-3)/3;
                            se *= Cert;
                            for (int j=LX; j; --j) {
                                if ((!IsBub[j])&&(CurV[j]==spid)) {
                                    ExtScr[j] = max(ExtScr[j],se/max(1,2+bubline));
                                }
                                if (Fill[j]==LY) {
                                    ExtScr[j]=max(ExtScr[j],se/max(1,5+bubline)); break;
                                }
                            }
                            CurSp = max(CurSp,sn);
                            if (Cert&&bubline<5) ImeSp=max(ImeSp,600);
                            for (pair<int,int> pp : DDP[i][d]) {
                                --Fill[x+pp.first]; --PFill[x+pp.first];
                            }
                        }
                    }
                    for (ClassSta vv : VV) DV[vv.d][vv.x+10][vv.y+10]=false;
                    VV.clear();
                    //CurSp *= (5+Exist[i])/7;
                    MxSp = max(MxSp,CurSp);
                    if (Exist[i]>=6) SpinScr+=ImeSp;
                }
                int rem = 999;
                for (int i=LX; i; --i) {
                    if (--rem<=0) break;
                    if (ExtScr[i]) {
                        SpinScr+=ExtScr[i]; rem=min(rem,(SetSpin&&Height<10)?4:2);
                    }
                }
                SpinScr += MxSp;
                SpinScr += ExtraScr;
                SpinScr = SpinScr*7/10;
                if ((Plr==6)&&(KickTable=="asc")&&(Height+10>DX)&&0) SpinScr/=2;
                if (Plr==6) {
                    for (int j=1; j<=LY; ++j) {
                        int tt = 0;
                        int bb = -999;
                        for (int i=LX; i; --i) {
                            if (D[i][j]) {
                                ++tt; if (bb<0) bb=5;
                            }
                            if ((i+5<DX)&&(!D[i][j])&&((CheckD(i+3,j-1)||(CheckD(i+3,j+1))))&&((!CheckD(i,j-1))||(!CheckD(i,j+1))||(ModSpin==2)))
                                SpinScr-=max(0,180-i*10);//((i<=15)?((i<=5)?150:100):50);
                            if ((!D[i][j])&&(!G[i][j])&&(SetSpin)) SpinScr-=max(0,bb)*tt+max(0,15-i);
                            if (bb>=0) --bb;
                        }
                    }
                }
                if (Plr==6) Eval-=bubline;
                for (int i=LX; i>=1; --i) {
                    if (Plr!=5&&Plr!=6) continue;
                    int fn=0, fg=0, bub=0, bub2=0, dii=0;
                    for (int j=1; j<=LY; ++j) {
                        fn += (D[i][j]!=0);
                        fg += (G[i][j]==0);
                        if (i<LX) bub+=((!G[i][j])&&(!D[i][j]));
                        if (i+1<LX) bub2+=((!G[i+1][j])&&(!D[i+1][j]));
                        if ((G[i][j])&&(!D[i][j])&&(CheckD(i,j-1))) ++dii;
                        //if ((!SetSpin)&&(i<LX)&&(!G[i][j])&&(!D[i][j])&&(D[i+1][j])) Eval-=2;
                    }
                    if (dii>1) dif=1;
                    if (dif) ++dif;
                    if (dif>3&&Plr==5) Eval-=1;
                    for (int j=1; j<=LY; ++j) {
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j-1))&&(!CheckD(i+1,j))&&(CheckD(i+1,j+1))&&(CheckD(i+1,j-1))&&(CheckD(i+2,j+1));
                        if (!ok) continue;
                        //if ((Height<8)&&(CheckD(i-1,j))) continue;
                        if (SetSpin) Eval-=1;
                    }
                    for (int j=1; j<=LY; ++j) {
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j+1))&&(!CheckD(i+1,j))&&(CheckD(i+1,j+1))&&(CheckD(i+1,j-1))&&(CheckD(i+2,j-1));
                        if (!ok) continue;
                        //if ((Height<8)&&(CheckD(i-1,j))) continue;
                        if (SetSpin) Eval-=1;
                    }
                    if (Plr!=5) continue;
                    if (fg>=LY-1) cn=max(cn,1);
                    if (cn) {
                        if (++cn>3) break;
                    }
                    if ((bub)&&(bub2)) continue;
                    if (i+1<ckli) continue;
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j-1))||(!CheckD(i-1,j-1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j))&&(!CheckD(i,j+1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j+1))&&(!CheckD(i+2,j+2))&&(!CheckD(i+3,j+1))&&(!CheckD(i+3,j+2));
                        if (!ok) continue;
                        if ((CheckD(i+2,j+3))&&(!CheckD(i+3,j+3))) continue;
                        int cn = int(CheckD(i+1,j+1))+int(CheckD(i+3,j))+int(CheckD(i-2,j)||CheckD(i-1,j+1));
                        if (cn==3) Tsn=max(Tsn,Exist[6]),Eval+=10;
                        if (cn==3&&fn>=LY-2) Tsc=max(Tsc,Exist[6]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j+1))||(!CheckD(i-1,j+1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j))&&(!CheckD(i,j-1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j-1))&&(!CheckD(i+2,j-2))&&(!CheckD(i+3,j-1))&&(!CheckD(i+3,j-2));
                        if (!ok) continue;
                        if ((CheckD(i+2,j-3))&&(!CheckD(i+3,j-3))) continue;
                        int cn = int(CheckD(i+1,j-1))+int(CheckD(i+3,j))+int(CheckD(i-2,j)||CheckD(i-1,j-1));
                        if (cn==3) Tsn=max(Tsn,Exist[6]),Eval+=10;
                        if (cn==3&&fn>=LY-2) Tsc=max(Tsc,Exist[6]);
                    }
                    /*for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j-1))||(!CheckD(i-1,j-1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j))&&(!CheckD(i-1,j+1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j+1))&&(!CheckD(i+2,j+2))&&(!CheckD(i+3,j+2));
                        if (!ok) continue;
                        if ((CheckD(i+2,j+3))&&(!CheckD(i+3,j+3))) continue;
                        int cn = int(CheckD(i,j+1))+int(CheckD(i+1,j+1))+int(CheckD(i+3,j)||CheckD(i+4,j))+int(CheckD(i-2,j)||CheckD(i-2,j+1));
                        if (cn==4) Tsn=max(Tsn,Exist[3]),Eval+=0;
                        if (cn==4&&fn>=LY-1) Tsc=max(Tsc,Exist[3]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j+1))||(!CheckD(i-1,j+1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j))&&(!CheckD(i-1,j-1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j-1))&&(!CheckD(i+2,j-2))&&(!CheckD(i+3,j-2));
                        if (!ok) continue;
                        if ((CheckD(i+2,j-3))&&(!CheckD(i+3,j-3))) continue;
                        int cn = int(CheckD(i,j-1))+int(CheckD(i+1,j-1))+int(CheckD(i+3,j)||CheckD(i+4,j))+int(CheckD(i-2,j)||CheckD(i-2,j-1));
                        if (cn==4) Tsn=max(Tsn,Exist[2]),Eval+=0;
                        if (cn==4&&fn>=LY-1) Tsc=max(Tsc,Exist[2]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j+1))||(!CheckD(i-1,j+1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j+1))&&(!CheckD(i,j+1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j+1))&&(!CheckD(i+3,j+2))&&(!CheckD(i+3,j+1));
                        if (!ok) continue;
                        int cn = int(CheckD(i+1,j+1))+int(CheckD(i+3,j)||CheckD(i+4,j))+int(CheckD(i-2,j+1)||CheckD(i-1,j));
                        if (cn==3) Tsn=max(Tsn,Exist[5]);
                        if (cn==3&&fn>=LY-2) Tsc=max(Tsc,Exist[5]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        if ((!CheckD(i+1,j+1))||(!CheckD(i-1,j+1))) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i-1,j-1))&&(!CheckD(i,j-1));
                        if (!ok) continue;
                        ok = (!CheckD(i+2,j))&&(!CheckD(i+2,j-1))&&(!CheckD(i+3,j-2))&&(!CheckD(i+3,j-1));
                        if (!ok) continue;
                        int cn = int(CheckD(i+1,j-1))+int(CheckD(i+3,j)||CheckD(i+4,j))+int(CheckD(i-2,j-1)||CheckD(i-1,j));
                        if (cn==3) Tsn=max(Tsn,Exist[7]);
                        if (cn==3&&fn>=LY-2) Tsc=max(Tsc,Exist[7]);
                    }*/
                    if (i<ckli) continue;
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i,j+1))&&(!CheckD(i-1,j+1));
                        if (!ok) continue;
                        //if ((!CheckD(i,j+2))&&(!CheckD(i-1,j+2))) continue;
                        int cn = int(CheckD(i+1,j+1))+int(CheckD(i+2,j+2))+int(CheckD(i-2,j+1)||CheckD(i-1,j));
                        if ((CheckD(i+2,j))||(CheckD(i+2,j+1))||(CheckD(i+3,j+1))||(CheckD(i+3,j+2))) continue;
                        if (cn==3) Tsn=max(Tsn,Exist[5]);
                        if (cn==3&&fn>=LY-3) Tsc=max(Tsc,Exist[5]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i,j-1))&&(!CheckD(i-1,j-1));
                        if (!ok) continue;
                        //if ((!CheckD(i,j-2))&&(!CheckD(i-1,j-2))) continue;
                        int cn = int(CheckD(i+1,j-1))+int(CheckD(i+2,j-2))+int(CheckD(i-2,j-1)||CheckD(i-1,j));
                        if ((CheckD(i+2,j))||(CheckD(i+2,j-1))||(CheckD(i+3,j-1))||(CheckD(i+3,j-2))) continue;
                        if (cn==3) Tsn=max(Tsn,Exist[7]);
                        if (cn==3&&fn>=LY-3) Tsc=max(Tsc,Exist[7]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i+1,j-1))&&(!CheckD(i+1,j-2))&&(!CheckD(i+1,j-1))&&(CheckD(i+2,j));
                        if (!ok) continue;
                        if ((!CheckD(i+2,j-3))||(!CheckD(i+1,j-3))) continue;
                        int cn = int(CheckD(i,j-1))+int(CheckD(i,j-2))+int(CheckD(i+2,j));
                        if (cn==3) Tsn=max(Tsn,Exist[2]);
                        if (cn==3&&fn>=LY-3) Tsc=max(Tsc,Exist[2]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i+1,j+1))&&(!CheckD(i+1,j+2))&&(!CheckD(i+1,j+1))&&(CheckD(i+2,j));
                        if (!ok) continue;
                        if ((!CheckD(i+2,j+3))||(!CheckD(i+1,j+3))) continue;
                        int cn = int(CheckD(i,j+1))+int(CheckD(i,j+2))+int(CheckD(i+2,j));
                        if (cn==3) Tsn=max(Tsn,Exist[3]);
                        if (cn==3&&fn>=LY-3) Tsc=max(Tsc,Exist[3]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j))&&(!CheckD(i+2,j))&&(!CheckD(i+1,j-1))&&(!CheckD(i+1,j+1));
                        if (!ok) continue;
                        int cn = int(CheckD(i+2,j+1))+int(CheckD(i,j+1))+int(CheckD(i+2,j-1))+int(CheckD(i,j-1));
                        //if (CheckD(i+2,j-1)&&CheckD(i+2,j+1)) continue;
                        if (cn==3) Tsn=max(Tsn,Exist[6]);
                        if (cn==3&&fn>=LY-3) Tsc=max(Tsc,Exist[6]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i+1,j+1))&&(!CheckD(i,j-1))&&(!CheckD(i+2,j));
                        if (!ok) continue;
                        if ((CheckD(i+2,j-1))&&((!CheckD(i+2,j-1))||(!CheckD(i+2,j+2)||(CheckD(i+2,j+1))))) continue;
                        int cn = int(CheckD(i,j+1))+int(CheckD(i+1,j-1));
                        if (cn==2) Tsn=max(Tsn,Exist[5]);
                        if (cn==2&&fn>=LY-2) Tsc=max(Tsc,Exist[5]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i+1,j))&&(!CheckD(i+1,j-1))&&(!CheckD(i,j+1))&&(!CheckD(i+2,j));
                        if (!ok) continue;
                        if ((CheckD(i+2,j+1))&&((!CheckD(i+2,j+1))||(!CheckD(i+2,j-2)||(CheckD(i+2,j-1))))) continue;
                        int cn = int(CheckD(i,j-1))+int(CheckD(i+1,j+1));
                        if (cn==2) Tsn=max(Tsn,Exist[7]);
                        if (cn==2&&fn>=LY-2) Tsc=max(Tsc,Exist[7]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j-1))&&(!CheckD(i,j+1))&&(!CheckD(i+1,j-1));
                        if (!ok) continue;
                        //if ((!CheckD(i-1,j))&&(!CheckD(i-1,j-1))&&(!CheckD(i-1,j+1))&&(!CheckD(i-2,j+1))) continue;
                        int cn = int(CheckD(i+1,j))+int(CheckD(i+1,j+1));
                        if (cn==2) Tsn=max(Tsn,Exist[2]);
                        if (cn==2&&fn>=LY-3) Tsc=max(Tsc,Exist[2]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j-1))&&(!CheckD(i,j+1))&&(!CheckD(i+1,j+1));
                        if (!ok) continue;
                        //if ((!CheckD(i-1,j))&&(!CheckD(i-1,j-1))&&(!CheckD(i-1,j+1))&&(!CheckD(i-2,j-1))) continue;
                        int cn = int(CheckD(i+1,j))+int(CheckD(i+1,j-1));
                        if (cn==2) Tsn=max(Tsn,Exist[3]);
                        if (cn==2&&fn>=LY-3) Tsc=max(Tsc,Exist[3]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j-1))&&(!CheckD(i+1,j))&&(!CheckD(i+2,j))&&(!CheckD(i+2,j+1))&&(CheckD(i+1,j+1));
                        if (!ok) continue;
                        if ((!CheckD(i-1,j))&&(!CheckD(i-1,j-1))) continue;
                        int cn = int(CheckD(i+1,j-1))+int(CheckD(i-1,j));
                        if (cn==2) Tsn=max(Tsn,Exist[2]);
                        if (cn==2&&fn>=LY-2) Tsc=max(Tsc,Exist[2]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j+1))&&(!CheckD(i+1,j))&&(!CheckD(i+2,j))&&(!CheckD(i+2,j-1))&&(CheckD(i+1,j-1));
                        if (!ok) continue;
                        if ((!CheckD(i-1,j))&&(!CheckD(i-1,j+1))) continue;
                        int cn = int(CheckD(i+1,j+1))+int(CheckD(i-1,j));
                        if (cn==2) Tsn=max(Tsn,Exist[3]);
                        if (cn==2&&fn>=LY-2) Tsc=max(Tsc,Exist[3]);
                    }
                    for (int j=1; j<=LY; ++j) {
                        if (bub) continue;
                        if (!G[i][j]) continue;
                        bool ok = (!CheckD(i,j))&&(!CheckD(i,j+1))&&(!CheckD(i,j+2))&&(!CheckD(i,j+3));
                        if (!ok) continue;
                        if ((!CheckD(i,j-1))||(!CheckD(i,j+4))) continue;
                        if ((!CheckD(i+1,j))&&(!CheckD(i+1,j+1))&&(!CheckD(i+1,j+2))&&(!CheckD(i+1,j+3))) continue;
                        if ((!CheckD(i-1,j))&&(!CheckD(i-1,j+1))&&(!CheckD(i-1,j+2))&&(!CheckD(i-1,j+3))) continue;
                        if ((CheckD(i+1,j))&&(CheckD(i+1,j+3))&&(CheckD(i-1,j))&&(CheckD(i-1,j+1))&&(CheckD(i-1,j+2))&&(CheckD(i-1,j+3))) continue;
                        int tot = ((CheckD(i-1,j))||(CheckD(i+1,j)))+((CheckD(i-1,j+1))||(CheckD(i+1,j+1)))+((CheckD(i-1,j+2))||(CheckD(i+1,j+2)))+((CheckD(i-1,j+3))||(CheckD(i+1,j+3)));
                        if (tot<4) continue;
                        Tsn=max(Tsn,Exist[1]);
                        if (fn>=LY-4) Tsc=max(Tsc,Exist[1]);
                    }
                    if ((Plr==5)&&(Tsn)&&(Height+8<DX)&&(SetSpin)) Eval+=((bubline>2)?0:2);
                    mTsn=max(mTsn,Tsn); mTsc=max(mTsc,Tsc);
                    Tsn=Tsc=0;
                }
                if ((Plr==5)&&(mTsn)&&(Height+8<DX)&&(SetSpin)) Eval+=10;
                if ((Plr==5)&&(mTsc>=6)&&(Height+8<DX)) Eval+=10;
                if ((Plr==6)&&(SetSpin)) {
                    for (int i=1; i<=LX; ++i) {
                        int tot = 0;
                        for (int j=2; j<LY; ++j) {
                            if (D[i][j]) ++tot;
                        }
                        if (tot==LY-2) Eval-=2;
                    }
                }
                bool Alt = ((Plr==2||Plr==3)&&(Height+8<DX));
                int GarC = 0;
                for (int i=1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if (B[i][j]>150) {
                            ++GarC; break;
                        }
                    }
                }
                //if (GarC>5) Alt=false;
                for (int i=pn+1; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) D[i][j]=0;
                }
                Eval += Ero*Lines-Land;
                if (!SetSpin&&Plr==6) Eval-=NewHeight-Lines;
                for (int i=1; i<=LY; ++i) D[0][i]=1;
                for (int i=1; i<=LX; ++i) D[i][0]=D[i][LY+1]=1;
                int Bubble=0, Float=0;
                for (int i=2; i<=LX; ++i) {
                    for (int j=1; j<=LY; ++j) {
                        if ((D[i][j])&&(!D[i][j-1])&&(!G[i][j-1])) ++Bubble;
                        if ((D[i][j]==2)&&(!D[i][j-1]&&!D[i][j+1])&&(!D[i-1][j])) ++Float;
                    }
                }
                //if (Plr==5&&sU*sD*sL*sR&&(o.p==2||o.p==3)&&!SetSpin) Eval-=10*Float;
                if ((Plr==3)&&(Height+12<DX)) Eval-=Bubble;
                if ((Height+6<DX)&&((Lines)&&(Lines<4))&&(!sU*sD*sL*sR)&&(Combo<1)&&(Plr==4)&&(!ook)) Eval-=30;
                if (((sU*sD*sL*sR)&&((Lines)||(!SetSpin)))||(Lines>=4)) Eval+=Ero*Lines*((Combo)?5:5),SpinScr+=((SetSpin)?100:50)*Lines;//5;
                else if ((Mini)&&(Lines)) Eval+=Ero*Lines*0;
                else if (((Plr==2)||(Plr==3)||(Plr==5)||(Plr==6))&&(Combo<=2||Plr==6)&&(Lines)) {
                    if (Combo<2||((Plr==6))) {
                        //if (Height+12<DX) Eval-=Ero*Lines/2;
                        //if (Plr==5) Bubble=false;
                        if (Height+12<DX) Eval-=Ero*Lines/((Bubble)?2:1);
                    }
                }
                if ((Height+12<DX)&&(Plr==6)&&(Combo<=3)&&(Lines)&&(Lines<4)&&(!(sU*sD*sL*sR))) Eval-=Ero*((SetSpin)?4:2);
                if ((SetSpin)&&(Lines==1)&&(!(sU*sD*sL*sR))&&(Ero==1)&&((o.p==1)||(o.p==4)||(o.p==5)||(o.p==7))) Eval-=3;
                pair<int,int> Act = make_pair(0,Lines);
                if ((ModSpin==2)&&(Lines)&&(!Mini)&&(!(sU*sD*sL*sR))) Act.second=1;
                if ((sU*sD*sL*sR)||(Mini)) Act.first=o.p;
                if ((ModSpin)&&(Act!=make_pair(0,0))&&(Act==LstAct)) Eval=-99999999;
                for (int i=1; i<=LY; ++i) D[0][i]=3;
                int BRC = 2;//(GarC<2)?5:1;
                if (Plr==5) BRC=(SetSpin)?0:0;
                if (Bubble) BRC=1;
                if (Bubble>1) BRC=0;
                if (Plr==2) BRC=1;
                int BRem=BRC, LstIso=0;
                for (int i=LX; i; --i) {
                    D[i][0]=D[i][LY+1]=3;
                    int UseB=0, Tot=0; bool Iso=false; int Sep=0;
                    for (int j=1; j<=LY; ++j) {
                        if ((!D[i][j])&&(D[i+1][j])&&(!G[i][j])) BRem=0;
                        if (D[i][j]) ++Tot;
                        if ((!D[i][j])&&((j==1)||(D[i][j-1]))&&((j==LY)||(D[i][j+1]))) Iso=true;
                        if ((!D[i][j])&&((j==1)||(D[i][j-1]))) ++Sep;
                    }
                    if (Tot+2>LY) BRem=0;
                    for (int j=1; j<=LY; ++j) {
                        if ((!D[i][j])&&(D[i+1][j])) {
                            if ((G[i][j])&&(Alt)&&((i<2)||(D[i-1][j]))&&(BRem)) ++UseB;
                            Eval -= 4;
                        }
                        if (bool(D[i][j])!=bool(D[i-1][j])) --Eval;
                        if (bool(D[i][j])!=bool(D[i][j-1])) --Eval;
                        if ((!D[i][j])&&((D[i][j+1])&&(D[i][j-1]))) Eval-=1;
                    }
                    if ((Iso)&&(LstIso)&&(Alt)&&(Plr==3)) Eval-=((BRC)?3:1);
                    LstIso = Iso;
                    if (UseB==1) Eval+=12;
                    if (UseB>1) BRem=0;
                    if (!D[i][LY]) --Eval;
                    if (UseB) --BRem;
                    if ((Iso)||(Sep>1)) BRem=0;
                    if ((!UseB)&&(BRem<BRC)) BRem=0;
                }
                int gpos=0, ghei=0;
                for (int i=1; i<=LX; ++i) {
                    int emp=0, bub=0;
                    for (int j=1; j<=LY; ++j) {
                        if (!D[i][j]) {
                            ++emp; bub=j;
                        }
                    }
                    if (emp==1) {
                        gpos=bub; ghei=i;
                    }
                    else break;
                }
                if ((Plr)&&(gpos)) {
                    int he=LX; while ((he)&&(!D[he][gpos])) --he;
                    Eval -= min(0,he-ghei);
                }
                Eval *= 100;
                Eval += SpinScr;//*85/100;
                Eval += 10*abs(fy-Piece[Pid][0].FstY-o.y);
                Eval += (fy-Piece[Pid][0].FstY>o.y);
                if (Eval>MaxEval) {
                    MaxEval=Eval; rstr=mp[o]; best=o;
                }
            }
            //printf("%d %d (%d)\n",_stas,_stas2,_stas2/max(1,_stas));
            Oper.clear(); if (best.p!=Pid) Oper.push_back(KEY_HOLD);
            for (char ch : rstr) Oper.push_back(ch);
            if ((Oper.size())&&(double(rnd(1<<30)+1)/double(1<<30)<MdRate)) {
                int type = rnd(3);
                if (!type) {
                    deque<char> NwOper;
                    for(char c:Oper) if(rng()&1) NwOper.push_back(c);
                    Oper = NwOper;
                }
                else if (type==1) Oper.resize(rnd(Oper.size()));
                else shuffle(Oper.begin(),Oper.end(),rng);
            }
            Oper.push_back(0);
            DivOperTime = OperTime/Oper.size();
            //printf("*%d %d %d %d\n",best.p,best.d,best.x,best.y);
        }
        vector<char> chs = GetKey(tm);
        if ((Oper.size())&&(OperDis>=(((OperTime>=300)||(Arcade))?DivOperTime:OperTime))) {
            while (Oper.size()) {
                chs.push_back(Oper.front()); Oper.pop_front();
                if ((OperTime>=300)||(Arcade)) break;
            }
            OperDis = 0;
            /*bool tp = (Oper.front()==KEY_DOWN);
            chs.push_back(Oper.front()); Oper.pop_front();
            if (tp) {
                while ((Oper.size())&&(Oper.front()==KEY_DOWN)) {
                    chs.push_back(Oper.front()); Oper.pop_front();
                }
            }*/
        }
        if (CheckActive()) {
            bool ckd = CheckDown();
            bool rsl=false, ru=false;
            for (char ch : chs) {
                if ((ch==KEY_LEFT)&&(AllowMove)) {
                    rsl|=MoveLeft();
                    if ((!ARR)&&(!Bot)&&(KeyDas[ch])) {
                        if (((!SDARR)&&(KeyDas[KEY_DOWN])&&(AllowSoft))||(!DropL)) {
                            bool ok = false;
                            while (MoveDown()) {
                                Score+=((!QuickPlay)&&(!Complete)); ok=true;
                            }
                            if ((ok)&&(ResetRem>0)) DropTime=0;
                        }
                        while (MoveLeft()) {
                            if (((!SDARR)&&(KeyDas[KEY_DOWN])&&(AllowSoft))||(!DropL)) {
                                bool ok = false;
                                while (MoveDown()) {
                                    Score+=((!QuickPlay)&&(!Complete)); ok=true;
                                }
                                if ((ok)&&(ResetRem>0)) DropTime=0;
                            }
                        }
                    }
                }
                if ((ch==KEY_RIGHT)&&(AllowMove)) {
                    rsl|=MoveRight();
                    if ((!ARR)&&(!Bot)&&(KeyDas[ch])) {
                        if ((((!SDARR)&&(KeyDas[KEY_DOWN])&&(AllowSoft))||(!DropL))) {
                            bool ok = false;
                            while (MoveDown()) {
                                Score+=((!QuickPlay)&&(!Complete)); ok=true;
                            }
                            if ((ok)&&(ResetRem>0)) DropTime=0;
                        }
                        while (MoveRight()) {
                            if ((((!SDARR)&&(KeyDas[KEY_DOWN])&&(AllowSoft))||(!DropL))) {
                                bool ok = false;
                                while (MoveDown()) {
                                    Score+=((!QuickPlay)&&(!Complete)); ok=true;
                                }
                                if ((ok)&&(ResetRem>0)) DropTime=0;
                            }
                        }
                    }
                }
                if ((ch==KEY_CW)&&(AllowRot)&&(Allow2Rot)) rsl|=Rotate((Dir+1)&3);
                if ((ch==KEY_CCW)&&(AllowRot)&&(Allow2Rot)) rsl|=Rotate((Dir+3)&3);
                if ((ch==KEY_180)&&(AllowRot)&&(AllowHalf)) rsl|=Rotate((Dir+2)&3);
                if ((ch==KEY_FLIP)&&(Flip[Pid])&&(AllowFlip)) rsl|=Rotate((Dir+2)&3,Flip[Pid]);
                if ((ch==KEY_WASTE)&&((Zen)||(WasteRem))) {
                    ForceWaste=true;
                    if ((!Zen)&&(WasteRem<99999999)) {
                        --WasteRem;
                        sprintf(buf, "%d", WasteRem);
                        double asz = sz*double(LY)*0.1;
                        TQu.push_back({sz*0.5*double(DX),sz*0.5*double(LY)-asz*0.7,asz,0.2,0.0006,buf,0xFFFFFF});
                    }
                }
                if ((ch==KEY_LOCK)&&(AllowLock)) Lock();
                if ((ch==KEY_ROT)&&(AllowRot)) rsl|=Rotate((Dir+RotType)&3);
                if ((ch==KEY_DOWN)&&(AllowSoft)) {
                    if ((KeyDas[KEY_DOWN])&&(!Bot)) {
                        if (ckd) {
                            if (SDARR) DropTime+=DropL*double(tm)/double(SDARR);
                            else {
                                bool ok = false;
                                while (CheckDown()) {
                                    MoveDown(); Score+=((!QuickPlay)&&(!Complete)); ok=true;
                                }
                                if ((ok)&&(ResetRem>0)) DropTime=0;
                            }
                        }
                    }
                    else {
                        if (MoveDown()) {
                            Score+=((!QuickPlay)&&(!Complete));
                            if ((ResetRem>0)||(!ResetLim)) DropTime=0;
                        }
                        else if ((AllowDeep)&&(!Bot)) rsl|=DeepDrop();
                    }
                }
                if ((ch==KEY_UP)&&(AllowUp)) {
                    bool tmp = MoveUp();
                    rsl|=tmp; ru|=tmp;
                }
                if ((ch==KEY_SONIC)&&(AllowSonic)) {
                    while (CheckDown()) {
                        MoveDown(); Score+=((!QuickPlay)&&(!Complete));
                    }
                    if ((!ResetLim)||(ResetRem)) DropTime=0;
                }
                if (((ch==KEY_HARD)&&((Bot)||(AllowHard)))||(!ch)) {
                    if ((Bot)||(((!EV[2])||(!EV[6]))&&(!HcdLeft))) HardDrop();
                }
                if (ch==KEY_HOLD) {
                    if ((!HoldEnable)||(!HoldRule)) continue;
                    int pid = Pid;
                    if (Hold) {
                        if (Spawn(Hold,InitFacing)) {
                            Hold = pid;
                            if (HoldRule==1) HoldEnable=false;
                            DropTime=0; ResetRem=max(1,ResetLim);
                        }
                    }
                    else if (Next.size()>1) {
                        if (Spawn(Next.front(),InitFacing)) {
                            Hold=pid; Next.pop_front();
                            if (HoldRule==1) HoldEnable=false;
                            DropTime=0; ResetRem=max(1,ResetLim);
                        }
                    }
                }
                if ((ch==KEY_RESET)&&(HoldRule==2)) {
                    if (Spawn(Pid,InitFacing)) {
                        DropTime=0; ResetRem=max(1,ResetLim);
                    }
                }
                if (ch==KEY_EVEN) AtkType=1;
                if (ch==KEY_KO) AtkType=2;
                if (ch==KEY_RANDOM) AtkType=3;
                if (ch==KEY_PAYBACK) AtkType=4;
                if (ch==KEY_BADGE) AtkType=5;
                if (ch==KEY_ATTACKERS) AtkType=6;
                if ((ch==KEY_UNDO)&&(Zen)&&(!UndoCD)) Undo=true;
                if (ch==KEY_RETRY) ForceAbort=true;
            }
            if ((CheckActive())&&(Bot)&&(!DropL)) {
                while (MoveDown());
            }
            if ((CheckActive())&&(!Bot)) {
                bool nckd = CheckDown();
                if (((ckd)&&(nckd))&&(!ru)) rsl=false;
                if ((DropTime)&&(rsl)&&(ResetRem>0)) {
                    if (ResetLim) DropTime=0;
                    if (!ResetDec) ResetRem=max(0,ResetRem-1);
                }
                if (ResetDec) ResetDec=false;
                if (nckd) {
                    if (!DropL) {
                        bool ok = false;
                        while (CheckDown()) {
                            MoveDown(); ok=true; if (KeyDas[KEY_DOWN]) Score+=((!QuickPlay)&&(!Complete));
                        }
                        if (ResetRem>0) DropTime=0;
                    }
                    else if (DropTime>=DropL) {
                        while (DropTime>=DropL) {
                            if (!CheckDown()) {
                                if (ResetRem>0) DropTime=0;
                                break;
                            }
                            if (ResetRem>0) DropTime-=DropL;
                            if (MoveDown()) {
                                if (KeyDas[KEY_DOWN]) Score+=((!QuickPlay)&&(!Complete));
                            }
                        }
                        if (ResetRem>0) {
                            if (CheckDown()) DropTime%=DropL;
                            else DropTime=0;
                        }
                    }
                }
                else if ((DropTime>LockL)&&(!Bot)) Lock();
            }
            if (!CheckDown()) GTime=max(1,GTime);
            if ((GTime>GLockL)||(FTime>FLockL)) HardDrop();
        }
    }
    string KeyName(char ch) {
        if ((ch>='a')&&(ch<='z')) return string("")+char(ch+'A'-'a');
        if ((ch>='A')&&(ch<='Z')) return string("")+char(ch);
        if (ch==VK_UP) return "Up";
        if (ch==VK_DOWN) return "Down";
        if (ch==VK_LEFT) return "Left";
        if (ch==VK_RIGHT) return "Tight";
        if (ch==VK_SHIFT) return "Shift";
        if (ch==VK_SPACE) return "Space";
        if (ch==VK_TAB) return "Tab";
        if (ch==VK_RETURN) return "Enter";
        if (ch==VK_CAPITAL) return "Caps";
        if (ch==VK_CONTROL) return "Ctrl";
        return "none";
    }
    vector<string> GetHint(string Command) {
        if (Command=="") return {};
        while ((Command.size())&&(Command.back())) Command.pop_back();
        string cur=""; vector<string> Co; 
        for (char ch : Command) {
            if (ch) cur.push_back(ch);
            else {
                Co.push_back(cur); cur="";
            }
        }
        if (cur.size()) Co.push_back(cur);
        int pp = 0;
        for (int i=0; i<Co.size(); ++i) {
            if ((Co[i]=="forall")||(Co[i]=="run")) pp=i+1;
        }
        if ((Co.size())&&(!pp)&&(Co[0]=="for")) {
            return {"[X] e [x] - Select players satisfying their [X] equal to x",
            "[X] ne [x] - Select players satisfying their [X] unequal to x",
            "[X] g [x] - Select players satisfying their [X] greater than x",
            "[X] l [x] - Select players satisfying their [X] less than x",
            "[X] ge [x] - Select players satisfying their [X] not less than x",
            "[X] le [x] - Select players satisfying their [X] not greater than x",
            "pick [x] - Pick the first [x] players",
            "sort [X] - Sort current list by ascending order of [X]",
            "rsort [X] - Sort current list by descending order of [X]",
            "shuffle - Random shuffle the current list"};
        }
        vector<string> ChangeList = {"complete - does goal completed",
        "levelstart - start level calculated as max",
        "levelbase - base level of level calculation",
        "levelline - line cleared per level",
        "leveltime - time per level",
        "levelpiece - piece per level",
        "levelattack - attack per level",
        "increaseline - increasing line cleared required per level",
        "increasetime - increasing time required per level",
        "increasepiece - increasing piece required per level",
        "increaseattack - increasing attack required per level",
        "levelmaster - begin level of 20g",
        "levelratio - difficulty scale of level",
        "targetpiece - goal pieces",
        "targettime - goal time",
        "targetline - goal cleared lines",
        "targetattack - goal attack points",
        "targetscore - goal score",
        "sumpiece - number of placed pieces",
        "sumline - number of cleared lines",
        "sumdig - number of cleared garbage lines",
        "sumattack - number of total attack points",
        "staticheight - height of auto filled garbage lines",
        "startheight - height of starting garbage lines",
        "usemove - allow moving",
        "userotate - allow rotation",
        "use2rotate - allow two direct rotation",
        "usehalf - allow half rotation",
        "usehard - allow hard drop",
        "usesoft - allow soft drop",
        "usesonic - allow sonic drop",
        "useflip - allow flip operation",
        "useup - allow moving up",
        "uselock - allow lock in place",
        "usedeep - allow deep drop",
        "wastelimit - allow waste operations in one game",
        "holdpiece - holding piece",
        "pid - active piece",
        "tar - target of attack",
        "attacktype - targeting style",
        "passthrough - passthrough delay",
        "bot - does the player controlled by cpu",
        "bottype - algorithm of cpu control",
        "point - number of victory rounds",
        "height - displaying height of board",
        "realheight - real height of board",
        "vanish - height of vanish zone",
        "width - width of board",
        "ko - knockouts",
        "badge - badges from knockout",
        "botspeed - the operating distance of cpu",
        "over - does the game be over",
        "next - next piece",
        "history - predecessor remembered by piece generator",
        "roll - roll tries of piece generator",
        "extra - extra pieces in one bag",
        "reset - lock delay reset limit",
        "lock - lock delay",
        "groundlock - force lock delay after on ground",
        "forcelock - force lock delay",
        "drop - time of drop per grid",
        "openerphrase - length of opener bonus",
        "garbagepreview - count of garbage previewed",
        "garbagegap - limit of garbage entering at once",
        "garbagedelay - delay of garbage being active",
        "garbagerise - entering distance between garbage layers",
        "initfacing - inital facing of piece",
        "hold - hold rule",
        "sequence - piece generation rule",
        "das - delayed auto shift",
        "arr - auto repeat rate",
        "drd - drop delay",
        "dropdas - soft drop delayed auto shift",
        "droparr - soft drop auto repeat rate",
        "dcd - auto shift cancel delay",
        "hcd - hard drop cooldown",
        "deathare - delay given to prevent top out",
        "are - appearance delay",
        "lcd - line clear delay",
        "shadow - shadow piece",
        "roundheight - height avoiding line clear",
        "stock - extra lifes in one game",
        "life - remaining extra lifes",
        "mod2 - quick play mod : No Hold",
        "mod3 - quick play mod : Messier Garbage",
        "mod4 - quick play mod : Gravity",
        "mod5 - quick play mod : Volatile Garbage",
        "mod6 - quick play mod : Double Hold Garbage",
        "mod7 - quick play mod : Invisible",
        "mod8 - quick play mod : All-Spin",
        "mod9 - quick play mod : Expert Mode"};
        vector<string> tmp;
        for (int i=pp; i<Co.size(); ++i) tmp.push_back(Co[i]);
        Co = tmp;
        if (!Co.size()) {
            if (pp) {
                return {
                "launch - launch a certain game mode",
                "quit - quit the current game",
                "config - change configs used by players",
                "keymap - change key bindings",
                "finish - finish the current game",
                "abort - abort the current game",
                "setblock - change a block on a certain place",
                "fill - fill blocks in a square area",
                "garbage - push garbage lines",
                "damage - send attack to selected player",
                "waste - waste the current piece",
                "lock - force the current piece to lock",
                "set - change a certain value of the selected players",
                "gamerule - change rules of the game",
                "spectate - spectate a certain player"};
            }
            else {
                return {"forall - run command to all players",
                "for <condition> run - run command to players satisfying certain conditions",
                "launch - launch a certain game mode",
                "quit - quit the current game",
                "config - change configs used by players",
                "keymap - change key bindings",
                "finish - finish the current game",
                "abort - abort the current game",
                "setblock - change a block on a certain place",
                "fill - fill blocks in a square area",
                "garbage - push garbage lines",
                "damage - send attack to selected player",
                "waste - waste the current piece",
                "lock - force the current piece to lock",
                "set - change a certain value of the selected players",
                "gamerule - change rules of the game",
                "spectate - spectate a certain player"};
            }
        }
        if (Co.size()==1) Co.push_back(".");
        if (Co[0]=="config") {
            if (Co[1]=="style") return {"default","classic","arcade","simple"};
            if (Co[1]=="defaultrotate") return {"ccw - counterclockwise",
            "cw - clockwise"};
            if ((Co[1]=="dropeffect")||(Co[1]=="rotateeffect")||(Co[1]=="moveeffect")||(Co[1]=="spineffect")) return {"true","false"};
            return {"das - delayed auto shift",
            "arr - auto repeat rate",
            "dropdas - soft drop delayed auto shift",
            "droparr - soft drop auto repeat rate",
            "dcd - auto shift cancel delay",
            "hcd - hard drop cooldown",
            "defaultrotate - direction of default rotation",
            "style - visual style",
            "moveeffect - visual effect on stuck move and lock",
            "spineffect - visual effect on spin",
            "dropeffect - visual drop effect",
            "rotateeffect - visual rotate effect"};
        }
        if (Co[0]=="keymap") {
            if (Co[1]!=".") return {};
            return {"left - move left",
            "right - move right",
            "down - soft drop",
            "drop - hard drop",
            "sonic - sonic drop",
            "rotate - default rotate",
            "cw - clockwise rotate",
            "ccw - counterclockwise rotate",
            "half - half rotate",
            "hold - swap hold piece",
            "undo - undo the last piece [zen exclusive]",
            "retry - restart the game",
            "reset - reset the piece to inital position [zen exclusive]",
            "flip - flip the current piece",
            "up - move up",
            "waste - skip the current piece",
            "even - set attack mode to Even",
            "ko - set attack mode to KOs",
            "random - set attack mode to Random",
            "payback - set attack mode to Payback",
            "badge - set attack mode to Badges",
            "attacker - set attack mode to Attackers"};
        }
        vector<string> BlockList = {"0 - Empty"};
        for (int i=1; i<155; ++i) {
            if (CheckBlockType(i)) BlockList.push_back(IToS(i)+" - "+PName[i]);
        }
        if (Co[0]=="setblock") {
            if (Co.size()>=3) return BlockList;
            return {"setblock [x] [y] [val=154] [replace=-1]"};
        }
        if (Co[0]=="fill") {
            if (Co.size()>=5) return BlockList;
            return {"fill [beg x] [beg y] [end x] [end y] [val=154] [replace=-1]"};
        }
        if (Co[0]=="garbage") return {"garbage [count=1] [type=random]"};
        if (Co[0]=="damage") return {"damage [count=1] [type=random]"};
        if (Co[0]=="waste") return {"waste [count=1]"};
        if (Co[0]=="set") return ChangeList;
        if (Co[0]=="spectate") return {"spectate [player=current]"};
        if (Co[0]=="gamerule") {
            if (Co[1]=="spin") return {"allspin - pieces are equal and spins are divided to 3 levels",
            "allfull - every immovable spin is counted as full",
            "allsemi - spins without T-piece are counted as semi",
            "allmini - spins without T-piece are counted as mini",
            "minionly - all spins are regarded as mini",
            "tspin - only T-spins are rewarded",
            "default - spin rule similar to guildline",
            "easy - spin rule of TGM3 easy mode",
            "none - disable spin detection"};
            if (Co[1]=="clutch") return {"default - enable clutch on line clears",
            "always - always enable clutch",
            "none - disable clutch"};
            if (Co[1]=="baseattack") return {"default - guideline rule of normal clear attack",
            "asc - attack rule of ascension and cultris",
            "classic - attack rule of huopin",
            "arcade - attack rule of TGM",
            "equal - basic attack equals to lines cleared",
            "none - disable normal clear attack"};
            if (Co[1]=="cleargravity") return {"default - normal clear gravity",
            "none - no clear gravity",
            "cascade - every piece falls separately",
            "sticky - every connected part falls separately",
            "separate - every block above cleared lines falls separately"};
            if (Co[1]=="b2b") return {"default - B2B rule of guildline",
            "chain - continuous B2B is extra rewarded",
            "surge - send surge attack while ending B2B chain",
            "techmino - B2B is accumulated by percentage",
            "none - disable B2B"};
            if (Co[1]=="combo") return {"multipler - combo boost base attack by multipler with 2,3,4-wide weakened",
            "io - combo boost base attack by multipler",
            "default - combo table of guildline",
            "firends - combo table of 4 friends",
            "expert - combo table of 4 friends expert mode",
            "battle - combo table of 4 battle",
            "99 - combo table of 4 99",
            "ppt - combo rule of puyo puyo T",
            "effect - combo rule of T effect",
            "zone - combo rule of T effect zone battle",
            "techmino - a weakened multipler combo system",
            "c2 - a series of line clears in a short time",
            "aquamino - 2,3,4-wide weakened",
            "none - disable combo bonus"};
            if (Co[1]=="rotation") return {"default - rotate system based on srs+ with ospin and additional kicks",
            "extend - rotate system with powerful half rotation kicks",
            "srs - rotate system of guildline",
            "srsplus - rotate system based on srs with basic half rotation kicks",
            "asc - rotate system suitable for multiminos",
            "ascplus - rotate system based on asc with maxium spin possibilities",
            "ors - rotate system of original T",
            "rnrs - rotate system of nes T",
            "lnrs - rotate system of gameboy T",
            "atari - rotate system of atari T",
            "ars - rotate system of arcade",
            "tetrax - tetra-x rotate system",
            "c2 - rotate system of cultris",
            "new - rotate system of the new T",
            "none - same basic rotation as default but without kicks"};
            if (Co[1]=="allclear") return {"extend - all clear give the same attack as width and half clear decrease garbage",
            "default - all clear give the same attack as width",
            "techmino - damage of all clear and half clear increase by 2 every time",
            "quickplay - all clear give 3 attack and 2 B2B",
            "league - all clear give 5 attack and 1 B2B",
            "99 - all clear give 4 attack",
            "arcade - all clear doubles the current attack",
            "none - disable all clear"};
            if (Co[1]=="garbagetype") return {"layer - garbage enter as fall garbage",
            "bomb - garbage enter as bomb line",
            "fall - garbage fall to the top of stack",
            "solid - garbage line cannot be cleared"};
            if (Co[1]=="garbagemode") return {"combo - garbage enter upon none clearing locks",
            "attack - garbage enter upon none attack locks",
            "lock - garbage enter upon lock",
            "instant - garbage enter instantly"};
            if (Co[1]=="garbagecancel") return {"default - attack points cancel pending garbage",
            "none - no garbage canceling",
            "dig - attack points dig garbage lines on board"};
            if (Co[1]=="garbageshape") return {"cheese - garbage with 1 hole per line",
            "full - full filled garbage",
            "empty - empty garbage line",
            "random - every position of garbage is random",
            "bubble - garbage with 1 block per line",
            "copy - copy the bottom line of receiver",
            "clear - copy the shape of attacker\'s clear",
            "arcade - copy the upside-down shape of attacker\'s clear",
            "board - garbage with board and hole alternating"};
            if (Co[1]=="garbagebonus") return {"default - advanced clear with garbage give 1 defence",
            "io - advanced clear with garbage give 1 attack",
            "none - no garbage clear bonus"};
            if (Co[1]=="opener") return {"default - given the same defence as attack in opener phrase",
            "io - cancel twice if many garbage in queue in opener phrase",
            "none - disable opener phrase"};
            if (Co[1]=="sequence") return {"random - each piece is generated separately",
            "bag - pieces are generated by bag",
            "fixed - pieces are generated in a sequence loop"};
            if (Co[1]=="initfacing") return {"up","down","left","right"};
            if (Co[1]=="hold") return {"none - disable hold",
            "default - hold no more than one before lock",
            "infinity - free hold and reset function enabled"};
            if (Co[1]=="targetbonus") return {"default - reward attack when targeted by many players and using attackers targeting and defence otherwise",
            "99 - reward attack when targeted by many players and using attackers targeting",
            "defensive - reward defence when targeted by many players",
            "none - no target bonus"};
            if (Co[1]=="badgebonus") return {"default - reward attack from badges smoothly",
            "99 - reward attack from badges like T 99",
            "none - no badge bonus"};
            if ((Co[1]=="arcaderound")||(Co[1]=="observebot")||(Co[1]=="shadow")||(Co[1]=="usemove")||(Co[1]=="userotate")||(Co[1]=="use2rotate")||(Co[1]=="usehalf")||(Co[1]=="usehard")||(Co[1]=="usesoft")||(Co[1]=="usesonic")||(Co[1]=="useflip")||(Co[1]=="useup")||(Co[1]=="uselock")||(Co[1]=="usedeep")) return {"false","true"};
            if (Co[1]=="scaletype") return {"default - scale difficulty by marathon rule",
            "div - scale difficulty by inverse proportion",
            "dec - reduce delay by static value per level",
            "exp - scale difficulty exponentially"};
            if (Co[1]=="piece") return {""};
            return {
            "levelstart - start level calculated as max",
            "levelbase - base level of level calculation",
            "levelline - lines cleared per level",
            "leveltime - time per level",
            "levelpiece - piece per level",
            "levelattack - attack per level",
            "increaseline - increasing line cleared required per level",
            "increasetime - increasing time required per level",
            "increasepiece - increasing piece required per level",
            "increaseattack - increasing attack required per level",
            "levelmaster - begin level of 20g",
            "levelratio - difficulty scale of level",
            "scaletype - scale type of leveling",
            "usemove - allow moving",
            "userotate - allow rotation",
            "use2rotate - allow two direct rotation",
            "usehalf - allow half rotation",
            "usehard - allow hard drop",
            "usesoft - allow soft drop",
            "usesonic - allow sonic drop",
            "useflip - allow flip operation",
            "useup - allow moving up",
            "uselock - allow lock in place",
            "usedeep - allow deep drop",
            "wastelimit - allow waste operations in one game",
            "spin - spin detecting rule",
            "clutch - clutch rule",
            "baseattack - basic attack rule",
            "cleargravity - tule of block drop after clear",
            "b2b - back to back rule",
            "combo - combo rule",
            "rotation - rotate system",
            "allclear - all clear rule",
            "garbageluck - clear easiness of garbage hole position",
            "passthrough - passthrough delay",
            "garbagetype - type of attack effect",
            "garbagemode - garbage entering mode",
            "garbagecancel - garbage cancel rule",
            "garbageshape - position mode of garbage",
            "garbagebonus - bonus of clearing garbage with advanced clear",
            "opener - opener phrase rule",
            "sequence - piece generation rule",
            "initfacing - inital facing of piece",
            "arcaderound - use round in arcade",
            "observebot - observe cpu players battle after knockout",
            "shadow - shadow piece",
            "targetbonus - bonus when targeted by many players",
            "badgebonus - attack bonus from badges",
            "hold - hold rule",
            "innermess - messiness inside a segment of attack",
            "segmess - messiness between segments of attack",
            "openerphrase - length of opener bonus",
            "garbagepreview - count of garbage previewed",
            "garbagegap - limit of garbage entering at once",
            "garbagedelay - delay of garbage being active",
            "garbagerise - entering distance between garbage layers",
            "drop - time of drop per grid",
            "lock - lock delay",
            "groundlock - force lock delay after on ground",
            "forcelock - force lock delay",
            "reset - lock delay reset limit",
            "deathare - delay given to prevent top out",
            "are - appearance delay",
            "lcd - line clear delay",
            "drd - drop delay",
            "next - next piece",
            "history - predecessor remembered by piece generator",
            "roll - roll tries of piece generator",
            "extra - extra pieces in one bag",
            "height - displaying height of board",
            "realheight - real height of board",
            "vanish - height of vanish zone"
            "width - width of board",
            "stock - extra lifes in one game",
            "piece - the used piece in generation"};
        }
        return {};
    }
    bool Press = false;
    string Str(int x) {
        return string("")+char(x);
    }
    void PaintGlobal(int tm) {
        ll curtm = clock();
        while ((FP.size())&&(FP.front()+1000LL<=curtm)) FP.pop();
        FP.push(curtm);
        POINT p; GetCursorPos(&p);
        ScreenToClient(GetForegroundWindow(), &p);
        p.y-=96; p.x-=100;
        p.y/=4.86/5.00; p.x/=4.98/5.00;
        //Command="forall set botspeed 0";
        vector<pair<string,string> > Option = {
        {"General",""},{"Resume","forall"}, {"Retry","abort"},{"Kill","kill"},{"Quit","quit"},
        {"Hold",""},{"Disable","gamerule hold none"}, {"Enable","gamerule hold default"}, {"Infinite","gamerule hold infinity"},{"",""},
        {"Next","gamerule next ~"},{"Disable","gamerule next 0"},{"1","gamerule next 1"},{"3","gamerule next 3"},{"5","gamerule next 5"},
        {"Rotation",""},{"Default","gamerule rotation default"},{"SRS","gamerule rotation srs"},{"SRS+","gamerule rotation srsplus"},{"Extend","gamerule rotation extend"},
        {"",""},{"ASC+","gamerule rotation ascplus"},{"TETRA-X","gamerule rotation tetrax"},{"ORS","gamerule rotation ors"},{"ARS","gamerule rotation ars"},
        {"",""},{"NES","gamerule rotation rnrs"},{"GB","gamerule rotation lnrs"},{"Cultris","gamerule rotation c2"},{"Atari","gamerule rotation atari"},
        {"",""},{"ASC","gamerule rotation asc"},{"New","gamerule rotation new"},{"None","gamerule rotation none"},{"",""},
        {"UseMove",""},{"On","gamerule usemove true"},{"Off","gamerule usemove false"},{"",""},{"",""},
        {"UseRot",""},{"On","gamerule userotate true"},{"Off","gamerule userotate false"},{"",""},{"",""},
        {"Use2Rot",""},{"On","gamerule use2rotate true"},{"Off","gamerule use2rotate false"},{"",""},{"",""},
        {"UseHalf",""},{"On","gamerule usehalf true"},{"Off","gamerule usehalf false"},{"",""},{"",""},
        {"UseHard",""},{"On","gamerule usehard true"},{"Off","gamerule usehard false"},{"",""},{"",""},
        {"UseSoft",""},{"On","gamerule usesoft true"},{"Off","gamerule usesoft false"},{"",""},{"",""},
        {"UseSonic",""},{"On","gamerule usesonic true"},{"Off","gamerule usesonic false"},{"",""},{"",""},
        {"UseFlip",""},{"On","gamerule useflip true"},{"Off","gamerule useflip false"},{"",""},{"",""},
        {"UseUp",""},{"On","gamerule useup true"},{"Off","gamerule useup false"},{"",""},{"",""},
        {"UseLock",""},{"On","gamerule uselock true"},{"Off","gamerule uselock false"},{"",""},{"",""},
        {"UseDeep",""},{"On","gamerule usedeep true"},{"Off","gamerule usedeep false"},{"",""},{"",""},
        {"BaseAtk",""},{"Guildline","gamerule baseattack default"},{"ASC","gamerule baseattack asc"},{"Classic","gamerule baseattack classic"},{"Arcade","gamerule baseattack arcade"},
        {"",""},{"Equal","gamerule baseattack equal"},{"Disable","gamerule baseattack none"},{"",""},{"",""},
        {"Combo",""},{"Multipler","gamerule combo multipler"},{"IO","gamerule combo io"},{"Guildline","gamerule combo default"},{"99","gamerule combo 99"},
        {"",""},{"PPT","gamerule combo ppt"},{"Effect","gamerule combo effect"},{"Zone","gamerule combo zone"},{"Cultris","gamerule combo c2"},
        {"",""},{"Techmino","gamerule combo techmino"},{"Battle","gamerule combo battle"},{"Friends","gamerule combo friends"},{"Expert","gamerule combo expert"},
        {"",""},{"Aquamino","gamerule combo aquamino"},{"Disable","gamerule combo none"},{"",""},{"",""},
        {"B2B",""},{"Guildline","gamerule b2b default"},{"Chain","gamerule b2b chain"},{"Surge","gamerule b2b surge"},{"Techmino","gamerule b2b techmino"},
        {"",""},{"Disable","gamerule b2b none"},{"",""},{"",""},{"",""},
        {"Spin",""},{"All-Spin","gamerule spin allspin"},{"Guildline","gamerule spin default"},{"All-Full","gamerule spin allfull"},{"All-Semi","gamerule spin allsemi"},
        {"",""},{"All-Mini","gamerule spin allmini"},{"T-Spin","gamerule spin tspin"},{"Easy","gamerule spin easy"},{"Mini-Only","gamerule spin minionly"},
        {"",""},{"Disable","gamerule spin none"},{"",""},{"",""},{"",""},
        {"PC",""},{"Extend","gamerule allclear extend"},{"Default","gamerule allclear default"},{"Techmino","gamerule allclear techmino"},{"IO","gamerule allclear league"},
        {"",""},{"QP","gamerule allclear quickplay"},{"99","gamerule allclear 99"},{"Arcade","gamerule allclear arcade"},{"Disable","gamerule allclear none"},
        {"DefRot",""},{"CCW","config defaultrotate ccw"},{"CW","config defaultrotate cw"},{"",""},{"",""},
        {"DAS","config das ~"},{"0","config das 0"},{"0.05","config das 50"},{"0.06","config das 60"},{"0.08","config das 80"},
        {"",""},{"0.1","config das 100"},{"0.12","config das 120"},{"0.167","config das 167"},{"0.2","config das 200"},
        {"",""},{"0.25","config das 250"},{"0.3","config das 300"},{"0.5","config das 500"},{"1","config das 1000"},
        {"ARR","config arr ~"},{"0","config arr 0"},{"0.01","config arr 10"},{"0.02","config arr 20"},{"0.033","config arr 33"},
        {"",""},{"0.05","config arr 50"},{"0.1","config arr 100"},{"0.15","config arr 150"},{"0.2","config arr 200"},
        {"SDDAS","config dropdas ~"},{"0","config dropdas 0"},{"0.05","config dropdas 50"},{"0.06","config dropdas 60"},{"0.08","config dropdas 80"},
        {"",""},{"0.1","config dropdas 100"},{"0.12","config dropdas 120"},{"0.15","config dropdas 150"},{"0.2","config dropdas 200"},
        {"",""},{"0.25","config dropdas 250"},{"0.3","config dropdas 300"},{"0.5","config dropdas 500"},{"1","config dropdas 1000"},
        {"SDARR","config droparr ~"},{"0","config droparr 0"},{"0.01","config droparr 10"},{"0.02","config droparr 20"},{"0.05","config droparr 50"},
        {"",""},{"0.075","config droparr 75"},{"0.1","config droparr 100"},{"0.15","config droparr 150"},{"0.2","config droparr 200"},
        {"DCD","config dcd ~"},{"0","config dcd 0"},{"0.01","config dcd 10"},{"0.02","config dcd 20"},{"0.03","config dcd 30"},
        {"",""},{"0.05","config dcd 50"},{"0.075","config dcd 75"},{"0.1","config dcd 100"},{"0.15","config dcd 150"},
        {"",""},{"0.2","config dcd 200"},{"0.5","config dcd 500"},{"1","config dcd 1000"},{"Infinity","config dcd max"},
        {"HCD","config hcd ~"},{"0","config hcd 0"},{"0.01","config hcd 10"},{"0.02","config hcd 20"},{"0.03","config hcd 30"},
        {"",""},{"0.05","config hcd 50"},{"0.075","config hcd 75"},{"0.1","config hcd 100"},{"0.15","config hcd 150"},
        {"",""},{"0.2","config hcd 200"},{"0.5","config hcd 500"},{"1","config hcd 1000"},{"Infinity","config hcd max"},
        {"GarbType",""},{"Layer","gamerule garbagetype layer"},{"Bomb","gamerule garbagetype bomb"},{"Fall","gamerule garbagetype fall"},{"Solid","gamerule garbagetype solid"},
        {"GarbMode",""},{"Combo","gamerule garbagemode combo"},{"Attack","gamerule garbagemode attack"},{"Lock","gamerule garbagemode lock"},{"Instant","gamerule garbagemode instant"},
        {"GarbCnel",""},{"Default","gamerule garbagecancel default"},{"Dig","gamerule garbagecancel dig"},{"Disable","gamerule garbagecancel none"},{"",""},
        {"GarbShape",""},{"Cheese","gamerule garbageshape cheese"},{"Full","gamerule garbageshape full"},{"Empty","gamerule garbageshape empty"},{"Random","gamerule garbageshape random"},
        {"",""},{"Board","gamerule garbageshape board"},{"Bubble","gamerule garbageshape bubble"},{"Copy","gamerule garbageshape copy"},{"Clear","gamerule garbageshape clear"},
        {"",""},{"Arcade","gamerule garbageshape arcade"},{"",""},{"",""},{"",""},
        {"Opener",""},{"Default","gamerule opener default"},{"IO","gamerule opener io"},{"Disable","gamerule opener none"},{"",""},
        {"OpenLen","gamerule openerphrase ~"},{"7","gamerule openerphrase 7"},{"14","gamerule openerphrase 14"},{"28","gamerule openerphrase 28"},{"50","gamerule openerphrase 50"},
        {"DigBonus",""},{"Default","gamerule garbagebonus default"},{"IO","gamerule garbagebonus io"},{"Disable","gamerule garbagebonus none"},{"",""},
        {"GarbDelay","gamerule garbagedelay ~"},{"0","gamerule garbagedelay 0"},{"0.1","gamerule garbagedelay 100"},{"0.25","gamerule garbagedelay 250"},{"0.5","gamerule garbagedelay 500"},
        {"",""},{"1","gamerule garbagedelay 1000"},{"1.5","gamerule garbagedelay 1500"},{"2","gamerule garbagedelay 2000"},{"5","gamerule garbagedelay 5000"},
        {"GarbRise","gamerule garbagerise ~"},{"0","gamerule garbagerise 0"},{"0.01","gamerule garbagerise 10"},{"0.02","gamerule garbagerise 20"},{"0.05","gamerule garbagerise 50"},
        {"",""},{"0.75","gamerule garbagerise 75"},{"0.1","gamerule garbagerise 100"},{"0.2","gamerule garbagerise 200"},{"0.5","gamerule garbagerise 500"},
        {"",""},{"1","gamerule garbagerise 1000"},{"2","gamerule garbagerise 2000"},{"5","gamerule garbagerise 5000"},{"10","gamerule garbagerise 10000"},
        {"GarbPrev","gamerule garbagepreview ~"},{"Off","gamerule garbagepreview 0"},{"1","gamerule garbagepreview 1"},{"3","gamerule garbagepreview 3"},{"10","gamerule garbagepreview 10"},
        {"GarbGap","gamerule garbagegap ~"},{"0","gamerule garbagegap 0"},{"1","gamerule garbagegap 1"},{"2","gamerule garbagegap 2"},{"4","gamerule garbagegap 4"},
        {"",""},{"5","gamerule garbagegap 5"},{"8","gamerule garbagegap 8"},{"10","gamerule garbagegap 10"},{"Infinity","gamerule garbagegap max"},
        {"InnerMess","gamerule innermess ~"},{"0","gamerule innermess 0"},{"0.01","gamerule innermess 1"},{"0.02","gamerule innermess 2"},{"0.05","gamerule innermess 5"},
        {"",""},{"0.1","gamerule innermess 10"},{"0.15","gamerule innermess 15"},{"0.2","gamerule innermess 2"},{"0.25","gamerule innermess 25"},
        {"",""},{"0.3","gamerule innermess 30"},{"0.5","gamerule innermess 50"},{"0.75","gamerule innermess 75"},{"1","gamerule innermess 100"},
        {"SegMess","gamerule segmess ~"},{"0","gamerule segmess 0"},{"0.01","gamerule segmess 1"},{"0.02","gamerule segmess 2"},{"0.05","gamerule segmess 5"},
        {"",""},{"0.1","gamerule segmess 10"},{"0.15","gamerule segmess 15"},{"0.2","gamerule segmess 2"},{"0.25","gamerule segmess 25"},
        {"",""},{"0.3","gamerule segmess 30"},{"0.5","gamerule segmess 50"},{"0.75","gamerule segmess 75"},{"1","gamerule segmess 100"},
        {"GarbPass","gamerule passthrough ~"},{"0","gamerule passthrough 0"},{"0.001","gamerule passthrough 1"},{"0.05","gamerule passthrough 50"},{"0.1","gamerule passthrough 100"},
        {"",""},{"0.2","gamerule passthrough 200"},{"0.333","gamerule passthrough 333"},{"0.5","gamerule passthrough 500"},{"1","gamerule passthrough 1000"},
        {"",""},{"1.25","gamerule passthrough 1250"},{"1.5","gamerule passthrough 1500"},{"2","gamerule passthrough 2000"},{"Infinity","gamerule passthrough max"},
        {"GarbLuck","gamerule garbageluck ~"},{"-100","gamerule garbageluck 0"},{"-75","gamerule garbageluck 25"},{"-50","gamerule garbageluck 50"},{"-30","gamerule garbageluck 70"},
        {"",""},{"-25","gamerule garbageluck 75"},{"-20","gamerule garbageluck 80"},{"-15","gamerule garbageluck 85"},{"-10","gamerule garbageluck 90"},
        {"",""},{"-5","gamerule garbageluck 95"},{"0","gamerule garbageluck 100"},{"+5","gamerule garbageluck 105"},{"+10","gamerule garbageluck 110"},
        {"",""},{"+15","gamerule garbageluck 115"},{"+20","gamerule garbageluck 120"},{"+25","gamerule garbageluck 125"},{"+30","gamerule garbageluck 130"},
        {"",""},{"+50","gamerule garbageluck 150"},{"+75","gamerule garbageluck 175"},{"+100","gamerule garbageluck 200"},{"+1000","gamerule garbageluck 1100"},
        {"ClearGrav",""},{"Default","gamerule cleargravity default"},{"None","gamerule cleargravity none"},{"Sticky","gamerule cleargravity sticky"},{"Cascade","gamerule cleargravity cascade"},
        {"",""},{"Separate","gamerule cleargravity separate"},{"",""},{"",""},{"",""},
        {"Clutch",""},{"Default","gamerule clutch default"},{"Always","gamerule clutch always"},{"Disable","gamerule clutch none"},{"",""},
        {"Piece","gamerule piece ~"},{"M1","gamerule piece a"},{"M2","gamerule piece b"},{"M3","gamerule piece cd"},{"M4","gamerule piece ijlostz"},
        {"",""},{"M5","gamerule piece efhi5j5l5npqrs5t5uvwxyz5"},{"M6","gamerule piece k30k31k32k33k34k35k36k37k38k39k40k41k42k43k44k45k46k47k48k49k50k51k52k53k54k55k56k57k58k59k60k61k62k63k64k65k66k67k68k69k70k71k72k73k74k75k76k77k78k79k80k81k82k83k84k85k86k87k88k89"},{"M123","gamerule piece abcd"},{"M1234","gamerule piece abcdijlostz"},
        {"",""},{"M12345","gamerule piece abcdefhijlnopqrstuvwxyzi5j5l5s5t5z5"},{"M45","gamerule piece ijlostzefhi5j5l5npqrs5t5uvwxyz5"},{"M123456","gamerule piece abcdefhijlnopqrstuvwxyzi5j5l5s5t5z5k30k31k32k33k34k35k36k37k38k39k40k41k42k43k44k45k46k47k48k49k50k51k52k53k54k55k56k57k58k59k60k61k62k63k64k65k66k67k68k69k70k71k72k73k74k75k76k77k78k79k80k81k82k83k84k85k86k87k88k89"},{"Mixed","ciallo"},
        {"",""},{"14-Bag","gamerule piece iijjlloossttzz"},{"Drought","gamerule piece jlostz"},{"Kid\'s","gamerule piece ijlot"},{"Heaven","gamerule piece i"},
        {"",""},{"M4-","gamerule piece ijost"},{"M5-","gamerule piece ehi5j5prs5t5uvwx"},{"M6-","gamerule piece k30k31k32k33k34k35k36k37k38k39k40k42k44k46k48k50k52k54k56k58k60k62k64k66k68k70k72k74k76k78k80k82k84k86k88"},{"M45-","gamerule piece ijostehi5j5prs5t5uvwx"},
        {"",""},{"M12345-","gamerule piece abcijostehi5j5prs5t5uvwx"},{"M123456-","gamerule piece abcijostehi5j5prs5t5uvwxk30k31k32k33k34k35k36k37k38k39k40k42k44k46k48k50k52k54k56k58k60k62k64k66k68k70k72k74k76k78k80k82k84k86k88"},{"",""},{"",""},
        {"Sequence",""},{"Bag","gamerule sequence bag"},{"Random","gamerule sequence random"},{"Fixed","gamerule sequence fixed"},{"",""},
        {"SeqHis","gamerule history ~"},{"0","gamerule history 0"},{"1","gamerule history 1"},{"2","gamerule history 2"},{"4","gamerule history 4"},
        {"SeqRoll","gamerule roll ~"},{"1","gamerule roll 1"},{"2","gamerule roll 2"},{"4","gamerule roll 4"},{"6","gamerule roll 6"},
        {"BagExtra","gamerule extra ~"},{"0","gamerule extra 0"},{"1","gamerule extra 1"},{"2","gamerule extra 2"},{"3","gamerule extra 3"},
        {"InitDir",""},{"Up","gamerule initfacing up"},{"Down","gamerule initfacing down"},{"Left","gamerule initfacing left"},{"Right","gamerule initfacing right"},
        {"Shadow",""},{"On","gamerule shadow true"},{"Off","gamerule shadow false"},{"",""},{"",""},
        {"ObsBot",""},{"On","gamerule observebot true"},{"Off","gamerule observebot false"},{"",""},{"",""},
        {"TarBonus",""},{"Default","gamerule targetbonus default"},{"99","gamerule targetbonus 99"},{"Defense","gamerule targetbonus defensive"},{"Disable","gamerule targetbonus none"},
        {"BdgBonus",""},{"Default","gamerule badgebonus default"},{"99","gamerule badgebonus 99"},{"Disable","gamerule badgebonus none"},{"",""},
        {"StartH","set startheight ~"},{"Off","set startheight 0"},{"1","set startheight 1"},{"2","set startheight 2"},{"3","set startheight 3"},
        {"",""},{"4","set startheight 4"},{"10","set startheight 10"},{"15","set startheight 15"},{"20","set startheight 20"},
        {"StaticH","set staticheight ~"},{"Off","set staticheight 0"},{"1","set staticheight 1"},{"2","set staticheight 2"},{"3","set staticheight 3"},
        {"",""},{"4","set staticheight 4"},{"10","set staticheight 10"},{"20","set staticheight 20"},{"Infinity","set staticheight max"},
        {"Width","gamerule width ~"},{"4","gamerule width 4"},{"5","gamerule width 5"},{"8","gamerule width 8"},{"10","gamerule width 10"},
        {"",""},{"12","gamerule width 12"},{"15","gamerule width 15"},{"20","gamerule width 20"},{"50","gamerule width 50"},
        {"Height","gamerule height ~"},{"0","gamerule height 2"},{"2","gamerule height 4"},{"5","gamerule height 7"},{"10","gamerule height 12"},
        {"",""},{"15","gamerule height 17"},{"20","gamerule height 22"},{"40","gamerule height 42"},{"88","gamerule height 90"},
        {"BufHeight","gamerule realheight ~"},{"4","gamerule realheight 4"},{"22","gamerule realheight 22"},{"40","gamerule realheight 40"},{"90","gamerule realheight 90"},
        {"WasteLim","gamerule wastelimit ~"},{"0","gamerule wastelimit 0"},{"10","gamerule wastelimit 10"},{"25","gamerule wastelimit 25"},{"Infinity","gamerule wastelimit max"},
        {"Reset","gamerule reset ~"},{"0","gamerule reset 0"},{"1","gamerule reset 1"},{"2","gamerule reset 2"},{"5","gamerule reset 5"},
        {"",""},{"10","gamerule reset 10"},{"15","gamerule reset 15"},{"30","gamerule reset 30"},{"Infinity","gamerule reset max"},
        {"Drop","gamerule drop ~"},{"0","gamerule drop 0"},{"0.01","gamerule drop 10"},{"0.02","gamerule drop 20"},{"0.05","gamerule drop 50"},
        {"",""},{"0.1","gamerule drop 100"},{"0.2","gamerule drop 200"},{"0.25","gamerule drop 250"},{"0.5","gamerule drop 500"},
        {"",""},{"0.75","gamerule drop 750"},{"0.8","gamerule drop 800"},{"1","gamerule drop 1000"},{"2","gamerule drop 2000"},
        {"",""},{"2.5","gamerule drop 2500"},{"3","gamerule drop 3000"},{"5","gamerule drop 5000"},{"Infinity","gamerule drop max"},
        {"Lock","gamerule lock ~"},{"0","gamerule lock 0"},{"0.1","gamerule lock 100"},{"0.2","gamerule lock 200"},{"0.25","gamerule lock 250"},
        {"",""},{"0.3","gamerule lock 300"},{"0.5","gamerule lock 500"},{"1","gamerule lock 1000"},{"1.5","gamerule lock 1500"},
        {"",""},{"2","gamerule lock 2000"},{"3","gamerule lock 3000"},{"5","gamerule lock 5000"},{"Infinity","gamerule lock max"},
        {"GndLock","gamerule groundlock ~"},{"0","gamerule groundlock 0"},{"0.2","gamerule groundlock 200"},{"0.25","gamerule groundlock 250"},{"0.5","gamerule groundlock 500"},
        {"",""},{"0.75","gamerule groundlock 750"},{"1","gamerule groundlock 1000"},{"1.5","gamerule groundlock 1500"},{"2","gamerule groundlock 2000"},
        {"",""},{"3","gamerule groundlock 3000"},{"5","gamerule groundlock 5000"},{"10","gamerule groundlock 10000"},{"Infinity","gamerule groundlock max"},
        {"FceLock","gamerule forcelock ~"},{"0.2","gamerule forcelock 200"},{"0.25","gamerule forcelock 250"},{"0.5","gamerule forcelock 500"},{"0.75","gamerule forcelock 750"},
        {"",""},{"1","gamerule forcelock 1000"},{"1.5","gamerule forcelock 1500"},{"2","gamerule forcelock 2000"},{"3","gamerule forcelock 3000"},
        {"",""},{"5","gamerule forcelock 5000"},{"10","gamerule forcelock 10000"},{"20","gamerule forcelock 20000"},{"Infinity","gamerule forcelock max"},
        {"ARE","gamerule are ~"},{"0","gamerule are 0"},{"0.05","gamerule are 50"},{"0.1","gamerule are 100"},{"0.2","gamerule are 200"},
        {"",""},{"0.25","gamerule are 250"},{"0.5","gamerule are 500"},{"1","gamerule are 1000"},{"2","gamerule are 2000"},
        {"LCD","gamerule lcd ~"},{"0","gamerule lcd 0"},{"0.05","gamerule lcd 50"},{"0.1","gamerule lcd 100"},{"0.2","gamerule lcd 200"},
        {"",""},{"0.25","gamerule lcd 250"},{"0.5","gamerule lcd 500"},{"1","gamerule lcd 1000"},{"2","gamerule lcd 2000"},
        {"DRD","gamerule drd ~"},{"0","gamerule drd 0"},{"0.05","gamerule drd 50"},{"0.1","gamerule drd 100"},{"0.15","gamerule drd 150"},
        {"",""},{"0.2","gamerule drd 200"},{"0.25","gamerule drd 250"},{"0.3","gamerule drd 300"},{"0.5","gamerule drd 500"},
        {"",""},{"0.75","gamerule drd 750"},{"1","gamerule drd 1000"},{"1.5","gamerule drd 1500"},{"Infinity","gamerule drd max"},
        {"DeathARE","gamerule deathare ~"},{"0","gamerule deathare 0"},{"0.05","gamerule deathare 50"},{"0.1","gamerule deathare 100"},{"0.2","gamerule deathare 200"},
        {"",""},{"0.25","gamerule deathare 250"},{"0.5","gamerule deathare 500"},{"1","gamerule deathare 1000"},{"2","gamerule deathare 2000"},
        {"Lifes","gamerule stock ~"},{"1","gamerule stock 0"},{"2","gamerule stock 1"},{"3","gamerule stock 2"},{"5","gamerule stock 4"},
        {"",""},{"8","gamerule stock 7"},{"10","gamerule stock 9"},{"20","gamerule stock 19"},{"Infinity","gamerule stock max"},
        {"Bot",""},{"Human","set bot 0"},{"Bot","set bot 1"},{"AllHuman","forall set bot 0"},{"AllBot","forall set bot 1"},
        {"BotType",""},{"0","set bottype 0"},{"1","set bottype 1"},{"2","set bottype 2"},{"3","set bottype 3"},
        {"",""},{"4","set bottype 4"},{"5","set bottype 5"},{"6","set bottype 6"},{"",""},
        {"AllType",""},{"0","forall set bottype 0"},{"1","forall set bottype 1"},{"2","forall set bottype 2"},{"3","forall set bottype 3"},
        {"",""},{"4","forall set bottype 4"},{"5","forall set bottype 5"},{"6","forall set bottype 6"},{"",""},
        {"BotSpeed","set botspeed ~"},{"0","set botspeed 0"},{"5","set botspeed 5"},{"10","set botspeed 10"},{"20","set botspeed 20"},
        {"",""},{"50","set botspeed 50"},{"100","set botspeed 100"},{"200","set botspeed 200"},{"300","set botspeed 300"},
        {"",""},{"500","set botspeed 500"},{"750","set botspeed 750"},{"1000","set botspeed 1000"},{"1500","set botspeed 1500"},
        {"AllSpeed","forall set botspeed ~"},{"0","forall set botspeed 0"},{"5","forall set botspeed 5"},{"10","forall set botspeed 10"},{"20","forall set botspeed 20"},
        {"",""},{"50","forall set botspeed 50"},{"100","forall set botspeed 100"},{"200","forall set botspeed 200"},{"300","forall set botspeed 300"},
        {"",""},{"500","forall set botspeed 500"},{"750","forall set botspeed 750"},{"1000","forall set botspeed 1000"},{"1500","forall set botspeed 1500"},
        {"QPModOff",""},{"-Hold","set mod2 0"},{"-Messier","set mod3 0"},{"-Gravity","set mod4 0"},{"-Strength","set mod5 0"},
        {"",""},{"-Holes","set mod6 0"},{"-Invis","set mod7 0"},{"-AllSpin","set mod8 0"},{"-Expert","set mod9 0"},
        {"QPModOn",""},{"Hold","set mod2 1"},{"Messier","set mod3 1"},{"Gravity","set mod4 1"},{"Strength","set mod5 1"},
        {"",""},{"Holes","set mod6 1"},{"Invis","set mod7 1"},{"AllSpin","set mod8 1"},{"Expert","set mod9 1"},
        {"QPModRev",""},{"+Hold","set mod2 2"},{"+Messier","set mod3 2"},{"+Gravity","set mod4 2"},{"+Strength","set mod5 2"},
        {"",""},{"+Holes","set mod6 2"},{"+Invis","set mod7 2"},{"+AllSpin","set mod8 2"},{"+Expert","set mod9 2"},
        {"Operate",""},{"1Garb","garbage 1"},{"2Garb","garbage 2"},{"4Garb","garbage 4"},{"10Garb","garbage 10"},
        {"",""},{"1Damage","damage 1"},{"2Damage","damage 2"},{"4Damage","damage 4"},{"10Damage","damage 10"},
        {"",""},{"Clear","fill 1 1 99 99 0"},{"FillAll","fill 1 1 99 99"},{"Lock","lock"},{"Waste","waste"},
        {"GoalLine","set targetline ~"},{"Off","set targetline 0"},{"10","set targetline 10"},{"20","set targetline 20"},{"40","set targetline 40"},
        {"",""},{"100","set targetline 100"},{"200","set targetline 200"},{"500","set targetline 500"},{"1000","set targetline 1000"},
        {"GoalPiece","set targetpiece ~"},{"Off","set targetpiece 0"},{"25","set targetpiece 25"},{"50","set targetpiece 50"},{"100","set targetpiece 100"},
        {"",""},{"250","set targetpiece 250"},{"500","set targetpiece 500"},{"1000","set targetpiece 1000"},{"2000","set targetpiece 2000"},
        {"GoalAtk","set targetattack ~"},{"Off","set targetattack 0"},{"10","set targetattack 10"},{"20","set targetattack 20"},{"40","set targetattack 40"},
        {"",""},{"100","set targetattack 100"},{"200","set targetattack 200"},{"500","set targetattack 500"},{"1000","set targetattack 1000"},
        {"GoalScore","set targetscore ~"},{"Off","set targetscore 0"},{"1000","set targetscore 1000"},{"5000","set targetscore 5000"},{"10000","set targetscore 10000"},
        {"",""},{"50000","set targetscore 50000"},{"100000","set targetscore 100000"},{"500000","set targetscore 500000"},{"1000000","set targetscore 1000000"},
        {"TimeLim","set targettime ~"},{"Off","set targettime 0"},{"10","set targettime 10000"},{"30","set targettime 30000"},{"60","set targettime 60000"},
        {"",""},{"120","set targettime 120000"},{"180","set targettime 180000"},{"300","set targettime 300000"},{"600","set targettime 600000"},
        {"BaseLev","gamerule levelbase ~"},{"0","gamerule levelbase 0"},{"2","gamerule levelbase 2"},{"5","gamerule levelbase 5"},{"10","gamerule levelbase 10"},
        {"",""},{"15","gamerule levelbase 15"},{"18","gamerule levelbase 18"},{"20","gamerule levelbase 20"},{"30","gamerule levelbase 30"},
        {"StartLev","gamerule levelstart ~"},{"0","gamerule levelstart 0"},{"2","gamerule levelstart 2"},{"5","gamerule levelstart 5"},{"10","gamerule levelstart 10"},
        {"",""},{"15","gamerule levelstart 15"},{"18","gamerule levelstart 18"},{"20","gamerule levelstart 20"},{"30","gamerule levelstart 30"},
        {"LevLine","gamerule levelline ~"},{"None","gamerule levelline 0"},{"5","gamerule levelline 5"},{"10","gamerule levelline 10"},{"20","gamerule levelline 20"},
        {"IncLine","gamerule increaseline ~"},{"0","gamerule increaseline 0"},{"1","gamerule increaseline 1"},{"5","gamerule increaseline 5"},{"10","gamerule increaseline 10"},
        {"LevPiece","gamerule levelpiece ~"},{"None","gamerule levelpiece 0"},{"25","gamerule levelpiece 25"},{"50","gamerule levelpiece 50"},{"100","gamerule levelpiece 100"},
        {"IncPiece","gamerule increasepiece ~"},{"0","gamerule increasepiece 0"},{"5","gamerule increasepiece 5"},{"10","gamerule increasepiece 10"},{"25","gamerule increasepiece 25"},
        {"LevTime","gamerule leveltime ~"},{"None","gamerule leveltime 0"},{"30","gamerule leveltime 30"},{"60","gamerule leveltime 60"},{"120","gamerule leveltime 120"},
        {"IncTime","gamerule increasetime ~"},{"0","gamerule increasetime 0"},{"5","gamerule increasetime 5"},{"10","gamerule increasetime 10"},{"30","gamerule increasetime 30"},
        {"LevAtk","gamerule levelattack ~"},{"None","gamerule levelattack 0"},{"10","gamerule levelattack 5"},{"25","gamerule levelattack 25"},{"50","gamerule levelattack 50"},
        {"IncAtk","gamerule increaseattack ~"},{"0","gamerule increaseattack 0"},{"1","gamerule increaseattack 1"},{"5","gamerule increaseattack 5"},{"10","gamerule increaseattack 10"},
        {"20GLev","gamerule levelmaster ~"},{"1","gamerule levelmaster 1"},{"5","gamerule levelmaster 5"},{"10","gamerule levelmaster 10"},{"15","gamerule levelmaster 15"},
        {"",""},{"18","gamerule levelmaster 18"},{"20","gamerule levelmaster 20"},{"30","gamerule levelmaster 30"},{"None","gamerule levelmaster max"},
        {"LevScale","gamerule levelratio ~"},{"0","gamerule levelratio 0"},{"0.001","gamerule levelratio 1"},{"0.002","gamerule levelratio 2"},{"0.005","gamerule levelratio 5"},
        {"",""},{"0.007","gamerule levelratio 7"},{"0.01","gamerule levelratio 10"},{"0.02","gamerule levelratio 20"},{"0.05","gamerule levelratio 50"},
        {"",""},{"0.075","gamerule levelratio 75"},{"0.1","gamerule levelratio 100"},{"0.2","gamerule levelratio 200"},{"0.25","gamerule levelratio 250"},
        {"",""},{"0.3","gamerule levelratio 300"},{"0.5","gamerule levelratio 500"},{"0.75","gamerule levelratio 750"},{"1","gamerule levelratio 1000"},
        {"LevType",""},{"Default","gamerule scaletype default"},{"Div","gamerule scaletype div"},{"Dec","gamerule scaletype dec"},{"Exp","gamerule scaletype exp"},
        {"Style",""},{"Default","config style default"},{"Classic","config style classic"},{"Arcade","config style arcade"},{"Simple","config style simple"},
        {"KeyMap",""},{"Left","keymap left ~"},{"Right","keymap right ~"},{"SoftDrop","keymap down ~"},{"HardDrop","keymap drop ~"},
        {"",""},{"Rotate","keymap rotate ~"},{"CW","keymap cw ~"},{"CCW","keymap ccw ~"},{"Half","keymap half ~"},
        {"",""},{"Hold","keymap hold ~"},{"Retry","keymap retry ~"},{"Reset","keymap reset ~"},{"Sonic","keymap sonic ~"},
        {"",""},{"Undo","keymap undo ~"},{"Flip","keymap flip ~"},{"Up","keymap up ~"},{"Waste","keymap waste ~"},
        {"",""},{"Lock","keymap lock ~"},{"Even","keymap even ~"},{"KO\'s","keymap ko ~"},{"Random","keymap random ~"},
        {"",""},{"Payback","keymap payback ~"},{"Badge","keymap badge ~"},{"Attacker","keymap attacker ~"},{"",""},
        {"MoveEff",""},{"On","config moveeffect true"},{"Off","config moveeffect false"},{"",""},{"",""},
        {"SpinEff",""},{"On","config spineffect true"},{"Off","config spineffect false"},{"",""},{"",""},
        {"DropEff",""},{"On","config dropeffect true"},{"Off","config dropeffect false"},{"",""},{"",""},
        {"RotEff",""},{"On","config rotateeffect true"},{"Off","config rotateeffect false"},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        };
        if (Command!="") Option.clear();
        if ((Plrs)&&(!Con)) Option={{"Pause","~"},{"",""},{"",""},{"",""},{"",""},
        {"Retry","abort"},{"",""},{"",""},{"",""},{"",""},
        {"Quit","quit"}};
        if ((!Plrs)&&(Command=="")) Option= {
        {"DefRot",""},{"CCW","config defaultrotate ccw"},{"CW","config defaultrotate cw"},{"",""},{"",""},
        {"DAS","config das ~"},{"0","config das 0"},{"0.05","config das 50"},{"0.06","config das 60"},{"0.08","config das 80"},
        {"",""},{"0.1","config das 100"},{"0.12","config das 120"},{"0.167","config das 167"},{"0.2","config das 200"},
        {"",""},{"0.25","config das 250"},{"0.3","config das 300"},{"0.5","config das 500"},{"1","config das 1000"},
        {"ARR","config arr ~"},{"0","config arr 0"},{"0.01","config arr 10"},{"0.02","config arr 20"},{"0.033","config arr 33"},
        {"",""},{"0.05","config arr 50"},{"0.1","config arr 100"},{"0.15","config arr 150"},{"0.2","config arr 200"},
        {"SDDAS","config dropdas ~"},{"0","config dropdas 0"},{"0.05","config dropdas 50"},{"0.06","config dropdas 60"},{"0.08","config dropdas 80"},
        {"",""},{"0.1","config dropdas 100"},{"0.12","config dropdas 120"},{"0.15","config dropdas 150"},{"0.2","config dropdas 200"},
        {"",""},{"0.25","config dropdas 250"},{"0.3","config dropdas 300"},{"0.5","config dropdas 500"},{"1","config dropdas 1000"},
        {"SDARR","config droparr ~"},{"0","config droparr 0"},{"0.01","config droparr 10"},{"0.02","config droparr 20"},{"0.05","config droparr 50"},
        {"",""},{"0.075","config droparr 75"},{"0.1","config droparr 100"},{"0.15","config droparr 150"},{"0.2","config droparr 200"},
        {"DCD","config dcd ~"},{"0","config dcd 0"},{"0.01","config dcd 10"},{"0.02","config dcd 20"},{"0.03","config dcd 30"},
        {"",""},{"0.05","config dcd 50"},{"0.075","config dcd 75"},{"0.1","config dcd 100"},{"0.15","config dcd 150"},
        {"",""},{"0.2","config dcd 200"},{"0.5","config dcd 500"},{"1","config dcd 1000"},{"Infinity","config dcd max"},
        {"HCD","config hcd ~"},{"0","config hcd 0"},{"0.01","config hcd 10"},{"0.02","config hcd 20"},{"0.03","config hcd 30"},
        {"",""},{"0.05","config hcd 50"},{"0.075","config hcd 75"},{"0.1","config hcd 100"},{"0.15","config hcd 150"},
        {"",""},{"0.2","config hcd 200"},{"0.5","config hcd 500"},{"1","config hcd 1000"},{"Infinity","config hcd max"},
        {"Style",""},{"Default","config style default"},{"Classic","config style classic"},{"Arcade","config style arcade"},{"Simple","config style simple"},
        {"KeyMap",""},{"Left","keymap left ~"},{"Right","keymap right ~"},{"SoftDrop","keymap down ~"},{"HardDrop","keymap drop ~"},
        {"",""},{"Rotate","keymap rotate ~"},{"CW","keymap cw ~"},{"CCW","keymap ccw ~"},{"Half","keymap half ~"},
        {"",""},{"Hold","keymap hold ~"},{"Retry","keymap retry ~"},{"Reset","keymap reset ~"},{"Sonic","keymap sonic ~"},
        {"",""},{"Undo","keymap undo ~"},{"Flip","keymap flip ~"},{"Up","keymap up ~"},{"Waste","keymap waste ~"},
        {"",""},{"Lock","keymap lock ~"},{"Even","keymap even ~"},{"KO\'s","keymap ko ~"},{"Random","keymap random ~"},
        {"",""},{"Payback","keymap payback ~"},{"Badge","keymap badge ~"},{"Attacker","keymap attacker ~"},{"",""},
        {"MoveEff",""},{"On","config moveeffect true"},{"Off","config moveeffect false"},{"",""},{"",""},
        {"SpinEff",""},{"On","config spineffect true"},{"Off","config spineffect false"},{"",""},{"",""},
        {"DropEff",""},{"On","config dropeffect true"},{"Off","config dropeffect false"},{"",""},{"",""},
        {"RotEff",""},{"On","config rotateeffect true"},{"Off","config rotateeffect false"},{"",""},{"",""},
        {"1P",""},{"Normal","launch x"},{"Marathon","launch marathon"},{"Sprint","launch sprint"},{"Ultra","launch ultra"},
        {"",""},{"Zenith","launch zenith"},{"Zen","launch zen"},{"Classic","launch classic"},{"Arcade","launch arcade"},
        {"",""},{"Dig","launch dig"},{"4-Wide","launch x 4w"},{"M5","launch x m5"},{"M5-","launch x 13w 26h mm5 flip"},
        {"",""},{"M123","launch x m123"},{"M12345","launch x m12345"},{"M12345-","launch x mm12345 13w 25h flip"},{"M123456-","launch x mm123456 15w 30h flip"},
        {"Marathon",""},{"Lv. 5","launch marathon lv5"},{"Lv. 10","launch marathon lv10"},{"Lv. 15","launch marathon lv15"},{"Lv. 20","launch marathon lv20"},
        {"Sprint",""},{"10L","launch sprint 10l"},{"20L","launch sprint 20l"},{"40L","launch sprint 40l"},{"100L","launch sprint 40l"},
        {"",""},{"200L","launch sprint 200l"},{"500L","launch sprint 500l"},{"1000L","launch sprint 1000l"},{"Zenith","launch zenithsprint"},
        {"Ultra",""},{"30s","launch ultra 30s"},{"60s","launch ultra 60s"},{"100s","launch ultra 100s"},{"120s","launch ultra 120s"},
        {"",""},{"180s","launch ultra 180s"},{"300s","launch ultra 300s"},{"600s","launch ultra 600s"},{"",""},
        {"Battle",""},{"2P","launch battle"},{"10P","launch battle 10p"},{"31P","launch battle 31p"},{"100P","launch battle 100p"},
        {"Zenith",""},{"10P","launch zenith 10p"},{"31P","launch zenith 31p"},{"50P","launch zenith 50p"},{"100P","launch zenith 100p"},
        {"Survive",""},{"0.5","launch survive 500gr"},{"1","launch survive 1000gr"},{"2","launch survive 2000gr"},{"5","launch survive 5000gr"},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        };
        int SpaceC = 0;
        for (char ch : Command) SpaceC+=(!ch);
        if ((Command.size()>6)&&(Command.substr(0,6)=="keymap")&&(SpaceC==2)) Option={
        {"",""},{"Back","~"},{"",""},{"",""},{"None","~none"},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"Up","~up"},{"Down","~down"},{"Left","~left"},{"Right","~right"},
        {"",""},{"Space","~space"},{"Shift","~shift"},{"Tab","~tab"},{"Enter","~enter"},
        {"",""},{"Caps","~caps"},{"Ctrl","~ctrl"},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"A","~a"},{"B","~b"},{"C","~c"},{"D","~d"},
        {"",""},{"E","~e"},{"F","~f"},{"G","~g"},{"H","~h"},
        {"",""},{"I","~i"},{"J","~j"},{"K","~k"},{"L","~l"},
        {"",""},{"M","~m"},{"N","~n"},{"O","~o"},{"P","~p"},
        {"",""},{"Q","~q"},{"R","~r"},{"S","~s"},{"T","~t"},
        {"",""},{"U","~u"},{"V","~v"},{"W","~w"},{"X","~x"},
        {"",""},{"Y","~y"},{"Z","~z"},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"0","~0"},{"1","~1"},{"2","~2"},{"3","~3"},
        {"",""},{"4","~4"},{"5","~5"},{"6","~6"},{"7","~7"},
        {"",""},{"8","~8"},{"9","~9"},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        };
        if ((Command.size()>13)&&(Command.substr(0,8)=="gamerule")&&(Command.substr(9,5)=="piece")&&(SpaceC==2)) Option={
        {"",""},{"Back","~"},{"OK","~ "},{"",""},{"Clear","gamerule piece "},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"Garb","+k154"},{"Solid","+k153"},{"Spin","+k152"},{"Bomb","+k151"},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"A","+a"},{"",""},{"B","+b"},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"M3","+cd"},{"",""},{"C","+c"},{"D","+d"},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"M4","+ijlostz"},{"M4-","+ijost"},{"",""},{"",""},
        {"",""},{"I","+i"},{"J","+j"},{"L","+l"},{"O","+o"},
        {"",""},{"S","+s"},{"T","+t"},{"Z","+z"},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"M5","+efhi5j5l5npqrs5t5uvwxyz5"},{"M5-","ehi5j5prs5t5uvwx"},{"",""},{"",""},
        {"",""},{"E","+e"},{"F","+f"},{"H","+h"},{"I","+i5"},
        {"",""},{"J","+j5"},{"L","+l5"},{"N","+n"},{"P","+p"},
        {"",""},{"Q","+q"},{"R","+r"},{"S","+s5"},{"T","+t5"},
        {"",""},{"U","+u"},{"V","+v"},{"W","+w"},{"X","+x"},
        {"",""},{"Y","+y"},{"Z","+z5"},{"",""},{"",""},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"M6","+k30k31k32k33k34k35k36k37k38k39k40k41k42k43k44k45k46k47k48k49k50k51k52k53k54k55k56k57k58k59k60k61k62k63k64k65k66k67k68k69k70k71k72k73k74k75k76k77k78k79k80k81k82k83k84k85k86k87k88k89"},{"M6-","+k30k31k32k33k34k35k36k37k38k39k40k42k44k46k48k50k52k54k56k58k60k62k64k66k68k70k72k74k76k78k80k82k84k86k88"},{"",""},{"",""},
        {"",""},{Str(132),"+k30"},{"d","+k31"},{Str(133),"+k32"},{"0","+k33"},
        {"",""},{"e","+k34"},{Str(134),"+k35"},{"x","+k36"},{Str(145),"+k37"},
        {"",""},{"c","+k38"},{"|","+k39"},{Str(135),"+k40"},{Str(136),"+k41"},
        {"",""},{"y","+k42"},{"1","+k43"},{"n","+k44"},{"h","+k45"},
        {"",""},{"p","+k46"},{"q","+k47"},{"f","+48"},{Str(137),"+k49"},
        {"",""},{"<","+k50"},{">","+k51"},{"r","+k52"},{Str(138),"+k53"},
        {"",""},{Str(139),"+k54"},{Str(140),"+k55"},{"7","+k56"},{Str(141),"+k57"},
        {"",""},{Str(142),"+k58"},{Str(143),"+k59"},{"$","+k60"},{"%","+k61"},
        {"",""},{"4","+k62"},{Str(144),"+k63"},{"G","+k64"},{"?","+k65"},
        {"",""},{"/","+k66"},{"\\","+k67"},{Str(146),"+k68"},{Str(147),"+k69"},
        {"",""},{Str(148),"+k70"},{Str(149),"+k71"},{"K","+k72"},{Str(150),"+k73"},
        {"",""},{Str(151),"+k74"},{Str(152),"+k75"},{"2","+k76"},{"5","+k77"},
        {"",""},{"{","+k78"},{"}","+k79"},{Str(153),"+k80"},{"u","+k81"},
        {"",""},{Str(154),"+k82"},{Str(155),"+k83"},{Str(156),"+k84"},{Str(157),"+k85"},
        {"",""},{Str(158),"+k86"},{"a","+k87"},{"M","+k88"},{"m","+k89"},
        {"",""},{"",""},{"",""},{"",""},{"",""},
        {"",""},{"@","+k90"},{"o","+k91"},{"^","+k92"},{",","+k93"},
        {"",""},{":","+k94"},{"(","+k95"},{")","+k96"},{";","+k97"},
        {"",""},{"[","+k98"},{"]","+k99"},{"#","+k100"},{"",""},
        };
        int oid = 0;
        int sid = -1;
        int RowCnt = 50;
        int RowDis = 17; 
        int RowLen = 15;
        int ColDis = 65;
        int ColLen = 62;
        int LColDis = 350;
        int TextSz = 7;
        if (Option.size()<=240) {
            RowDis *= 1.5;
            RowLen *= 1.5;
            ColDis *= 1.5;
            ColLen *= 1.5;
            LColDis *= 1.5;
            TextSz *= 1.5;
            RowCnt = 28;
        }
        for (int i=0; i<Option.size()/5+2; ++i) {
            for (int j=0; j<5; ++j) {
                if (oid>=Option.size()) break;
                bool ok = ((p.y>=(i%RowCnt)*RowDis-30)&&(p.y<=(i%RowCnt)*RowDis-30+RowLen)&&(p.x>=-95+LColDis*(i/RowCnt)+j*ColDis)&&(p.x<=-95+LColDis*(i/RowCnt)+j*ColDis+ColLen));
                if (Option[oid].second=="") {
                    ok = false;
                    if (Option[oid].first=="") {
                        ++oid; continue;
                    }
                }
                if (ok) sid=oid;
                Rectangle((i%RowCnt)*RowDis-30,-95+j*ColDis+LColDis*(i/RowCnt),RowLen,ColLen,0x888888);
                Rectangle((i%RowCnt)*RowDis-30,-95+j*ColDis+LColDis*(i/RowCnt),RowLen-1,ColLen-1,0xCCCCCC);
                Rectangle((i%RowCnt)*RowDis-30+1,-95+j*ColDis+LColDis*(i/RowCnt)+1,RowLen-2,ColLen-2,(ok)?0x66CCFF:0xAAAAAA);
                PaintStrM(Option[oid].first,(i%RowCnt)*RowDis-30+ColDis/15,-95+j*ColDis+LColDis*(i/RowCnt)+ColDis/2-TextSz,TextSz,(oid%5)?0x666666:0x333333);
                ++oid;
            }
            if (oid>=Option.size()) break;
        }
        int pcnt = 0;
        double rat = double(max(1,tm));
        for (int i=0; i<PQu.size(); ++i) {
            Particle o = PQu[i];
            Poly(o.x, o.y, o.sz*sz/15.0, o.n, o.clr, o.th);
            o.x+=o.vx*rat; o.y+=o.vy*rat;
            o.vx+=o.ax*rat; o.vy+=o.ay*rat;
            o.sz -= o.de*rat*0.5;
            if (o.sz>0.0) PQu[pcnt++]=o;
        }
        while (PQu.size()>pcnt) PQu.pop_back();
        int tcnt = 0;
        for (int i=0; i<TQu.size(); ++i) {
            FloatText o = TQu[i];
            PaintStrM(o.str, o.x, o.y, o.sz, abs(o.clr), o.bd);
            o.bd -= o.de*rat*0.5;
            if ((Bot)&&(sz<10)&&(o.clr>=0)) o.bd=-1.0;
            if (o.bd>0.0) TQu[tcnt++]=o;
        }
        while (TQu.size()>tcnt) TQu.pop_back();
        bool nw = ((CheckKey(VK_LBUTTON))||(CheckKey(VK_RBUTTON)));
        SelX=SelY=0;
        for (int i=-11; i<=100; ++i) {
            if (!Zen) break;
            if ((Command=="")&&(Con)) break;
            if (!i) continue;
            for (int j=1; j<=100; ++j) {
                if ((20*(DX0-i)<=p.y)&&(p.y<=20*(DX0-i+1))&&(20*(j-1)+400<=p.x)&&(p.x<=20*j+400)) {
                    SelX=i; SelY=j;
                }
            }
        }
        vector<ClassAtkEff> nwAtkEff;
        for (ClassAtkEff oo : AtkEff) {
            ClassAtkEff o = oo;
            Poly(o.x, o.y, o.sz*5, 8, o.clr, o.th);
            o.th += tm*0.001;
            double tx=MX[o.tar], ty=MY[o.tar];
            double dis = (o.x-tx)*(o.x-tx)+(o.y-ty)*(o.y-ty);
            if (dis<0.1) continue;
            double td = atan2(ty-o.y,tx-o.x);
            double pi = acos(-1.0);
            //if (o.dir+pi<td) o.dir+=pi*2.0;
            //if (o.dir-pi>td) o.dir-=pi*2.0;
            o.dir = td;
            //if (o.dir<0.0) o.dir+=pi*2.0;
            //if (o.dir>=pi*2.0) o.dir-=pi*2.0;
            double dd = min(double(tm),sqrt(dis));
            o.x+=dd*cos(o.dir); o.y+=dd*sin(o.dir);
            nwAtkEff.push_back(o);
        }
        AtkEff = nwAtkEff;
        if (nw) {
            // Square(sz*double(DX-i),sz*double(j-1),sz*ss,clr)
            int clp = AddTp;
            int clr = Piece[clp][0].clr;
            if (Press) PQu.push_back({p.y,p.x,0,0,0,0,30,0.2,rndf()*acos(-1.0)*2.0,20,clr});
            else {
                if (sid>=0) {
                    Con = true;
                    ForceExecute = Option[sid].second;
                    LButtonCD = true;
                    for (int i=0; i<ForceExecute.size(); ++i) {
                        if (ForceExecute[i]==' ') ForceExecute[i]=0;
                    }
                }
                double th = rndf()*acos(-1.0)*2.0;
                PQu.push_back({p.y,p.x,0,0,0,0,60,0.1,rndf()*acos(-1.0)*2.0,20,clr});
                for (int i=0; i<5; ++i) {
                    th += acos(-1.0)*2.0/5.0;
                    PQu.push_back({p.y,p.x,sin(th)*0.1,cos(th)*0.1,0,0,30,0.02,rndf()*acos(-1.0)*2.0,5,clr});
                }
            }
        }
        else if (Press) _fstl=false;
        Press = nw;
        int bg = Mix(0xFFFFFF,0x000000,BackgroundRatio);
        RespondTime = max(0,RespondTime-tm);
        if (RespondTime) PaintStrL(Respond, -65, 20, 9, Mix(RespondColor,bg,double(RespondTime)/10000.0));
        sprintf(buf, "    [%u]", FP.size());
        PaintStrL(buf, -95, 0, 9, 0xEE82EE);
        if (Con) {
            vector<string> Hint = GetHint(Command);
            for (int i=0; i<Hint.size(); ++i) PaintStrL(Hint[i], -40+15*(i%40), 20+500*(i/40), 9, 0xFFFFFF);
        }
        if (!Con) {
            PaintStrL((Command.size())?"> "+Command:"  Press [Esc] to pause...", -80, 0, 9, 0x888888);
            //PaintStrL(str, -80, 0, 9, 0x888888);
            return;
        }
        if ((Con)&&(sid>=0)) {
            PaintStrL(": "+Option[sid].second, -80, 0, 9, 0xFDD000);
            return;
        }
        if ((Con)&&(Command=="")) {
            PaintStrL("  Press [Esc] to resume or input command ending with [Enter]...", -80, 0, 9, 0x39C5BB);
            return;
        }
        PaintStrL("> "+Command, -80, 0, 9, 0x00FFCC);
    }
    int QueryVal(string str) {
        if (str=="complete") return Complete;
        if (str=="levelstart") return LevStart;
        if (str=="levelbase") return LevBase;
        if (str=="levelline") return LevLine;
        if (str=="leveltime") return LevTime;
        if (str=="levelpiece") return LevPiece;
        if (str=="levelattack") return LevAttack;
        if (str=="increaseline") return LevLineInc;
        if (str=="increasetime") return LevTimeInc;
        if (str=="increasepiece") return LevPieceInc;
        if (str=="increaseattack") return LevAttackInc;
        if (str=="levelmaster") return MasterBeg;
        if (str=="levelratio") return Diff;
        if (str=="targetpiece") return TarPiece;
        if (str=="targettime") return TarTime;
        if (str=="targetline") return TarLine;
        if (str=="targetattack") return TarAttack;
        if (str=="targetscore") return TarScore; 
        if (str=="passthrough") return Passthrough;
        if (str=="blockheight") return QueryHeight();
        if (str=="sumpiece") return SumPiece;
        if (str=="sumline") return SumLine;
        if (str=="sumdig") return SumDig;
        if (str=="sumattack") return SumAttack;
        if (str=="staticheight") return StaticHeight;
        if (str=="startheight") return StartHeight;
        if (str=="usemove") return AllowMove;
        if (str=="userotate") return AllowRot;
        if (str=="use2rotate") return Allow2Rot;
        if (str=="usehalf") return AllowHalf;
        if (str=="usehard") return AllowHard;
        if (str=="usesoft") return AllowSoft;
        if (str=="usesonic") return AllowSonic; 
        if (str=="useflip") return AllowFlip;
        if (str=="useup") return AllowUp;
        if (str=="uselock") return AllowLock;
        if (str=="usedeep") return AllowDeep;
        if (str=="wastelimit") return WasteLim;
        if (str=="vs") return SumAttack+SumDig;
        if (str=="holdpiece") return Hold;
        if (str=="pid") return Pid;
        if (str=="tar") return Tar;
        if (str=="attacktype") return AtkType;
        if (str=="receive") {
            int tot=0; for (pair<int,pair<int,ll> > o : Rec) tot+=o.first;
            return tot+ActiveGarb.size();
        }
        if (str=="queuegarbage") {
            int tot=0; for (pair<int,pair<int,ll> > o : Rec) tot+=o.first;
            return tot;
        }
        if (str=="activegarbage") return ActiveGarb.size();
        if (str=="bot") return Bot;
        if (str=="bottype") return Plr;
        if (str=="point") return Wins;
        if (str=="height") return DX;
        if (str=="realheight") return LX;
        if (str=="vanish") return VanishHeight;
        if (str=="width") return LY;
        if (str=="ko") return KO;
        if (str=="badge") return SKO;
        if (str=="botspeed") return OperTime;
        if (str=="over") return Over;
        if (str=="next") return ViewNxt;
        if (str=="history") return His;
        if (str=="roll") return Rol;
        if (str=="extra") return Ext;
        if (str=="reset") return ResetLim;
        if (str=="lock") return BaseLockL;
        if (str=="groundlock") return GLockL;
        if (str=="forcelock") return FLockL;
        if (str=="drop") return BaseDropL;
        if (str=="openerphrase") return OpenerPhrase;
        if (str=="garbagepreview") return GarbagePreview;
        if (str=="garbagegap") return GarbageGap;
        if (str=="garbagedelay") return GarbDelay;
        if (str=="garbagerise") return GarbRise;
        if (str=="initfacing") return InitFacing;
        if (str=="hold") return HoldRule;
        if (str=="sequence") return Sequence;
        if (str=="das") return DAS;
        if (str=="arr") return ARR;
        if (str=="dropdas") return SDDAS;
        if (str=="droparr") return SDARR; 
        if (str=="dcd") return DCD;
        if (str=="hcd") return HCD;
        if (str=="deathare") return DeathARE;
        if (str=="are") return ARE;
        if (str=="lcd") return LCD;
        if (str=="drd") return DRD;
        if (str=="shadow") return ShowShadow;
        if (str=="roundheight") return RoundHeight;
        if (str=="stock") return Stock;
        if (str=="life") return Life;
        if (str=="mod2") return ModHold;
        if (str=="mod3") return ModMess;
        if (str=="mod4") return ModGravity;
        if (str=="mod5") return ModStrength;
        if (str=="mod6") return ModDivergence;
        if (str=="mod7") return ModInvisible;
        if (str=="mod8") return ModSpin;
        if (str=="mod9") return ModExpert;
        return ERR;
    }
    int ChangeVal(string str, int x) {
        if (x==ERR) return ERR;
        if (str=="complete") Complete=bool(x);
        else if (str=="levelstart") LevStart=x;
        else if (str=="levelbase") LevBase=x;
        else if (str=="levelline") LevLine=x;
        else if (str=="leveltime") LevTime=x;
        else if (str=="levelpiece") LevPiece=x;
        else if (str=="levelattack") LevAttack=x;
        else if (str=="increaseline") LevLineInc=x;
        else if (str=="increasetime") LevTimeInc=x;
        else if (str=="increasepiece") LevPieceInc=x;
        else if (str=="increaseattack") LevAttackInc=x;
        else if (str=="levelmaster") MasterBeg=x;
        else if (str=="levelratio") Diff=x;
        else if (str=="targetpiece") TarPiece=x;
        else if (str=="targettime") TarTime=x;
        else if (str=="targetline") TarLine=x;
        else if (str=="targetattack") TarAttack=x;
        else if (str=="targetscore") TarScore=x;
        else if (str=="passthrough") Passthrough=x;
        else if (str=="sumpiece") SumPiece=x;
        else if (str=="sumline") SumLine=x;
        else if (str=="sumdig") SumDig=x;
        else if (str=="sumattack") SumAttack=x;
        else if (str=="staticheight") StaticHeight=x;
        else if (str=="startheight") StartHeight=x;
        else if (str=="usemove") AllowMove=bool(x);
        else if (str=="userotate") AllowRot=bool(x);
        else if (str=="use2rotate") Allow2Rot=bool(x);
        else if (str=="usehalf") AllowHalf=bool(x);
        else if (str=="usehard") AllowHard=bool(x);
        else if (str=="usesoft") AllowSoft=bool(x);
        else if (str=="usesonic") AllowSonic=bool(x);
        else if (str=="useflip") AllowFlip=bool(x);
        else if (str=="useup") AllowUp=bool(x); 
        else if (str=="uselock") AllowLock=bool(x); 
        else if (str=="usedeep") AllowDeep=bool(x);
        else if (str=="wastelimit") WasteLim=x;
        else if (str=="holdpiece") {
            if (!CheckBlockType(x)) return ERR;
            Hold = x;
        }
        else if (str=="pid") {
            if ((!x)||(!CheckBlockType(x))) return ERR;
            Pid = x;
        }
        else if (str=="tar") {
            if (x>=Plrs) return ERR;
            Tar = x;
        }
        else if (str=="attacktype") {
            if ((!x)||(x>6)) return ERR;
            AtkType = x;
        }
        else if (str=="bot") Bot=x;
        else if (str=="bottype") Plr=x;
        else if (str=="point") Wins=x;
        else if (str=="height") {
            if ((x<2)||(x>100)) return ERR;
            DX=x; LX=max(LX,DX);
            VanishHeight = max(VanishHeight,DX+2);
        }
        else if (str=="realheight") {
            if ((x<2)||(x>100)) return ERR;
            LX=x; DX=min(DX,LX);
        }
        else if (str=="vanish") VanishHeight=x;
        else if (str=="width") {
            if ((x<2)||(x>50)) return ERR;
            LY = x;
        }
        else if (str=="ko") KO=x;
        else if (str=="badge") SKO=x;
        else if (str=="botspeed") OperTime=x;
        else if (str=="next") {
            if (x>10) return ERR;
            ViewNxt = x;
        }
        else if (str=="history") {
            if (x>100) return ERR;
            His = x;
        }
        else if (str=="roll") {
            if ((!x)||(x>100)) return ERR;
            Rol = x;
        }
        else if (str=="extra") {
            if (x>100) return ERR;
            Ext = x;
        }
        else if (str=="reset") ResetLim=x;
        else if (str=="lock") BaseLockL=x;
        else if (str=="groundlock") GLockL=x;
        else if (str=="forcelock") FLockL=x;
        else if (str=="drop") BaseDropL=x;
        else if (str=="openerphrase") OpenerPhrase=x;
        else if (str=="garbagepreview") GarbagePreview=x;
        else if (str=="garbagegap") GarbageGap=x;
        else if (str=="garbagedelay") GarbDelay=x;
        else if (str=="garbagerise") GarbRise=x;
        else if (str=="initfacing") InitFacing=x&3;
        else if (str=="hold") {
            if (x>2) return ERR;
            HoldRule = x;
        }
        else if (str=="sequence") {
            if (x>2) return ERR;
            Sequence = x;
        }
        else if (str=="das") DAS=x;
        else if (str=="arr") ARR=x;
        else if (str=="dropdas") SDDAS=x;
        else if (str=="droparr") SDARR=x;
        else if (str=="dcd") DCD=x;
        else if (str=="hcd") HCD=x;
        else if (str=="deathare") DeathARE=x;
        else if (str=="are") ARE=x;
        else if (str=="lcd") LCD=x;
        else if (str=="drd") DRD=x;
        else if (str=="shadow") ShowShadow=bool(x);
        else if (str=="roundheight") RoundHeight=x;
        else if (str=="stock") Stock=x;
        else if (str=="life") Life=x;
        else if (str=="mod2") {
            ModHold=min(x,2); HoldRule=(ModHold)?0:((Zen)?2:1);
            Sequence = (ModHold==2)?0:1;
            ViewNxt = (ModHold==2)?1:5;
            if (ModHold==2) {
                His=0; Rol=1;
            }
        }
        else if (str=="mod3") {
            ModMess=min(x,2); LCD=(ModMess==2)?1150:0;
        }
        else if (str=="mod4") ModGravity=min(x,2);
        else if (str=="mod5") {
            if (ModStrength==2) DX=min(LX,DX+6);
            ModStrength = min(x,2);
            if (ModStrength==2) DX=max(2,DX-6);
        }
        else if (str=="mod6") ModDivergence=min(x,2);
        else if (str=="mod7") ModInvisible=min(x,2);
        else if (str=="mod8") ModSpin=min(x,2);
        else if (str=="mod9") {
            ModExpert=min(x,2); GarbRise=(ModExpert)?0:100;
        }
        else return ERR;
        return 0;
    }
} Global;
Board Plr[111];
int curh[999]; bool KOCount[999], ConKey[999];
vector<int> TransferBag(string str) {
    vector<int> res;
    while (str.size()) {
        char p=str.back(); int q=0; str.pop_back();
        int pw = 1;
        while ((p>='0')&&(p<='9')) {
            if (str.empty()) return vector<int>();
            q+=pw*int(p-'0'); pw*=10;
            p=str.back(); str.pop_back();
        }
        char dy = 0;
        int dg = 0;
        if ((p>='a')&&(p<='z')) p+='A'-'a';
        if (p=='A') {
            if ((!q)||(q==1)) dy='A';
        }
        if (p=='B') {
            if ((!q)||(q==2)) dy='B';
            if (q==5) dy='Q';
        }
        if (p=='C') {
            if ((!q)||(q==3)) dy='C';
        }
        if (p=='D') {
            if ((!q)||(q==3)) dy='D';
            if (q==2) dy='B';
            if (q==5) dy='P';
        }
        if (p=='E') {
            if ((!q)||(q==5)) dy='E';
        }
        if (p=='F') {
            if ((!q)||(q==5)) dy='F';
        }
        if (p=='G') {
            if ((!q)||(q==1)) dy='G';
            if (q==2) dy='g';
        }
        if (p=='H') {
            if ((!q)||(q==5)) dy='H';
        }
        if (p=='I') {
            if ((!q)||(q==4)) dy='I';
            if (q==5) dy='i';
            if (q==3) dy='D';
            if (q==2) dy='B';
            if (q==1) dy='A';
        }
        if (p=='J') {
            if ((!q)||(q==4)) dy='J';
            if (q==5) dy='j';
            if (q==3) dy='C';
        }
        if (p=='K') {
            if (q) dg=q;
            else dg=154;
        }
        if (p=='L') {
            if ((!q)||(q==4)) dy='L';
            if (q==5) dy='l';
            if (q==3) dy='C';
        }
        if (p=='M') {
            if ((!q)||(q==5)) dy='W';
            if (q==1) dy='A';
        }
        if (p=='N') {
            if ((!q)||(q==5)) dy='N';
        }
        if (p=='O') {
            if ((!q)||(q==4)) dy='O';
            if (q==1) dy='A';
        }
        if (p=='P') {
            if ((!q)||(q==5)) dy='P';
        }
        if (p=='Q') {
            if ((!q)||(q==5)) dy='Q';
        }
        if (p=='R') {
            if ((!q)||(q==5)) dy='R';
        }
        if (p=='S') {
            if ((!q)||(q==4)) dy='S';
            if (q==5) dy='s';
            if (q==1) dy='A';
        }
        if (p=='T') {
            if ((!q)||(q==4)) dy='T';
            if (q==5) dy='t';
        }
        if (p=='U') {
            if ((!q)||(q==5)) dy='U';
        }
        if (p=='V') {
            if ((!q)||(q==5)) dy='V';
            if (q==3) dy='C';
        }
        if (p=='W') {
            if ((!q)||(q==5)) dy='W';
        }
        if (p=='X') {
            if ((!q)||(q==5)) dy='X';
        }
        if (p=='Y') {
            if ((!q)||(q==5)) dy='Y';
        }
        if (p=='Z') {
            if ((!q)||(q==4)) dy='Z';
            if (q==5) dy='z';
        }
        if ((!dy)&&(!dg)) return vector<int>();
        int pc = 0;
        for (int i=1; i<155; ++i) {
            if (PName[i]==dy) pc=i;
        }
        if ((dg>0)&&(CheckBlockType(dg))) pc=dg;
        else if (dg) pc=0;
        if (!pc) return vector<int>();
        res.push_back(pc);
    }
    if (res.empty()) return res;
    reverse(res.begin(), res.end());
    return res;
}
void Apply(int o, int e, int x, int f) {
    if (!Odoo) return;
    if (QuickPlay) x>>=1;
    int lev = 1;
    if (x>=2) lev=2;
    if (x>=3) lev=4;
    int Fst=lev*100000, Rem=Fst;
    #define t(x) Plr[o].EV[x]
    if (e==1) {
        if ((Rem)&&(!Plr[o].Bl.empty())){
            while (Plr[o].Bl.size()) {
                if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
                Plr[o].Bl.pop(); Plr[o].AddGarbage(3+(Plr[f].OgTm>0),Plr[o].RollGarb());
            }
            Plr[o].EText("Burgeon", 0xFFA500);
        }
        if ((Rem)&&(t(6))) {
            int val = max(Rem,t(6)/2);
            t(6) -= val*2;
            t(2) = max(0,t(2)-val*2);
            Rem -= val;
            Plr[o].EText("Melt", 0xFFA500);
        }
        if ((Rem)&&(t(2))) {
            int val = max(Rem/2,t(2));
            t(2) -= val;
            Rem -= val*2;
            Plr[o].EText("Vaporize", 0xFFA500);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(4))&&(!t(5))) {
            int val = min(Rem,t(4));
            t(4) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(2+(Plr[f].OgTm>0), Plr[o].RollGarb());
            if (Plr[o].CheckActive()) {
                Plr[o].HardDrop(); Plr[o].Oper.clear();
            }
            Plr[o].EText("Overloaded", 0xEE0000);
        }
    }
    if (e==2) {
        if ((Rem)&&(t(1))) {
            int val = max(Rem,t(1)/2);
            t(1) -= val*2;
            Rem -= val;
            Plr[o].EText("Vaporize", 0xFFA500);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(5))&&(!t(1))) {
            int val = min(Rem,t(5));
            t(5) -= val;
            t(4) = max(0,t(4)-val);
            Rem -= val;
            val = max(1,val/100000);
            for (int i=0; i<min(10,val); ++i) Plr[o].Bl.push(clock());
            if (val) Plr[o].EText("Bloom", 0x00FF00);
        }
    }
    if (e==3) {
        if ((Rem)&&(t(1))) {
            int val = min(Rem,t(1));
            t(1) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Apply(o, 1, 1, f);
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(6))) {
            int val = min(Rem,t(6));
            t(6) -= val;
            t(2) = max(0,t(2)-val);
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Apply(o, 1, 1, f);
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(2))) {
            int val = min(Rem,t(2));
            t(2) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Apply(o, 2, 1, f);
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(4))&&(!t(5))) {
            int val = min(Rem,t(4));
            t(4) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Apply(o, 4, 1, f);
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(5))) {
            int val = min(Rem,t(5));
            t(5) -= val;
            Rem -= val;
            Plr[f].OgTm = 100000;
            Plr[o].EText("Overgrown", 0x00FF00);
        }
        if ((Rem)&&(t(7))) {
            int val = min(Rem,t(7));
            t(7) -= val;
            Rem -= val;
            int dd = 1;
            for (int i=1; i<=Plr[o].LX; ++i) {
                for (int j=1; j<=Plr[o].LY; ++j) {
                    if ((Plr[o].B[i][j])&&(!Plr[o].C[i][j])) dd=i;
                }
            }
            for (int _=0; _<2; ++_) {
                int x=rnd(dd)+1, y=rnd(dd+1);
                bool ok = true;
                for (int i=1; i<=Plr[o].LY; ++i) {
                    if ((Plr[o].C[x][i])||(Plr[o].C[y][i])) ok=false;
                }
                if (!ok) continue;
                for (int i=1; i<=Plr[o].LY; ++i) {
                    swap(Plr[o].B[x][i], Plr[o].B[y][i]);
                    swap(Plr[o].ID[x][i], Plr[o].ID[y][i]);
                    Plr[o].LE[x][i]=Plr[o].LE[y][i]=10000;
                }
            }
            if (val) Plr[o].EText("Dustraise", 0xFFE211);
        }
    }
    if (e==4) {
        if ((Rem)&&(!Plr[o].Bl.empty())) {
            while (Plr[o].Bl.size()) {
                if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
                Plr[o].Bl.pop(); Plr[o].AddGarbage(1,Plr[o].RollGarb());
                if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
                Plr[o].AddGarbage(1+(Plr[f].OgTm>0),Plr[o].RollGarb());
            }
            Plr[o].EText("Hyperbloom", 0xEE82EE);
        }
        if ((Rem)&&(t(1))) {
            int val = min(Rem,t(1));
            t(1) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(2+(Plr[f].OgTm>0), Plr[o].RollGarb());
            if (Plr[o].CheckActive()) Plr[o].HardDrop();
            Plr[o].EText("Overloaded", 0xEE0000);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(6))) {
            int val = min(Rem,t(6));
            t(6) -= val;
            t(2) = max(0,t(2)-val);
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].ScTm = 5000;
            Plr[o].EText("Superconduct", 0x66CCFF);
        }
    }
    if (e==5) {
        if ((Rem)&&(t(2))&&(!t(6))) {
            int val = min(Rem,t(2));
            t(2) -= val;
            Rem -= val;
            val = max(1,val/100000);
            for (int i=0; i<min(10,val); ++i) Plr[o].Bl.push(clock());
            if (val) Plr[o].EText("Bloom", 0x00FF00);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            Plr[f].OgTm = 100000;
            Plr[o].EText("Overgrown", 0x00FF00);
        }
    }
    if (e==6) {
        if ((Rem)&&(t(1))) {
            int val = max(Rem/2,t(1));
            t(1) -= val;
            Rem -= val*2;
            Plr[o].EText("Melt", 0xFFA500);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Swirl", 0x00FFCC);
        }
        if ((Rem)&&(t(4))&&(!t(5))) {
            int val = min(Rem,t(4));
            t(6) -= val;
            Rem -= val;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(1+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].ScTm = 5000;
            Plr[o].EText("Superconduct", 0x66CCFF);
        }
    }
    if (e==7) {
        if ((t(2))&&(t(6))) {
            t(2)=t(6)=0;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(2+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Shattered", 0xFFE211);
        }
        if ((Rem)&&(t(1))) {
            int val = min(Rem,t(1));
            t(1) -= val;
            Rem -= val;
            Plr[f].Cy.push_back(make_pair(clock(),1));
            Plr[f].Cy.push_back(make_pair(clock(),1));
            Plr[o].EText("Crystalize", 0xFFE211);
        }
        if ((Rem)&&(t(6))) {
            int val = min(Rem,t(6));
            t(6) -= val;
            t(2) = max(0,t(2)-val);
            Rem -= val;
            Plr[f].Cy.push_back(make_pair(clock(),6));
            Plr[f].Cy.push_back(make_pair(clock(),6));
            Plr[o].EText("Crystalize", 0xFFE211);
        }
        if ((Rem)&&(t(2))) {
            int val = min(Rem,t(2));
            t(2) -= val;
            Rem -= val;
            Plr[f].Cy.push_back(make_pair(clock(),2));
            Plr[f].Cy.push_back(make_pair(clock(),2));
            Plr[o].EText("Crystalize", 0xFFE211);
        }
        if ((Rem)&&(t(4))) {
            int val = min(Rem,t(4));
            t(4) -= val;
            Rem -= val;
            Plr[f].Cy.push_back(make_pair(clock(),4));
            Plr[f].Cy.push_back(make_pair(clock(),4));
            Plr[o].EText("Crystalize", 0xFFE211);
        }
        if ((Rem)&&(t(3))) {
            int val = min(Rem,t(3));
            t(3) -= val;
            Rem -= val;
            int dd = 1;
            for (int i=1; i<=Plr[o].LX; ++i) {
                for (int j=1; j<=Plr[o].LY; ++j) {
                    if ((Plr[o].B[i][j])&&(!Plr[o].C[i][j])) dd=i;
                }
            }
            for (int _=0; _<2; ++_) {
                int x=rnd(dd)+1, y=rnd(dd+1);
                bool ok = true;
                for (int i=1; i<=Plr[o].LY; ++i) {
                    if ((Plr[o].C[x][i])||(Plr[o].C[y][i])) ok=false;
                }
                if (!ok) continue;
                for (int i=1; i<=Plr[o].LY; ++i) {
                    swap(Plr[o].B[x][i], Plr[o].B[y][i]);
                    swap(Plr[o].ID[x][i], Plr[o].ID[y][i]);
                    Plr[o].LE[x][i]=Plr[o].LE[y][i]=10000;
                }
            }
            if (val) Plr[o].EText("Dustraise", 0xFFE211);
        }
    }
    if ((!e)&&(x>1)) {
        if ((t(2))&&(t(6))) {
            t(2)=t(6)=0;
            if (rnd(100)<_SegMess) Plr[o].LstHole=rnd(Plr[o].LY)+1;
            Plr[o].AddGarbage(2+(Plr[f].OgTm>0), Plr[o].RollGarb());
            Plr[o].EText("Shattered", 0xFFE211);
        }
    }
    if (Rem<Fst) return;
    if (e==1) {
        if ((!t(1))&&(t(5))) Plr[o].EText("Burning",0xFFA500);
    }
    if (e==2) {
        if ((!t(2))&&(t(4))&&(!t(6))) Plr[o].EText("Electro-Charged",0xEE82EE);
        if ((!t(2))&&(t(6))) Plr[o].EText("Frozen",0x66CCFF);
    }
    if (e==4) {
        if ((!t(4))&&(t(2))&&(!t(6))) Plr[o].EText("Electro-Charged",0xEE82EE);
        if ((!t(4))&&(t(5))&&(!t(1))) Plr[o].EText("Quickened",0x00FF00);
        if ((t(4))&&(t(5))&&(!t(1))) Plr[o].EText("Aggravate",0xEE82EE);
    }
    if (e==5) {
        if ((!t(5))&&(t(1))) Plr[o].EText("Burning",0xFFA500);
        if ((!t(5))&&(t(4))&&(!t(1))) Plr[o].EText("Quickened",0x00FF00);
        if ((t(5))&&(t(4))&&(!t(1))) Plr[o].EText("Spread",0x00FF00);
        if ((!t(5))&&(t(7))&&(!t(1))) Plr[o].EText("Solidification",0x00FF00);
        if ((!t(5))&&(t(6))&&(!t(1))) Plr[o].EText("Wither",0x66CCFF);
    }
    if (e==6) {
        if ((!t(6))&&(t(2))) Plr[o].EText("Frozen",0x66CCFF);
        if ((!t(6))&&(t(5))&&(!t(1))) Plr[o].EText("Wither",0x66CCFF);
    }
    if (e==7) {
        if ((!t(7))&&(t(5))&&(!t(1))) Plr[o].EText("Solidification",0x00FF00);
    }
    Plr[o].EV[e] = max(Plr[o].EV[e],Fst);
    Plr[o].ED[e] = (lev<2)?4:6;
    if (e==3) Plr[o].ED[e]*=2;
    if (e==7) Plr[o].ED[e]*=100;
    #undef t
}
string ForceLaunch = "";
vector<string> LaunchOpt;
pair<int,string> ExecuteProcess(vector<string> Co) {
    if (Co[0]=="ciallo") {
        DefaultBag.clear();
        for (int i=1; i<=100; ++i) {
            if (i!=91) DefaultBag.push_back(i);
        }
        for (int _=0; _<2; ++_) {
            for (int i=1; i<=11; ++i) DefaultBag.push_back(i);
            for (int __=0; __<2; ++__) {
                for (int i=8; i<=11; ++i) DefaultBag.push_back(i);
            }
        }
        for (int i=0; i<Plrs; ++i) Plr[i].Bag=DefaultBag;
        return make_pair(0xEE82EE,"No Comment");
    }
    if (Co[0]=="odoo") {
        Odoo = !Odoo;
        return make_pair(0xEE82EE,"No Comment");
    }
    if (Co[0]=="lqos") {
        LqOS = !LqOS;
        return make_pair(0xEE82EE,"No Comment");
    }
    if ((Co.size()>1)&&(Co[0]=="conste")) {
        int x = SToI(Co[1]);
        if (x<8) ConstE=x;
        return make_pair(0xEE82EE,"No Comment");
    }
    vector<int> lst; if (Obs>=0) lst.push_back(Obs);
    if (Co[0]=="for") {
        int pos = 0;
        for (int i=1; i<Co.size(); ++i) {
            if (Co[i]=="run") {
                pos=i; break;
            }
        }
        if (!pos) return make_pair(0xEE0000,"No paring \'run\' found in \'for\'");
        lst.clear();
        for (int i=0; i<Plrs; ++i) lst.push_back(i);
        vector<string> nw; deque<string> filter;
        for (int i=1; i<pos; ++i) filter.push_back(Co[i]);
        while (filter.size()) {
            string ValName=filter.front(); filter.pop_front();
            if ((ValName=="sort")||(ValName=="rsort")) {
                bool rev = (ValName=="rsort");
                if (filter.empty()) return make_pair(0xEE0000,"No paring variable for sorting");
                ValName=filter.front(); filter.pop_front();
                int val = Global.QueryVal(ValName);
                if (val==ERR) return make_pair(0xEE0000,"Unknown variable \'"+ValName+"\'");
                for (int i : lst) {
                    sortval[i]=Plr[i].QueryVal(ValName); if (rev) sortval[i]*=-1;
                }
                stable_sort(lst.begin(), lst.end(), [](int x, int y) {
                    return sortval[x]<sortval[y];
                });
                continue;
            }
            if (ValName=="pick") {
                if (filter.empty()) return make_pair(0xEE0000,"No paring count for picking");
                string pc=filter.front(); int cnt=SToI(pc); filter.pop_front();
                if (cnt==ERR) return make_pair(0xEE0000,"Invalid count \'"+pc+"\' for picking");
                while (lst.size()>cnt) lst.pop_back();
                continue;
            }
            if (ValName=="shuffle") {
                shuffle(lst.begin(), lst.end(), rng);
                continue;
            }
            int val = Global.QueryVal(ValName);
            if (val==ERR) return make_pair(0xEE0000,"Unknown variable \'"+ValName+"\'");
            if (filter.empty()) return make_pair(0xEE0000,"No paring limitation for variable \'"+ValName+"\'");
            string Lim=filter.front(); filter.pop_front();
            if ((Lim!="e")&&(Lim!="ne")&&(Lim!="ge")&&(Lim!="le")&&(Lim!="g")&&(Lim!="l")) {
                return make_pair(0xEE0000,"Invalid limitation \'"+Lim+"\' for variable \'"+ValName+"\'");
            }
            if (filter.empty()) return make_pair(0xEE0000,"No paring value for variable \'"+ValName+"\'");
            string cp=filter.front(); int cval=SToI(cp); filter.pop_front();
            if (cval==ERR) return make_pair(0xEE0000,"Invalid value \'"+cp+"\' for variable \'"+ValName+"\'");
            vector<int> nwlst;
            for (int i : lst) {
                val = Plr[i].QueryVal(ValName);
                if ((Lim=="e")&&(val==cval)) nwlst.push_back(i);
                if ((Lim=="ne")&&(val!=cval)) nwlst.push_back(i);
                if ((Lim=="g")&&(val>cval)) nwlst.push_back(i);
                if ((Lim=="ge")&&(val>=cval)) nwlst.push_back(i);
                if ((Lim=="l")&&(val<cval)) nwlst.push_back(i);
                if ((Lim=="le")&&(val<=cval)) nwlst.push_back(i);
            }
            lst = nwlst;
        }
        for (int i=pos+1; i<Co.size(); ++i) nw.push_back(Co[i]);
        Co = nw;
    }
    else if (Co[0]=="forall") {
        lst.clear(); for (int i=0; i<Plrs; ++i) lst.push_back(i);
        vector<string> nw;
        for (int i=1; i<Co.size(); ++i) nw.push_back(Co[i]);
        Co = nw;
    }
    //if (lst.empty()) return make_pair(0xAAAAAA,"No target selected");
    if (Co.empty()) return make_pair(0xAAAAAA,"No command");
    if (Co[0]=="for") return make_pair(0xEE0000,"Invalid \'for\' command");
    if (Co[0]=="run") return make_pair(0xEE0000,"Invalid \'run\' command");
    if (Co[0]=="forall") return make_pair(0xEE0000,"Invalid \'forall\' command");
    if (Co[0]=="sort") return make_pair(0xEE0000,"Invalid \'sort\' command");
    if (Co[0]=="rsort") return make_pair(0xEE0000,"Invalid \'rsort\' command");
    if (Co[0]=="pick") return make_pair(0xEE0000,"Invalid \'pick\' command");
    if (Co[0]=="shuffle") return make_pair(0xEE0000,"Invalid \'shuffle\' command");
    if (Co[0]=="kill") {
        int tot = 0;
        for (int d : lst) {
            if (!Plr[d].Over) {
                Plr[d].ForceOver=true; ++tot;
            }
        }
        if (tot) return make_pair(0x66CCFF,"Cleared "+IToS(tot)+" player"+((tot>1)?"s":""));
        else return make_pair(0xAAAAAA,"No players cleared");
    }
    if (Co[0]=="finish") {
        ForceRound=true; return make_pair(0x66CCFF,"Finished the current game");
    }
    if (Co[0]=="abort") {
        ForceAbort=true; return make_pair(0x66CCFF,"Aborted the current game");
    }
    if (Co[0]=="setblock") {
        if (Co.size()<3) return make_pair(0xEE0000,"Insufficient values for \'setblock\' command");
        int x=SToI(Co[1]), y=SToI(Co[2]), val=154, rep=-1;
        if (Co.size()>=4) val=SToI(Co[3]);
        if (Co.size()>=5) rep=SToI(Co[4]);
        if (x==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[1]+"\' for \'setblock\' command");
        if (y==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for \'setblock\' command");
        if (val==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[3]+"\' for \'setblock\' command");
        if (rep==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[4]+"\' for \'setblock\' command");
        if (!CheckBlockType(val)) return make_pair(0xEE0000,"\'"+Co[3]+"\' is not a block type");
        if ((rep>=0)&&(!CheckBlockType(rep))) return make_pair(0xEE0000,"\'"+Co[4]+"\' is not a block type");
        int tot = 0;
        for (int d : lst) {
            if ((x>Plr[d].LX)||(y>Plr[d].LY)) continue;
            if (Plr[d].C[x][y]) continue;
            if ((rep>=0)&&(Plr[d].B[x][y]!=rep)) continue;
            Plr[d].B[x][y]=val; ++tot;
            Plr[d].ID[x][y] = ++Plr[d].PartID;
        }
        if (tot) return make_pair(0x66CCFF,"Placed "+IToS(tot)+" block"+((tot>1)?"s":""));
        else return make_pair(0xAAAAAA,"No blocks placed");
    }
    if (Co[0]=="fill") {
        if (Co.size()<5) return make_pair(0xEE0000,"Insufficient values for \'fill\' command");
        int xl=SToI(Co[1]), yl=SToI(Co[2]), xr=SToI(Co[3]), yr=SToI(Co[4]), val=154, rep=-1;
        if (Co.size()>=6) val=SToI(Co[5]);
        if (Co.size()>=7) rep=SToI(Co[6]);
        if (xl==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[1]+"\' for \'fill\' command");
        if (yl==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for \'fill\' command");
        if (xr==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[3]+"\' for \'fill\' command");
        if (yr==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[4]+"\' for \'fill\' command");
        if (val==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[5]+"\' for \'fill\' command");
        if (rep==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[6]+"\' for \'fill\' command");
        if (!CheckBlockType(val)) return make_pair(0xEE0000,"\'"+Co[5]+"\' is not a block type");
        if ((rep>=0)&&(!CheckBlockType(rep))) return make_pair(0xEE0000,"\'"+Co[6]+"\' is not a block type");
        if (xl>xr) swap(xl,xr);
        if (yl>yr) swap(yl,yr);
        int tot = 0;
        for (int d : lst) {
            ++Plr[d].PartID;
            for (int i=1; i<Plr[d].LX; ++i) {
                for (int j=1; j<=Plr[d].LY; ++j) {
                    if (((xl<=i)&&(i<=xr))&&((yl<=j)&&(j<=yr))) {
                        if (Plr[d].C[i][j]) continue;
                        if ((rep>=0)&&(Plr[d].B[i][j]!=rep)) continue;
                        Plr[d].B[i][j]=val; ++tot;
                        Plr[d].ID[i][j] = Plr[d].PartID;
                    }
                }
            }
        }
        if (tot) return make_pair(0x66CCFF,"Placed "+IToS(tot)+" block"+((tot>1)?"s":""));
        else return make_pair(0xAAAAAA,"No blocks placed");
    }
    if (Co[0]=="garbage") {
        int val=1, pos=0;
        if (Co.size()>=2) val=SToI(Co[1]);
        if (Co.size()>=3) pos=SToI(Co[2]);
        if (val==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[1]+"\' for \'garbage\' command");
        if (pos==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for \'garbage\' command");
        int tot = 0;
        for (int d : lst) {
            int cn=min(Plr[d].LX,val); tot+=cn;
            if (pos) Plr[d].LstHole=pos;
            else if (rnd(100)<_SegMess) Plr[d].LstHole=Plr[d].RollHole(_Luck);
            Plr[d].AddGarbage(cn, Plr[d].RollGarb());
        }
        if (tot) return make_pair(0x66CCFF,"Pushed "+IToS(tot)+" garbage line"+((tot>1)?"s":""));
        else return make_pair(0xAAAAAA,"No garbage lines pushed");
    }
    if (Co[0]=="launch") {
        string Mode = "home";
        if (Co.size()>=2) Mode=Co[1];
        ForceLaunch = Mode;
        LaunchOpt.clear();
        for (int i=2; i<Co.size(); ++i) LaunchOpt.push_back(Co[i]);
        return make_pair(0x66CCFF,"Launched mode "+Mode);
    }
    if (Co[0]=="quit") {
        ForceLaunch = "home";
        LaunchOpt.clear();
        return make_pair(0x66CCFF,"Quit the current game");
    }
    if (Co[0]=="damage") {
        int val=1, pos=0, src=-1;
        if (Co.size()>=2) val=SToI(Co[1]);
        if (Co.size()>=3) pos=SToI(Co[2]);
        if (Co.size()>=4) src=SToI(Co[3]);
        if (val==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[1]+"\' for \'damage\' command");
        if (pos==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for \'damage\' command");
        if (src==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[3]+"\' for \'damage\' command");
        int tot=0; val=min(val,1000);
        for (int d : lst) {
            if (pos) Plr[d].LstHole=pos;
            else if (rnd(100)<_SegMess) Plr[d].LstHole=Plr[d].RollHole(_Luck);
            lll gb = Plr[d].RollGarb();
            Plr[d].Rec.push_back(make_pair(val,make_pair(gb,clock()))); tot+=val;
            if (src>=0) Plr[d].LstAtk=src;
        }
        if (tot) return make_pair(0x66CCFF,"Sent "+IToS(tot)+" attack"+((tot>1)?"s":""));
        else return make_pair(0xAAAAAA,"No attack sent");
    }
    if (Co[0]=="waste") {
        int val = 1;
        if (Co.size()>=2) val=SToI(Co[1]);
        if (val==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[1]+"\' for \'waste\' command");
        int tot = 0;
        for (int d : lst) {
            Plr[d].ForceWaste+=val; tot+=val;
        }
        return make_pair(0x66CCFF,"Wasted "+IToS(tot)+" piece"+((tot>1)?"s":""));
    }
    if (Co[0]=="lock") {
        int tot = 0;
        for (int d : lst) {
            Plr[d].ForceLock=true; ++tot;
        }
        return make_pair(0x66CCFF,"Locked "+IToS(tot)+" piece"+((tot>1)?"s":""));
    }
    if (Co[0]=="set") {
        if (Co.size()<3) return make_pair(0xEE0000,"Insufficient values for \'set\' command");
        string ValName=Co[1]; int val=Global.ChangeVal(ValName,((ValName=="width")||(ValName=="height")||(ValName=="realheight"))?4:((ValName=="tar")?0:1));
        if (val==ERR) return make_pair(0xEE0000,"Unknown variable \'"+Co[1]+"\' for \'set\' command");
        val=SToI(Co[2]); if (Global.ChangeVal(ValName,val)==ERR) return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for \'set\' command");
        int tot = 0;
        for (int d : lst) {
            Plr[d].ChangeVal(ValName,val); ++tot;
        }
        return make_pair(0x66CCFF,"Changed "+IToS(tot)+" player"+((tot>1)?"s\'":"\'s")+" attribute \'"+Co[1]+"\' to \'"+Co[2]+"\'");
    }
    if (Co[0]=="gamerule") {
        if (Co.size()<3) return make_pair(0xEE0000,"Insufficient values for \'gamerule\' command");
        if (Co[1]=="spin") {
            vector<string> lst = {"allspin","allfull","allsemi","allmini","tspin","default","easy","minionly","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    SpinRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="clutch") {
            vector<string> lst = {"default","always","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ClutchRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="baseattack") {
            vector<string> lst = {"default","asc","classic","arcade","equal","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    BaseRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="cleargravity") {
            vector<string> lst = {"default","none","sticky","cascade","separate"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ClearGravity = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="b2b") {
            vector<string> lst = {"default","chain","surge","techmino","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    B2BRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="combo") {
            vector<string> lst = {"multipler","io","default","friends","expert","battle","99","ppt","effect","zone","techmino","c2","aquamino","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ComboRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="rotation") {
            vector<string> lst = {"default","extend","srs","srsplus","asc","ascplus","ors","rnrs","lnrs","atari","ars","tetrax","c2","new","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    KickTable=ss; InitKick();
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="allclear") {
            vector<string> lst = {"default","extend","techmino","quickplay","league","99","arcade","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ACRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="garbagetype") {
            vector<string> lst = {"layer","bomb","fall","solid"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    GarbageType = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="garbagemode") {
            vector<string> lst = {"combo","attack","lock","instant"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    GarbageMode = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="garbagecancel") {
            vector<string> lst = {"default","dig","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    GarbageCancel = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="garbageshape") {
            vector<string> lst = {"cheese","full","empty","random","bubble","copy","board","clear","arcade"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    GarbageShape = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="garbagebonus") {
            vector<string> lst = {"default","io","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    GarbageBonus = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="opener") {
            vector<string> lst = {"default","io","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    OpenerBonus = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="scaletype") {
            vector<string> lst = {"default","div","dec","exp"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    LevelRule = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="sequence") {
            vector<string> lst = {"random","bag","fixed"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].Sequence=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="initfacing") {
            vector<string> lst = {"up","right","down","left"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].InitFacing=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="arcaderound") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ArcadeRound = vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="observebot") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    ObserveAI = vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="shadow") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].ShowShadow=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usemove") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowMove=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="userotate") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowRot=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="use2rotate") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].Allow2Rot=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usehalf") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowHalf=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usehard") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowHard=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usesoft") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowSoft=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usesonic") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowSonic=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="useflip") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowFlip=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="useup") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowUp=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="uselock") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowLock=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="usedeep") {
            vector<string> lst = {"false","true"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].AllowDeep=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="targetbonus") {
            vector<string> lst = {"default","99","defensive","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    TargetBonus = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="badgebonus") {
            vector<string> lst = {"default","99","none"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    BadgeBonus = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="hold") {
            vector<string> lst = {"none","default","infinity"};
            int vv = 0;
            for (string ss : lst) {
                if (ss==Co[2]) {
                    for (int i=0; i<Plrs; ++i) Plr[i].HoldRule=vv;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
                ++vv;
            }
        }
        else if (Co[1]=="innermess") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                _InnerMess = min(100,x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="segmess") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                _SegMess = min(100,x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="garbagedelay") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].GarbDelay=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="garbagerise") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].GarbRise=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="garbagegap") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].GarbageGap=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="garbageluck") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                _Luck = x-100;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="garbagepreview") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].GarbagePreview=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="openerphrase") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].OpenerPhrase=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="drop") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].BaseDropL=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="lock") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].BaseLockL=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="groundlock") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].GLockL=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="forcelock") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].FLockL=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="reset") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].ResetLim=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="deathare") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].DeathARE=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="are") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].ARE=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="lcd") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LCD=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="drd") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].DRD=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="next") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x<=10)) {
                for (int i=0; i<Plrs; ++i) Plr[i].ViewNxt=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="history") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x<=100)) {
                for (int i=0; i<Plrs; ++i) Plr[i].His=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="roll") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x)&&(x<=100)) {
                for (int i=0; i<Plrs; ++i) Plr[i].Rol=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="extra") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x<=100)) {
                for (int i=0; i<Plrs; ++i) Plr[i].Ext=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="width") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x>=2)&&(x<=50)) {
                for (int i=0; i<Plrs; ++i) Plr[i].ChangeVal("width",x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="height") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x>=2)&&(x<=90)) {
                for (int i=0; i<Plrs; ++i) Plr[i].ChangeVal("height",x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="realheight") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x>=2)&&(x<=90)) {
                for (int i=0; i<Plrs; ++i) Plr[i].ChangeVal("realheight",x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="vanish") {
            int x = SToI(Co[2]);
            if ((x!=ERR)&&(x>=2)&&(x<=90)) {
                for (int i=0; i<Plrs; ++i) Plr[i].VanishHeight=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="stock") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].ChangeVal("stock",x);
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelbase") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevBase=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelstart") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevStart=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelline") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevLine=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="leveltime") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevTime=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelpiece") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevPiece=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelattack") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevAttack=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="increaseline") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevLineInc=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="increasetime") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevTimeInc=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="increasepiece") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevPieceInc=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="increaseattack") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].LevAttackInc=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelmaster") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].MasterBeg=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="levelratio") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].Diff=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="wastelimit") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].WasteLim=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="passthrough") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                for (int i=0; i<Plrs; ++i) Plr[i].Passthrough=x;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="piece") {
            vector<int> Bag = TransferBag(Co[2]);
            if (Bag.size()) {
                DefaultBag=Bag; for (int i=0; i<Plrs; ++i) Plr[i].Bag=Bag;
                return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else return make_pair(0xEE0000,"Unknown gamerule \'"+Co[1]+"\'");
        return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for gamerule \'"+Co[1]+"\'");
    }
    #warning execute
    if (Co[0]=="config") {
        if (Co.size()<3) return make_pair(0xEE0000,"Insufficient values for \'config\' command");
        if (Co[1]=="das") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                DAS = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="dropdas") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                SDDAS = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="arr") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                ARR = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="droparr") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                SDARR = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="dcd") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                DCD = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="hcd") {
            int x = SToI(Co[2]);
            if (x!=ERR) {
                HCD = x;
                return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
            }
        }
        else if (Co[1]=="defaultrotate") {
            vector<string> lst = {"ccw","cw"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    DefaultRot = ss;
                    return make_pair(0x66CCFF,"Changed gamerule \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="style") {
            vector<string> lst = {"default","simple","arcade","classic"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    Style = ss;
                    return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="moveeffect") {
            vector<string> lst = {"true","false"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    MoveEff = (ss=="true");
                    return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="spineffect") {
            vector<string> lst = {"true","false"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    SpinEff = (ss=="true");
                    return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="dropeffect") {
            vector<string> lst = {"true","false"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    DropEff = (ss=="true");
                    return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else if (Co[1]=="rotateeffect") {
            vector<string> lst = {"true","false"};
            for (string ss : lst) {
                if (ss==Co[2]) {
                    RotEff = (ss=="true");
                    return make_pair(0x66CCFF,"Changed config \'"+Co[1]+"\' to \'"+Co[2]+"\'");
                }
            }
        }
        else return make_pair(0xEE0000,"Unknown config \'"+Co[1]+"\'");
        return make_pair(0xEE0000,"Invalid value \'"+Co[2]+"\' for config \'"+Co[1]+"\'");
    }
    if (Co[0]=="keymap") {
        if (Co.size()<3) return make_pair(0xEE0000,"Insufficient values for \'keymap\' command");
        int Key = AskKey(Co[2]);
        if (!Key) return make_pair(0xEE0000,"Invalid key name \'"+Co[2]+"\'");
        string Op=Co[1]; bool Suc=false;
        if (Op=="left") {
            Suc=true; KEY_LEFT=Key;
        }
        if (Op=="right") {
            Suc=true; KEY_RIGHT=Key;
        }
        if (Op=="down") {
            Suc=true; KEY_DOWN=Key;
        }
        if (Op=="drop") {
            Suc=true; KEY_HARD=Key;
        }
        if (Op=="sonic") {
            Suc=true; KEY_SONIC=Key;
        }
        if (Op=="flip") {
            Suc=true; KEY_FLIP=Key;
        }
        if (Op=="up") {
            Suc=true; KEY_UP=Key;
        }
        if (Op=="waste") {
            Suc=true; KEY_WASTE=Key;
        }
        if (Op=="rotate") {
            Suc=true; KEY_ROT=Key;
        }
        if (Op=="cw") {
            Suc=true; KEY_CW=Key;
        }
        if (Op=="ccw") {
            Suc=true; KEY_CCW=Key;
        }
        if (Op=="half") {
            Suc=true; KEY_180=Key;
        }
        if (Op=="hold") {
            Suc=true; KEY_HOLD=Key;
        }
        if (Op=="even") {
            Suc=true; KEY_EVEN=Key;
        }
        if (Op=="ko") {
            Suc=true; KEY_KO=Key;
        }
        if (Op=="random") {
            Suc=true; KEY_RANDOM=Key;
        }
        if (Op=="payback") {
            Suc=true; KEY_PAYBACK=Key;
        }
        if (Op=="badge") {
            Suc=true; KEY_BADGE=Key;
        }
        if (Op=="attacker") {
            Suc=true; KEY_ATTACKERS=Key;
        }
        if (Op=="undo") {
            Suc=true; KEY_UNDO=Key;
        }
        if (Op=="retry") {
            Suc=true; KEY_RETRY=Key;
        }
        if (Op=="reset") {
            Suc=true; KEY_RESET=Key;
        }
        if (Op=="lock") {
            Suc=true; KEY_LOCK=Key;
        }
        if (Suc) {
            for (int i=0; i<Plrs; ++i) Plr[i].ReloadKey();
            return make_pair(0x66CCFF,"Changed key mapping of \'"+Co[1]+"\' to \'"+Co[2]+"\'");
        }
        else return make_pair(0xEE0000,"Invalid operation name \'"+Co[1]+"\'");
    }
    if (Co[0]=="spectate") {
        int val = -1;
        if (Co.size()>=2) val=SToI(Co[1]);
        if (val==-1) {
            for (int d : lst) {
                if (!Plr[d].Over) {
                    Obs=d; return make_pair(0x66CCFF,"Spectating player "+IToS(d));
                }
            }
            return make_pair(0xEE0000,"All targets are over");
        }
        if ((val<0)||(val>=Plrs)) return make_pair(0xEE0000,"Player \'"+Co[1]+"\' didn\'t exist");
        if (Plr[val].Over) return make_pair(0xEE0000,"Player "+IToS(val)+" is over");
        Obs=val; return make_pair(0x66CCFF,"Spectating player "+IToS(val));
    }
    return make_pair(0xEE0000,"Unknown command \'"+Co[0]+"\'");
}
pair<int,string> Execute(vector<string> Co) {
    pair<int,string> res = ExecuteProcess(Co);
    if ((Zen)&&(res.first!=0xEE0000)) Storage=true;
    return res;
}
ClassPiece RotatePiece(ClassPiece x) {
    ClassPiece res;
    res.clr=x.clr; res.LX=x.LY; res.LY=x.LX; res.SDel=x.SDel;
    res.FstX=res.FstY=-1;
    for (int i=0; i<x.LX; ++i) {
        for (int j=0; j<x.LY; ++j) res.B[x.LY-j-1][i]=x.B[i][j];
    }
    for (int i=0; i<res.LX; ++i) {
        for (int j=0; j<res.LY; ++j) {
            if ((res.FstX<0)&&(res.B[i][j])) {
                res.FstX=i; res.FstY=j;
            }
        }
    }
    return res;
}
int StoragePos=1, StorageTot=1;
void Launch(string Mode="home") {
    ForceExecute = "";;
    Obs = -1; 
    _TIME = time(0);
    Plrs = 1;
    Storage=Undo=ForceRound=ForceAbort=false;
    DisAtk = true;
    UseAI = 0;
    AddTp = 1;
    Zen=QuickPlay=Arcade=false;
    memset(KOCount, 0, sizeof(KOCount));
    StoragePos=StorageTot=1;
    DefaultBag = {1,2,3,4,5,6,7};
    RoundTot = 0;
    memset(TarRem, 0, sizeof(TarRem));
    memset(ShiftCD, 0, sizeof(ShiftCD));
    SpinRule = "allspin";
    ClutchRule = "default";
    BaseRule = "default";
    ClearGravity = "default";
    B2BRule = "surge";
    ComboRule = "multipler";
    KickTable = "default";
    ACRule = "default";
    GarbageType = "layer";
    GarbageMode = "combo";
    GarbageCancel = "default";
    GarbageShape = "cheese";
    GarbageBonus = "default";
    OpenerBonus = "default";
    LevelRule = "default";
    ArcadeRound = "false";
    ObserveAI = true;
    TargetBonus = "default";
    BadgeBonus = "default";
    _InnerMess = 0;
    _SegMess = 100;
    _Luck = 0;
    if (Mode=="battle") Plrs=2;
    bool AllBot = false;
    if (Mode=="zenzenith") QuickPlay=Zen=true;
    if (Mode=="bot") AllBot=true;
    if (Mode=="zenith") QuickPlay=true;
    if (Mode=="botzenith") AllBot=QuickPlay=true;
    for (string str : LaunchOpt) {
        for (int i=2; i<=100; ++i) {
            if (str==IToS(i)+"p") Plrs=i;
        }
        if (str=="mm4") DefaultBag={1,2,4,5,6};
        if (str=="mm5") DefaultBag=TransferBag("ehi5j5prs5t5uvwx");
        if (str=="mm6") DefaultBag=TransferBag("k30k31k32k33k34k35k36k37k38k39k40k42k44k46k48k50k52k54k56k58k60k62k64k66k68k70k72k74k76k78k80k82k84k86k88");
        if (str=="mm45") DefaultBag=TransferBag("ijostehi5j5prs5t5uvwx");
        if (str=="mm12345") DefaultBag=TransferBag("abcijostehi5j5prs5t5uvwx");
        if (str=="mm123456") DefaultBag=TransferBag("abcijostehi5j5prs5t5uvwxk30k31k32k33k34k35k36k37k38k39k40k42k44k46k48k50k52k54k56k58k60k62k64k66k68k70k72k74k76k78k80k82k84k86k88");
        if (str=="m45") {
            DefaultBag.clear();
            for (int i=1; i<8; ++i) DefaultBag.push_back(i);
            for (int i=12; i<30; ++i) DefaultBag.push_back(i);
        }
        if (str=="m5") {
            DefaultBag.clear();
            for (int i=12; i<30; ++i) DefaultBag.push_back(i);
        }
        if (str=="m6") {
            DefaultBag.clear();
            for (int i=30; i<90; ++i) DefaultBag.push_back(i);
        }
        if (str=="m123") {
            DefaultBag.clear();
            for (int i=8; i<12; ++i) DefaultBag.push_back(i);
        }
        if (str=="m1234") {
            DefaultBag.clear();
            for (int i=1; i<12; ++i) DefaultBag.push_back(i);
        }
        if (str=="m12345") {
            DefaultBag.clear();
            for (int i=1; i<30; ++i) DefaultBag.push_back(i);
        }
        if (str=="m123456") {
            DefaultBag.clear();
            for (int i=1; i<90; ++i) DefaultBag.push_back(i);
        }
    }
    for (int i=0; i<Plrs; ++i) {
        Plr[i] = Board(6, 40, 10, 22, 0.0, (Plrs==1)?400.0:0.0, ((i+1<Plrs)||(AllBot)), 300);
        Plr[i].ClearAll(_TIME);
        Plr[i].ReloadKey();
    }
    if (Plrs>1) KickTable="extend";
    if (AllBot) KickTable="ascplus";
    if (Plrs>2) {
        for (int i=0; i+1<Plrs; ++i) {
            Plr[i].OperTime=100+(1000/Plrs)*i; Plr[i].Plr=6-(i%6);
            if ((Plr[i].Plr==2)||(Plr[i].Plr==3)) Plr[i].Plr=6;
            if (((Plr[i].Plr==2)||(Plr[i].Plr==3)||(Plr[i].Plr==5)||(Plr[i].Plr==4))&&(Plr[i].OperTime<300)) {
                if (QuickPlay) Plr[i].Plr=6;
            }
            if ((Plr[i].Plr==6)&&(QuickPlay)) Plr[i].ModSpin=!(i&((Plr[Plrs-1].Bot)?7:1));
            Plr[i].OperTime = max(150,Plr[i].OperTime);
            Plr[i].GarbRise = 100;
        }
    }
    else if (Plrs==2) {
        Plr[0].Plr=6; Plr[0].OperTime=300;
    }
    if ((Mode=="classic")||(Mode=="zenclassic")) {
        KickTable = "rnrs";
        ClutchRule = "none";
        Plr[0].DeathARE = 0;
        if (Mode=="zenclassic") Zen=true;
        Plr[0].LevLine = 10;
        Plr[0].MasterBeg = 99999999;
        Plr[0].HoldRule = 0;
        Plr[0].His=1; Plr[0].Rol=2; Plr[0].ViewNxt=1;
        Plr[0].Sequence = 0;
        Plr[0].Plr = 1;
        Plr[0].Allow2Rot=Plr[0].AllowHalf=Plr[0].AllowHard=Plr[0].AllowSonic=false;
        Plr[0].ResetLim = 0;
    }
    if ((Mode=="arcade")||(Mode=="zenarcade")) {
        KickTable = "srsplus";
        SpinRule = "easy";
        ClutchRule = "none";
        B2BRule = "default";
        Plr[0].DeathARE = 0;
        Arcade = true;
        if (Mode=="zenarcade") Zen=true;
        Plr[0].His=1; Plr[0].Rol=2; Plr[0].ViewNxt=3;
        Plr[0].Sequence = 0; 
        Plr[0].Plr = 4;
        Plr[0].AllowHalf = false;
    }
    if (Mode=="zen") {
        Zen=true; ClutchRule="always";
        Plr[0].LCD = 200;
    }
    if (Mode=="marathon") {
        Plr[0].LevLine = 10;
    }
    if (Mode=="sprint") Plr[0].TarLine=40;
    if (Mode=="ultra") Plr[0].TarTime=120000;
    if (Mode=="dig") Plr[0].StaticHeight=10;
    if (Mode=="survive") {
        Plr[0].StaticHeight=99999999; Plr[0].GarbRise=1500;
    }
    if (Mode=="zenithsprint") {
        QuickPlay=true; Plr[0].TarScore=1650000;
    }
    if (Zen) {
        BegDelay = 0;
        Plr[0].BaseLockL=Plr[0].ResetLim=99999999;
        Plr[0].HoldRule = 2;
    }
    if ((QuickPlay)&&((Plrs>1)||(Zen))) SpinRule="allmini";
    for (string str : LaunchOpt) {
        for (int i=2; i<=50; ++i) {
            if (str==IToS(i)+"w") {
                for (int j=0; j<Plrs; ++j) {
                    Plr[j].LY = i;
                    if (i<4) Plr[j].InitFacing=3;
                }
            }
        }
        for (int i=2; i<=80; ++i) {
            if (str==IToS(i)+"h") {
                for (int j=0; j<Plrs; ++j) {
                    Plr[j].DX=i+2; Plr[j].LX=max(Plr[j].LX,i+10);
                }
            }
        }
        for (int i=1; i<=10000; ++i) {
            if (str==IToS(i)+"gr") {
                for (int j=0; j<Plrs; ++j) Plr[j].GarbRise=i;
            }
        }
        for (int i=1; i<=10000; ++i) {
            if (str==IToS(i)+"l") {
                for (int j=0; j<Plrs; ++j) Plr[j].TarLine=i;
            }
        }
        for (int i=1; i<=10000; ++i) {
            if (str==IToS(i)+"s") {
                for (int j=0; j<Plrs; ++j) Plr[j].TarTime=i*1000;
            }
        }
        for (int i=0; i<=10000; ++i) {
            if (str==IToS(i)+"sp") {
                for (int j=0; j<Plrs; ++j) Plr[j].OperTime=i;
            }
        }
        if (str=="master") {
            for (int j=0; j<Plrs; ++j) {
                Plr[j].LevStart=max(Plr[j].LevStart,1); Plr[j].MasterBeg=1;
            }
        }
        for (int i=1; i<=99; ++i) {
            if (str=="lv"+IToS(i)) {
                for (int j=0; j<Plrs; ++j) Plr[j].LevStart=i;
            }
        }
        for (int i=1; i<=99; ++i) {
            if (str==IToS(i)+"lvb") {
                for (int j=0; j<Plrs; ++j) Plr[j].LevBase=i;
            }
        }
        for (int i=0; i<=1000; ++i) {
            if (str==IToS(i)+"lvl") {
                for (int j=0; j<Plrs; ++j) Plr[j].LevLine=i;
            }
        }
        for (int i=0; i<=1000; ++i) {
            if (str==IToS(i)+"lvli") {
                for (int j=0; j<Plrs; ++j) Plr[j].LevLineInc=i;
            }
        }
        if (str=="srs") KickTable="srs";
        if (str=="asc") KickTable="asc";
        if (str=="srsplus") KickTable="srsplus";
        if (str=="c2rs") KickTable="c2";
        if (str=="defrs") KickTable="default";
        if (str=="extrs") KickTable="extend";
        if (str=="ascplus") KickTable="ascplus";
        if (str=="tetrax") KickTable="tetrax";
        if (str=="ars") {
            KickTable = "ars";
            for (int i=0; i<Plrs; ++i) Plr[i].InitFacing=2;
        }
        if (str=="ors") {
            KickTable = "ors";
            for (int i=0; i<Plrs; ++i) Plr[i].InitFacing=2;
        }
        if (str=="lnrs") {
            KickTable = "lnrs";
            for (int i=0; i<Plrs; ++i) Plr[i].InitFacing=2;
        }
        if ((str=="rnrs")||(str=="nrs")) {
            KickTable = "rnrs";
            for (int i=0; i<Plrs; ++i) Plr[i].InitFacing=2;
        }
        if (str=="deep") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowDeep=true;
        }
        if (str=="flip") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowFlip=true;
        }
        if (str=="up") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowUp=true;
        }
        if (str=="lock") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowLock=true;
        }
        if (str=="hold") {
            for (int i=0; i<Plrs; ++i) Plr[i].HoldRule=1;
        }
        if (str=="nohold") {
            for (int i=0; i<Plrs; ++i) Plr[i].HoldRule=0;
        }
        if (str=="infhold") {
            for (int i=0; i<Plrs; ++i) Plr[i].HoldRule=2;
        }
        if (str=="allclutch") ClutchRule="always";
        if (str=="noclutch") ClutchRule="none";
        if (str=="clutch") ClutchRule="default";
        if (str=="pack") {
            for (int i=0; i<Plrs; ++i) Plr[i].RoundHeight=9999;
        }
        if (str=="nomove") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowMove=false;
        }
        if (str=="norot") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowRot=false;
        }
        if (str=="no2rot") {
            for (int i=0; i<Plrs; ++i) Plr[i].Allow2Rot=false;
        }
        if (str=="2rot") {
            for (int i=0; i<Plrs; ++i) Plr[i].Allow2Rot=true;
        }
        if (str=="nohalf") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowHalf=false;
        }
        if (str=="half") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowHalf=true;
        }
        if (str=="nohard") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowHard=false;
        }
        if (str=="hard") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowHard=true;
        }
        if (str=="nosonic") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowSonic=false;
        }
        if (str=="sonic") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowSonic=true;
        }
        if (str=="nosoft") {
            for (int i=0; i<Plrs; ++i) Plr[i].AllowSoft=false;
        }
        if (str=="cascade") ClearGravity="separate";
    }
    if ((Plrs==1)&&(!QuickPlay)&&(!Zen)) DisAtk=false;
    if (Mode=="home") Plrs=0;
    LaunchOpt.clear();
    // -- after --
    InitKick();
    if (Zen) {
        Plr[1] = Plr[0];
    }
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) {
    for (int i=0; i<Floor.size(); ++i) Floor[i]*=1000LL;
    GradeBonus[0] = {0};
    GradeBonus[1] = {10,10,10,10,10,5,5,5,5,5,2};
    GradeBonus[2] = {20,20,20,15,15,15,10,10,10,10,12};
    GradeBonus[3] = {40,30,30,30,20,20,20,15,15,15,13};
    GradeBonus[4] = {50,40,40,40,40,30};
    ComboMul[0] = {0};
    ComboMul[1] = {0,2,2,4,4,4,4,5,5,10};
    ComboMul[2] = {0,4,5,6,7,8,9,10,11,15};
    ComboMul[3] = {0,5,8,10,12,13,14,15,16,20};
    ComboMul[4] = {0,5,8,10,12,13,14,15,16,20};
    for (int i=0; i<GradeDec.size(); ++i) GradeDec[i]=GradeDec[i]*5/3;
    for (int i=0; i<ArcadeAre.size(); ++i) ArcadeAre[i]=ArcadeAre[i]*50/3;
    for (int i=0; i<ArcadeLcd.size(); ++i) ArcadeLcd[i]=ArcadeLcd[i]*50/3;
    for (int i=0; i<ArcadeLock.size(); ++i) ArcadeLock[i]=ArcadeLock[i]*50/3;
    for (int i=0; i<CoolTm.size(); ++i) CoolTm[i]*=1000;
    for (int i=0; i<RegretTm.size(); ++i) RegretTm[i]*=1000;
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL bQuit = FALSE;
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = HBRUSH(GetStockObject (BLACK_BRUSH));
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass(&wc);
    //hWnd = GetConsoleWindow();
    hWnd = CreateWindow("GLSample", "qqwq", WS_CAPTION|WS_POPUPWINDOW|WS_VISIBLE, 0, 0, 1500, 1000, NULL, NULL, hInstance, NULL);
    EnableOpenGL(hWnd, &hDC, &hRC);
    InitChar(); Global.sz=1;
    for (int i=1; i<155; ++i) Flip[i]=i;
    #define FL(i, j) Flip[i]=j, Flip[j]=i
    Piece[1][0] = ClassPiece(4,4,0x66CCFF,-1,{{0,0,0,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    Piece[2][0] = ClassPiece(3,3,0x0080FF,-1,{{1,0,0},{1,1,1},{0,0,0}});
    Piece[3][0] = ClassPiece(3,3,0xFFA500,-1,{{0,0,1},{1,1,1},{0,0,0}});
    Piece[4][0] = ClassPiece(3,3,0xFFE211,-1,{{0,1,1},{0,1,1},{0,0,0}});
    Piece[5][0] = ClassPiece(3,3,Mix(0x000000,0x33EE00,0.1),-1,{{0,1,1},{1,1,0},{0,0,0}});
    Piece[6][0] = ClassPiece(3,3,0xEE82EE,-1,{{0,1,0},{1,1,1},{0,0,0}});
    Piece[7][0] = ClassPiece(3,3,0xEE0000,-1,{{1,1,0},{0,1,1},{0,0,0}});
    FL(2, 3);
    FL(5, 7);
    Piece[8][0] = ClassPiece(2,2,0xFFAFBE,0,{{1,0},{1,1}});
    Piece[9][0] = ClassPiece(3,3,Mix(0x000000,0x00FFCC,0.1),0,{{0,0,0},{1,1,1},{0,0,0}});
    Piece[10][0] = ClassPiece(2,2,Mix(0x000000,0x99FFFF,0.1),0,{{1,1},{0,0}});
    Piece[11][0] = ClassPiece(2,2,0x006666,0,{{0,1},{0,0}});
    Piece[12][0] = ClassPiece(5,5,0x66CCAA,-1,{{0,0,0,0,0},{0,0,0,0,0},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    Piece[13][0] = ClassPiece(3,3,0xDF3782,0,{{0,1,0},{0,1,0},{1,1,1}});
    Piece[14][0] = ClassPiece(3,3,0xB17D43,-1,{{1,0,1},{1,1,1},{0,0,0}});
    Piece[15][0] = ClassPiece(3,3,0x9E00FF,0,{{0,0,1},{0,0,1},{1,1,1}});
    Piece[16][0] = ClassPiece(4,4,0x9999FF,-1,{{0,0,1,0},{0,1,1,1},{0,0,1,0},{0,0,0,0}});
    Piece[17][0] = ClassPiece(3,3,0xD29700,0,{{1,0,0},{1,1,1},{0,1,0}});
    Piece[18][0] = ClassPiece(3,3,0x00AAAA,0,{{0,0,1},{1,1,1},{0,1,0}});
    FL(17, 18);
    Piece[19][0] = ClassPiece(3,3,0x00AA00,0,{{1,0,0},{1,1,1},{0,0,1}});
    Piece[20][0] = ClassPiece(3,3,0xAA0000,0,{{0,0,1},{1,1,1},{1,0,0}});
    FL(19, 20);
    Piece[21][0] = ClassPiece(4,4,0x3333FF,-1,{{0,0,0,0},{1,0,0,0},{1,1,1,1},{0,0,0,0}});
    Piece[22][0] = ClassPiece(4,4,0xFF5000,-1,{{0,0,0,0},{0,0,0,1},{1,1,1,1},{0,0,0,0}});
    FL(21, 22);
    Piece[23][0] = ClassPiece(4,4,0x00AAFF,-1,{{0,0,0,0},{0,0,1,0},{1,1,1,1},{0,0,0,0}});
    Piece[24][0] = ClassPiece(4,4,0xCC99FF,-1,{{0,0,0,0},{0,1,0,0},{1,1,1,1},{0,0,0,0}});
    FL(23, 24);
    Piece[25][0] = ClassPiece(4,4,Mix(0x000000,0xAAFF66,0.1),-1,{{0,0,0,0},{0,0,1,1},{1,1,1,0},{0,0,0,0}});
    Piece[26][0] = ClassPiece(4,4,0xFF6666,-1,{{0,0,0,0},{1,1,0,0},{0,1,1,1},{0,0,0,0}});
    FL(25, 26);
    Piece[27][0] = ClassPiece(3,3,0xCCCC00,-1,{{0,1,1},{1,1,1},{0,0,0}});
    Piece[28][0] = ClassPiece(3,3,0xFCC000,-1,{{1,1,0},{1,1,1},{0,0,0}});
    FL(27, 28);
    Piece[29][0] = ClassPiece(3,3,0x5F630E,0,{{0,0,1},{0,1,1},{1,1,0}});
    PName[30]=132; Piece[30][0]=ClassPiece(6,6,0x96D6CB,-2,{{0,0,0,0,0,0},{0,0,0,0,0,0},{1,1,1,1,1,1},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}});
    Char[132] = {"hw"};
    PName[31]='d'; Piece[31][0]=ClassPiece(4,4,0x62FFE0,-2,{{0,1,1,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    PName[32]=133; Piece[32][0]=ClassPiece(3,3,0xEB22B9,0,{{0,1,0},{1,1,1},{1,1,0}});
    Char[133] = {"jt10ukghny3"};
    PName[33]='0'; Piece[33][0]=ClassPiece(3,3,0xCCCC99,-1,{{1,1,1},{1,1,1},{0,0,0}});
    PName[34]='e'; Piece[34][0]=ClassPiece(3,3,0xC4A179,0,{{1,0,0},{1,1,0},{1,1,1}});
    PName[35]=134; Piece[35][0]=ClassPiece(4,4,0x9A1751,-1,{{0,0,0,1},{1,1,1,1},{0,0,0,1},{0,0,0,0}});
    Char[134] = {"kgj","hw23"};
    PName[36]='x'; Piece[36][0]=ClassPiece(4,4,0xD1D1FF,-1,{{0,0,1,0},{1,1,1,1},{0,0,1,0},{0,0,0,0}});
    PName[37]=145; Piece[37][0]=ClassPiece(3,3,0x006F9B,0,{{0,1,0},{1,1,1},{1,0,1}});
    Char[145] = {"akqsoe","c6"};
    PName[38]='c'; Piece[38][0]=ClassPiece(4,4,0xF3BDBD,-2,{{1,0,0,1},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    PName[39]='|'; Piece[39][0]=ClassPiece(5,5,0x686998,-2,{{0,0,0,0,0},{0,0,1,0,0},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    PName[40]=135; Piece[40][0]=ClassPiece(5,5,0xFFD17C,-2,{{0,0,0,0,0},{0,0,0,0,1},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    Char[135] = {"a452squ"};
    PName[41]=136; Piece[41][0]=ClassPiece(5,5,0x48A4FF,-2,{{0,0,0,0,0},{1,0,0,0,0},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    Char[136] = {"d265zvx"};
    PName[42]='y'; Piece[42][0]=ClassPiece(5,5,0xB59ECD,-2,{{0,0,0,0,0},{0,1,0,0,0},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    PName[43]='1'; Piece[43][0]=ClassPiece(5,5,0x7ED0F8,-2,{{0,0,0,0,0},{0,0,0,1,0},{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    PName[44]='n'; Piece[44][0]=ClassPiece(5,5,0xFF8F66,-2,{{0,0,0,0,0},{1,1,0,0,0},{0,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    PName[45]='h'; Piece[45][0]=ClassPiece(5,5,0x7ECD3F,-2,{{0,0,0,0,0},{0,0,0,1,1},{1,1,1,1,0},{0,0,0,0,0},{0,0,0,0,0}});
    PName[46]='p'; Piece[46][0]=ClassPiece(4,4,0xCBB344,-2,{{1,1,0,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    PName[47]='q'; Piece[47][0]=ClassPiece(4,4,0xDCE654,-2,{{0,0,1,1},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    PName[48]='f'; Piece[48][0]=ClassPiece(4,4,0x3A96B5,-2,{{1,0,1,0},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    PName[49]=137; Piece[49][0]=ClassPiece(4,4,0xE2B977,-2,{{0,1,0,1},{1,1,1,1},{0,0,0,0},{0,0,0,0}});
    Char[137] = {"ae","d7","nkp"};
    PName[50]='<'; Piece[50][0]=ClassPiece(4,4,0xFFBF00,-1,{{0,0,0,1},{0,0,0,1},{1,1,1,1},{0,0,0,0}});
    PName[51]='>'; Piece[51][0]=ClassPiece(4,4,0x93B0CC,-1,{{1,0,0,0},{1,0,0,0},{1,1,1,1},{0,0,0,0}});
    PName[52]='r'; Piece[52][0]=ClassPiece(4,4,0xA879A7,-1,{{0,1,0,0},{0,1,0,0},{1,1,1,1},{0,0,0,0}});
    PName[53]=138; Piece[53][0]=ClassPiece(4,4,0xC6F82F,-1,{{0,0,1,0},{0,0,1,0},{1,1,1,1},{0,0,0,0}});
    Char[138] = {"bco3","iq0"};
    PName[54]=139; Piece[54][0]=ClassPiece(4,4,0x1D9C58,-1,{{1,0,0,0},{1,1,1,1},{0,1,0,0},{0,0,0,0}});
    Char[139] = {"afxz","hn","io"};
    PName[55]=140; Piece[55][0]=ClassPiece(4,4,0xED396F,-1,{{0,0,0,1},{1,1,1,1},{0,0,1,0},{0,0,0,0}});
    Char[140] = {"pmy","io","dj"};
    PName[56]='7'; Piece[56][0]=ClassPiece(4,4,0x8F9878,-1,{{0,1,0,0},{1,1,1,1},{0,0,0,1},{0,0,0,0}});
    PName[57]=141; Piece[57][0]=ClassPiece(4,4,0x92837C,-1,{{0,0,1,0},{1,1,1,1},{1,0,0,0},{0,0,0,0}});
    Char[141] = {"ae","dswqv7"};
    PName[58]=142; Piece[58][0]=ClassPiece(4,4,0x72FF72,-1,{{1,0,0,0},{1,1,1,1},{0,0,0,1},{0,0,0,0}});
    Char[142] = {"jdh6:4"};
    PName[59]=143; Piece[59][0]=ClassPiece(4,4,0xFF9999,-1,{{0,0,0,1},{1,1,1,1},{1,0,0,0},{0,0,0,0}});
    Char[143] = {"aepu028<"};
    PName[60]='$'; Piece[60][0]=ClassPiece(4,4,0xE1CD68,-1,{{0,1,0,0},{1,1,1,1},{0,0,1,0},{0,0,0,0}});
    PName[61]='%'; Piece[61][0]=ClassPiece(4,4,0x658666,-1,{{0,0,1,0},{1,1,1,1},{0,1,0,0},{0,0,0,0}});
    PName[62]='4'; Piece[62][0]=ClassPiece(4,4,0x6B3131,-1,{{0,0,1,0},{0,0,1,1},{1,1,1,0},{0,0,0,0}});
    PName[63]=144; Piece[63][0]=ClassPiece(4,4,0x6B5531,-1,{{0,1,0,0},{1,1,0,0},{0,1,1,1},{0,0,0,0}});
    Char[144] = {"ko","l04","n28"};
    PName[64]='G'; Piece[64][0]=ClassPiece(4,4,0xD44AD6,-1,{{0,0,0,0},{0,1,1,1},{1,1,0,1},{0,0,0,0}});
    PName[65]='?'; Piece[65][0]=ClassPiece(4,4,0xB56AFF,-1,{{0,0,0,0},{1,1,1,0},{1,0,1,1},{0,0,0,0}});
    PName[66]='/'; Piece[66][0]=ClassPiece(5,5,0xA8C080,-2,{{0,0,0,0,0},{1,1,1,0,0},{0,0,1,1,1},{0,0,0,0,0},{0,0,0,0,0}});
    PName[67]='\\'; Piece[67][0]=ClassPiece(5,5,0xA8C09F,-2,{{0,0,0,0,0},{0,0,1,1,1},{1,1,1,0,0},{0,0,0,0,0},{0,0,0,0,0}});
    PName[68]=146; Piece[68][0]=ClassPiece(4,4,0x3B5224,-2,{{0,0,0,0},{1,1,1,0},{0,1,1,1},{0,0,0,0}});
    Char[146] = {"gku02yoig","c6"};
    PName[69]=147; Piece[69][0]=ClassPiece(4,4,0x114514,-1,{{0,0,0,0},{0,1,1,1},{1,1,1,0},{0,0,0,0}});
    Char[147] = {"b0x","qn<"};
    PName[70]=148; Piece[70][0]=ClassPiece(4,4,0x5F3C91,-1,{{0,0,1,1},{1,1,1,0},{0,0,1,0},{0,0,0,0}});
    Char[148] = {"fbhs","eow6"};
    PName[71]=149; Piece[71][0]=ClassPiece(4,4,0x913C72,-1,{{1,1,0,0},{0,1,1,1},{0,1,0,0},{0,0,0,0}});
    Char[149] = {"bfpvxtjdh;"};
    PName[72]='K'; Piece[72][0]=ClassPiece(3,3,0x8CE7CC,0,{{1,1,0},{1,1,1},{1,0,0}});
    PName[73]=150; Piece[73][0]=ClassPiece(3,3,0x96DCFF,0,{{0,1,1},{1,1,1},{0,0,1}});
    Char[150] = {"ae","d7","blrs"};
    PName[74]=151; Piece[74][0]=ClassPiece(4,4,0x5E91D8,-1,{{0,1,0,0},{1,1,1,0},{0,0,1,1},{0,0,0,0}});
    Char[151] = {"gku0wr","w2yoi"};
    PName[75]=152; Piece[75][0]=ClassPiece(4,4,0xCC5DE8,-1,{{0,0,1,0},{0,1,1,1},{1,1,0,0},{0,0,0,0}});
    Char[152] = {"dbfln","lpz57=A"};
    PName[76]='2'; Piece[76][0]=ClassPiece(4,4,0x65CF70,-1,{{1,1,0,0},{0,1,0,0},{0,1,1,1},{0,0,0,0}});
    PName[77]='5'; Piece[77][0]=ClassPiece(4,4,0x65B3CF,-1,{{0,0,1,1},{0,0,1,0},{1,1,1,0},{0,0,0,0}});
    PName[78]='{'; Piece[78][0]=ClassPiece(4,4,0x6D6D14,-1,{{1,0,0,0},{1,1,0,0},{0,1,1,1},{0,0,0,0}});
    PName[79]='}'; Piece[79][0]=ClassPiece(4,4,0x64334B,-1,{{0,0,0,1},{0,0,1,1},{1,1,1,0},{0,0,0,0}});
    PName[80]=153; Piece[80][0]=ClassPiece(3,3,0xA2FF00,0,{{0,0,1},{1,0,1},{1,1,1}});
    Char[153] = {"4ko8"};
    PName[81]='u'; Piece[81][0]=ClassPiece(3,3,0x1CFF18,0,{{1,0,0},{1,0,1},{1,1,1}});
    PName[82]=154; Piece[82][0]=ClassPiece(3,3,0x18E0FF,0,{{1,0,0},{1,1,1},{1,0,1}});
    Char[154] = {"fz","kghn<B"};
    PName[83]=155; Piece[83][0]=ClassPiece(3,3,0x5D54FF,0,{{0,0,1},{1,1,1},{1,0,1}});
    Char[155] = {"akqrn","d28"};
    PName[84]=156; Piece[84][0]=ClassPiece(4,4,0xBA4C4C,-1,{{1,0,0,0},{1,1,1,0},{0,0,1,1},{0,0,0,0}});
    Char[156] = {"ear48"};
    PName[85]=157; Piece[85][0]=ClassPiece(4,4,0xBAA147,-1,{{0,0,0,1},{0,1,1,1},{1,1,0,0},{0,0,0,0}});
    Char[157] = {"dbfpvx37"};
    PName[86]=158; Piece[86][0]=ClassPiece(3,3,0x7B60D3,0,{{0,1,1},{1,1,0},{1,1,0}});
    Char[158] = {"ms265zplo"};
    PName[87]='a'; Piece[87][0]=ClassPiece(3,3,0x60D395,0,{{1,1,0},{0,1,1},{0,1,1}});
    PName[88]='M'; Piece[88][0]=ClassPiece(4,4,0x834BEB,-1,{{1,1,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}});
    PName[89]='m'; Piece[89][0]=ClassPiece(4,4,0xBC79B9,-1,{{0,0,1,1},{0,1,1,0},{1,1,0,0},{0,0,0,0}});
    for (int i=40; i<=80; i+=2) FL(i,i+1);
    PName[90]='@'; Piece[90][0]=ClassPiece(4,4,0xCCCCCC,-1,{{0,1,1,1},{0,1,1,1},{0,1,1,1},{0,0,0,0}});
    PName[91]='o'; Piece[91][0]=ClassPiece(4,4,0xAAAAAA,-1,{{0,1,1,1},{0,1,0,1},{0,1,1,1},{0,0,0,0}});
    PName[92]='^'; Piece[92][0]=ClassPiece(3,3,0xCDA9A9,-1,{{0,1,0},{1,0,1},{0,0,0}});
    PName[93]=','; Piece[93][0]=ClassPiece(3,3,0x45C9AE,-1,{{1,0,0},{0,1,0},{0,0,0}});
    PName[94]=':'; Piece[94][0]=ClassPiece(3,3,0x7EAEC8,-1,{{0,0,0},{1,0,1},{0,0,0}});
    PName[95]='('; Piece[95][0]=ClassPiece(3,3,0xC2C25B,-1,{{1,0,0},{0,1,1},{0,0,0}});
    PName[96]=')'; Piece[96][0]=ClassPiece(3,3,0xD3D38D,-1,{{0,0,1},{1,1,0},{0,0,0}});
    FL(95, 96);
    PName[97]=';'; Piece[97][0]=ClassPiece(4,4,0x6F8F79,-1,{{0,0,0,0},{1,1,0,1},{0,0,0,0},{0,0,0,0}});
    PName[98]='['; Piece[98][0]=ClassPiece(3,3,0x9CC199,-1,{{0,0,1},{1,0,1},{0,0,0}});
    PName[99]=']'; Piece[99][0]=ClassPiece(3,3,0x999FC1,-1,{{1,0,0},{1,0,1},{0,0,0}});
    FL(98, 99);
    PName[100]='#'; Piece[100][0]=ClassPiece(3,3,0x229468,-1,{{1,0,1},{1,0,1},{0,0,0}});
    #undef FL
    /*
    a b c d e
    f g h i j
    k l m n o
    p q r s t
    u v w x y
    z 0 1 2 3
    4 5 6 7 8
    9 : ; < =
    > ? @ A B
    C D E F G
    */
    #warning piece
    Piece[151][0] = ClassPiece(1,1,0xFFFF99,-1,{{1}});
    Piece[152][0] = ClassPiece(1,1,0x8800FF,-1,{{1}});
    Piece[153][0] = ClassPiece(1,1,0x444444,-1,{{1}});
    Piece[154][0] = ClassPiece(1,1,0x888888,-1,{{1}});
    PName[151]=128; PName[152]=129;
    PName[153]=130; PName[154]=131;
    Char[128] = {"mh","nj","st","x3","w1","vz","qp","lf"};
    Char[129] = {"acm","ckpv","mwy","wojd"};
    Char[130] = {"fj3zf","f3","jz"};
    Char[131] = {"fj3zf"};
    for (int i=1; i<155; ++i) {
        for (int j=1; j<4; ++j) Piece[i][j]=RotatePiece(Piece[i][j-1]);
    }
    for (int i=1; i<155; ++i) {
        for (int j=0; j<4; ++j) {
            for (int x=0; x<10; ++x) {
                for (int y=0; y<10; ++y) {
                    if (Piece[i][j].B[x][y]) DDP[i][j].push_back(make_pair(x,y));
                }
            }
        }
    }
    ll CurT = clock();
    int PaintTm = 0;
    int PrevPlrs = Plrs;
    int ClearOnDuel = 0;
    vector<string> Co;
    bool EscCD = false;
    Launch("marathon");
    while (!bQuit) {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
            if (msg.message==WM_QUIT) bQuit=true;
            else {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        else {
            if (!CheckKey(VK_ESCAPE)) EscCD=false;
            Focus = (hWnd==GetFocus());
            DX0 = Plr[0].DX+Plr[0].DXDel;
            if (ForceLaunch!="") {
                Launch(ForceLaunch); ForceLaunch="";
                continue;
            }
            bool HumanAlive = false;
            for (int i=0; i<Plrs; ++i) {
                if ((!Plr[i].Over)&&(!Plr[i].Bot)) HumanAlive=true;
            }
            if ((Plrs>1)&&(CheckKey(VK_LBUTTON))) {
                POINT p; GetCursorPos(&p);
                ScreenToClient(GetForegroundWindow(), &p);
                p.y-=96; p.x-=100;
                p.y/=4.86/5.00; p.x/=4.98/5.00;
                for (int i=0; i<Plrs; ++i) {
                    if (Plr[i].Over) continue;
                    if ((p.y>=Plr[i].KX)&&(p.y<=Plr[i].KX+(Plr[i].DX+Plr[i].DXDel)*Plr[i].sz)&&
                    (p.x>=Plr[i].KY)&&(p.x<=Plr[i].KY+Plr[i].LY*Plr[i].sz)) {
                        if ((HumanAlive)&&(!QuickPlay)) {
                            for (int j=0; j<Plrs; ++j) {
                                if ((!Plr[j].Over)&&(!Plr[j].Bot)&&(i!=j)) Plr[j].Tar=i;
                            }
                        }
                        if (!HumanAlive) Obs=i;
                    }
                }
            }
            #warning console
            if (Con) {
                glClearColor(BackgroundRatio, BackgroundRatio, BackgroundRatio, 0);
                glClear(GL_COLOR_BUFFER_BIT);
                glPushMatrix();
                ll NewT=clock(); int del=int(NewT-CurT);
                CurT = NewT;
                for (int i=0; i<Plrs; ++i) {
                    Plr[i].begtm += ll(del);
                    for (pair<int,pair<lll,ll> > &o : Plr[i].Rec) o.second.second+=del;
                    if ((!Plr[i].Over)||((Plrs==1)&&(!Zen))||(QuickPlay)) Plr[i].Paint(del);
                }
                for (int i=0; i<Plrs; ++i) {
                    if (!Plr[i].Over) {
                        int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==i)||((Plr[i].AtkType==6)&&(TarRem[i][j])))&&(!Plr[j].Over));
                        Plr[i].PaintParticle(del, tars);
                    }
                    MX[i] = Plr[i].KX+Plr[i].DX*0.5*Plr[i].sz;
                    MY[i] = Plr[i].KY+Plr[i].LY*0.5*Plr[i].sz;
                }
                Global.PaintGlobal(del);
                glPopMatrix();
                SwapBuffers(hDC);
                if ((CheckKey(VK_ESCAPE))&&(!EscCD)) {
                    EscCD = true;
                    Con=false; continue;
                }
                if ((ForceExecute!="")&&(ForceExecute.back()=='~')) {
                    Command=ForceExecute; ForceExecute=""; Command.pop_back();
                }
                if ((ForceExecute!="")&&(ForceExecute.front()=='+')) {
                    Command=Command+ForceExecute.substr(1,ForceExecute.size()-1); ForceExecute="";
                }
                if ((ForceExecute!="")&&(ForceExecute.front()=='~')) {
                    Command=Command+ForceExecute.substr(1,ForceExecute.size()-1); ForceExecute=Command;
                }
                if (((Command.size())&&(CheckKey(VK_RETURN)))||((ForceExecute!="")&&(ForceExecute.back()!='~'))) {
                    if (ForceExecute!="") {
                        Command=ForceExecute; ForceExecute="";
                    }
                    if (!Command.back()) Command.pop_back();
                    for (int i=0; i<Command.size(); ++i) {
                        if (Command[i]==' ') Command[i]=0;
                    }
                    while (CheckKey(VK_RETURN));
                    string cur=""; Co.clear();
                    for (char ch : Command) {
                        if (ch) cur.push_back(ch);
                        else {
                            Co.push_back(cur); cur="";
                        }
                    }
                    if (cur.size()) Co.push_back(cur);
                    Con=false; Command=""; continue;
                }
                vector<char> lst; lst.push_back(' '); lst.push_back(VK_BACK); lst.push_back(VK_DELETE);
                for (char i='0'; i<='9'; ++i) lst.push_back(i);
                for (char i='A'; i<='Z'; ++i) lst.push_back(i);
                vector<char> key;
                for (char ch : lst) {
                    bool sta = CheckKey(ch);
                    if ((sta)&&(!ConKey[ch])) key.push_back(ch);
                    ConKey[ch] = sta;
                }
                for (char ch : key) {
                    if (ch==VK_BACK) {
                        if (Command.size()) Command.pop_back();
                        continue;
                    }
                    if (ch==VK_DELETE) {
                        Command=""; continue;
                    }
                    char dy = ch;
                    if ((ch>='A')&&(ch<='Z')) dy+='a'-'A';
                    else if (ch==' ') dy=0;
                    if ((ch!=' ')||((Command.size())&&(Command.back()))) Command.push_back(dy);
                }
                continue;
            }
            if ((CheckKey(VK_ESCAPE))&&(!EscCD)) {
                EscCD = true;
                for (int i=0; i<999; ++i) ConKey[i]=false;
                Con=true; continue;
            }
            if (Co.size()) {
                pair<int,string> o=Execute(Co); Co.clear();
                Respond=o.second; RespondColor=o.first; RespondTime=10000;
            }
            for (int i=0; i<Plrs; ++i) Plr[i].BeFrom=Plr[i].BeTo=false;
            if ((PlrsCnt>2)&&(Obs>=0)) {
                if (Plr[Obs].Tar>=0) Plr[Plr[Obs].Tar].BeTo=true;
                if (Plr[Obs].AtkType==6) {
                    for (int i=0; i<Plrs; ++i) {
                        if (TarRem[Obs][i]) Plr[i].BeTo=true;
                    }
                }
                for (int i=0; i<Plrs; ++i) {
                    if (Plr[i].Tar==Obs) Plr[i].BeFrom=true;
                    if ((Plr[i].AtkType==6)&&(TarRem[i][Obs])) Plr[i].BeFrom=true;
                }
            }
            if ((Obs>=0)&&(Plr[Obs].Over)&&((Plr[Obs].Bot)||(!QuickPlay))) {
                bool ok = true;
                if (QuickPlay) {
                    for (int i=0; i<Plrs; ++i) {
                        if ((!Plr[i].Bot)&&(!Plr[i].Over)) ok=false;
                    }
                }
                if ((!Plr[Plr[Obs].LstAtk].Over)&&(ok)) Obs=Plr[Obs].LstAtk;
                else Obs=-1;
            }
            for (int i=0; i<Plrs; ++i) {
                if ((Plr[i].Over)&&(QuickPlay)&&(Plr[i].Bot)) {
                    Plr[i].Over=KOCount[i]=false; Plr[i].ClearAll(time(0));
                }
            }
            if (Obs<0) {
                for (int i=0; i<Plrs; ++i) {
                    if ((!Plr[i].Bot)&&(!Plr[i].Over)) {
                        if (Obs<0) Obs=i;
                    }
                }
                for (int i=0; i<Plrs; ++i) {
                    if ((Plr[i].Bot)&&(!Plr[i].Over)) {
                        if (Obs<0) Obs=i;
                    }
                }
            }
            vector<int> PlrOrd;
            for (int i=0; i<Plrs; ++i) {
                if ((!Plr[i].Bot)&&((!Plr[i].Over)||(QuickPlay))) PlrOrd.push_back(i);
            }
            for (int i=0; i<Plrs; ++i) {
                if ((Plr[i].Bot)&&(!Plr[i].Over)) PlrOrd.push_back(i);
            }
            if (PlrOrd.size()==1) {
                Plr[PlrOrd[0]].SKX=0; Plr[PlrOrd[0]].SKY=400; Plr[PlrOrd[0]].Ssz=20;
            }
            else if (PlrOrd.size()==2) {
                if (PlrOrd[0]!=Obs) swap(PlrOrd[0],PlrOrd[1]);
                Plr[PlrOrd[0]].SKX=0; Plr[PlrOrd[0]].SKY=100; Plr[PlrOrd[0]].Ssz=20;
                Plr[PlrOrd[1]].SKX=0; Plr[PlrOrd[1]].SKY=600; Plr[PlrOrd[1]].Ssz=20;
            }
            else if (PlrOrd.size()>2){
                int pos = 0;
                vector<int> AtkOrd = PlrOrd;
                if (QuickPlay) {
                    stable_sort(AtkOrd.begin(), AtkOrd.end(), [](int x, int y) {
                        return Plr[x].Score>Plr[y].Score;
                    });
                }
                int lnc=11; double ssz=4;
                if (PlrOrd.size()<=81) {
                    lnc=10; ssz=4.3;
                }
                if (PlrOrd.size()<=64) {
                    lnc=9; ssz=4.7;
                }
                if (PlrOrd.size()<=49) {
                    lnc=8; ssz=5.4;
                }
                if (PlrOrd.size()<=36) {
                    lnc=7; ssz=6.2;
                }
                if (PlrOrd.size()<=31) {
                    lnc=6; ssz=7.1;
                }
                if (PlrOrd.size()<=21) {
                    lnc=5; ssz=8.8;
                }
                if (PlrOrd.size()<=13) {
                    lnc=4; ssz=11.4;
                }
                if (PlrOrd.size()<=7) {
                    lnc=3; ssz=15;
                }
                if (PlrOrd.size()<=5) {
                    lnc=2; ssz=17;
                }
                for (int i : AtkOrd) {
                    if (Obs==i) {
                        Plr[i].SKX=0; Plr[i].SKY=100; Plr[i].Ssz=20;
                        continue;
                    }
                    int yn=pos%lnc; if ((pos/lnc)&1) yn=lnc-1-yn;
                    Plr[i].SKX=110*ssz/4.0*(pos/lnc)-80; Plr[i].SKY=90*ssz/4.0*yn+450; Plr[i].Ssz=ssz;
                    if (lnc==2) Plr[i].SKY+=100;
                    ++pos;
                }
            }
            PlrsCnt = 0;
            for (int i=0; i<Plrs; ++i) {
                PlrsCnt+=(!Plr[i].Over); if (Plr[i].Over) continue;
                Plr[i].VSRnk = 1;
                for (int j=0; j<Plrs; ++j) {
                    if ((make_pair(Plr[j].SumAttack+Plr[j].SumDig,j)>make_pair(Plr[i].SumAttack+Plr[i].SumDig,i))&&(!Plr[j].Over)) ++Plr[i].VSRnk;
                }
                if (QuickPlay) {
                    Plr[i].VSRnk = 1;
                    for (int j=0; j<Plrs; ++j) {
                        if ((make_pair(Plr[j].Score,j)>make_pair(Plr[i].Score,i))&&(!Plr[j].Over)) ++Plr[i].VSRnk;
                    }
                }
            }
            /*if ((Plrs>2)&&(PrevPlrs>2)&&(PlrsCnt==2)&&(ClearOnDuel)) {
                int seed = time(0);
                for (int i=0; i<Plrs; ++i) {
                    if (Plr[i].Over) continue;
                    for (int j=1; j<=Plr[i].LX; ++j) {
                        for (int k=1; k<=Plr[i].LY; ++k) {
                            Plr[i].B[j][k]=Plr[i].C[j][k]=0;
                        }
                    }
                    Plr[i].Hold=0; Plr[i].Next.clear(); Plr[i].gen=mt19937(seed);
                }
            }*/
            PrevPlrs = PlrsCnt;
            ll NewT=clock(); int del=int(NewT-CurT);
            CurT=NewT; PaintTm+=del;
            for (int i=0; i<Plrs; ++i) {
                for (int j=0; j<Plrs; ++j) TarRem[i][j]=max(0,TarRem[i][j]-del);
                ShiftCD[i] = max(0,ShiftCD[i]-del);
            }
            for (int i=0; i<Plrs; ++i) {
                if (Plr[i].Tar>=0) TarRem[Plr[i].Tar][i]=3000;
            }
            int AILim = 5;
            if (Plrs>40) AILim=4;
            if (Plrs>50) AILim=3;
            if (Plrs>60) AILim=2;
            if (Plrs>70) AILim=1;
            vector<int> Bot;
            for (int i=0; i<Plrs; ++i) {
                if ((Odoo)&&(ConstE)) Apply(i,ConstE,0,100);
            }
            for (int i=0; i<Plrs; ++i) {
                int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==i)||(((Plr[i].AtkType==6)&&(TarRem[i][j]))))&&(!Plr[j].Over));
                if (Plr[i].Bot) Bot.push_back(i);
                else Plr[i].Frame(del,tars);
            }
            if (Bot.size()>AILim) shuffle(Bot.begin(),Bot.end(),rng);   
            if (Bot.size()==Plrs) AILim=max(AILim,10);
            AILim = min(AILim,int(Bot.size()));
            for (int id=0; id<Bot.size(); ++id) {
                int i = Bot[id];
                int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==i)||(((Plr[i].AtkType==6)&&(TarRem[i][j]))))&&(!Plr[j].Over));
                UseAI=0; Plr[i].Frame(del,tars,(id<AILim));
                if (!UseAI) ++AILim;
            }
            vector<int> AggList, AggVal(Plrs,0);
            for (int i=0; i<Plrs; ++i) {
                curh[i] = Plr[i].QueryHeight();
                if (Plr[i].Over) continue;
                int Mins = int((clock()-Plr[i].begtm-BegDelay)/60000LL);
                int Agg = 12;
                if (Mins>=3) Agg+=4;
                if (Mins>=5) Agg+=4;
                if (Mins>=7) Agg+=4;
                int RecHeight = curh[i]+Plr[i].ActiveGarb.size();
                for (pair<int,pair<lll,ll> > o : Plr[i].Rec) RecHeight+=o.first;
                if ((RecHeight+7>Plr[i].DX)&&(!Plr[i].ModExpert)) Agg-=6;
                if ((Plr[i].ModSpin==2)||(Plr[i].ModMess==2)||(Plr[i].ModDivergence==2)) {
                    int GarbC = 0;
                    for (int x=1; x<=Plr[i].LX; ++x) {
                        for (int y=1; y<=Plr[i].LY; ++y) {
                            if (Plr[i].B[x][y]==154) {
                                ++GarbC; break;
                            }
                        }
                    }
                    Agg -= min(GarbC,5)*2;
                }
                Agg -= Plr[i].AggDec;
                Agg = max(Agg,0);
                AggVal[i] = Agg;
                if (Plr[i].AggDec) {
                    Plr[i].AggTm += del;
                    if (Plr[i].AggTm>=DecDis[min(int(DecDis.size()-1),Plr[i].QueryFloor())]) {
                        Plr[i].AggTm=0; --Plr[i].AggDec;
                    }
                }
                for (int j=0; j<((QuickPlay)?Agg:1); ++j) AggList.push_back(i);
            }
            stable_sort(AggList.begin(), AggList.end(), [](int x, int y) {
                return Plr[x].Score<Plr[y].Score;
            });
            for (int i=0; i<Plrs; ++i) {
                if ((!QuickPlay)&&(rnd(5000)<del)) Plr[i].Tar=-1;
                if ((QuickPlay)&&(Plr[i].Tar>=0)&&(!AggVal[Plr[i].Tar])) Plr[i].Tar=-1;
                if (QuickPlay) Plr[i].AtkType=7;
                if (Plr[i].AtkType==6) {
                    bool ok = false;
                    for (int j=0; j<Plrs; ++j) {
                        if ((!Plr[j].Over)&&(j!=i)&&(TarRem[i][j])) ok=true;
                    }
                    if (ok) Plr[i].Tar=-1;
                }
                if (((Plr[i].Tar<0)||(Plr[Plr[i].Tar].Over))&&(PlrsCnt>1)) {
                    vector<int> TarList;
                    for (int j=0; j<Plrs; ++j) {
                        if (i==j) continue;
                        if (!Plr[j].Over) TarList.push_back(j);
                    }
                    Plr[i].Tar = -1;
                    if (TarList.size()) {
                        shuffle(TarList.begin(), TarList.end(), rng);
                        if (Plr[i].AtkType==3) Plr[i].Tar=TarList[0];
                        else if (Plr[i].AtkType==4) {
                            if ((Plr[i].LstAtk>=0)&&(!Plr[Plr[i].LstAtk].Over)) Plr[i].Tar=Plr[i].LstAtk;
                            else Plr[i].Tar=TarList[0];
                        }
                        else if (Plr[i].AtkType==6) {
                            vector<int> lst;
                            for (int j : TarList) {
                                if ((!Plr[j].Over)&&(TarRem[i][j])) lst.push_back(j);
                            }
                            if (lst.size()) Plr[i].Tar=lst[rnd(lst.size())];
                            else Plr[i].Tar=TarList[0];
                        }
                        else if (Plr[i].AtkType==7) {
                            Plr[i].Tar = -1;
                            if (AggList.empty()) continue;
                            vector<int> NwList(Plrs,0);
                            bool exi=false; int ln=-1;
                            int mul=0; int NwTot=0;
                            for (int j=0; j<AggList.size(); ++j) {
                                if (AggList[j]==i) exi=true;
                                if ((AggList[j]!=i)&&(exi)) {
                                    NwTot += (11-mul)*max(1,Plr[AggList[j]].QueryFloor()-6)/2;
                                    NwList[AggList[j]] += (11-mul)*max(1,Plr[AggList[j]].QueryFloor()-6)/2;
                                    if (AggList[j]!=ln) {
                                        ++mul; if (mul>10) break;
                                    }
                                    ln = AggList[j];
                                }
                                if ((exi)&&(AggList[j]!=i)&&(j+1==AggList.size())&&(mul<=10)) {
                                    j=max(0,j-10); mul+=4;
                                }
                            }
                            exi=false; ln=-1; mul=0;
                            for (int j=AggList.size()-1; j>=0; --j) {
                                if (AggList[j]==i) exi=true;
                                if ((AggList[j]!=i)&&(exi)) {
                                    NwTot+=min(11,20-mul); NwList[AggList[j]]+=min(11,20-mul);
                                    if (AggList[j]!=ln) {
                                        ++mul; if (mul>10) break;
                                    }
                                    ln = AggList[j];
                                }
                            }
                            if (NwTot) {
                                int rn = rnd(NwTot);
                                for (int j=0; j<Plrs; ++j) {
                                    if (rn<NwList[j]) {
                                        Plr[i].Tar=j; break;
                                    }
                                    rn -= NwList[j];
                                }
                            }
                            if (Plr[i].Atk.size()>1) {
                                int att = 10;
                                while (att--) {
                                    if (AggList.empty()) break;
                                    int nw = AggList[rnd(AggList.size())];
                                    if (nw!=i) {
                                        Plr[i].Tar=nw; break;
                                    }
                                }
                            }
                        }
                        else {
                            vector<pair<int,int> > lst;
                            int currnk = Plr[i].VSRnk;
                            for (int i : TarList) {
                                int val = 0;
                                if (Plr[i].AtkType==1) val=-curh[i];
                                else if (Plr[i].AtkType==2) val=curh[i];
                                else val=Plr[i].SKO;
                                lst.push_back(make_pair(val*10000+rnd(10000),i));
                            }
                            shuffle(lst.begin(), lst.end(), rng);
                            stable_sort(lst.begin(), lst.end(), [](pair<int,int> x, pair<int,int> y) {
                                return x.first>y.first;
                            });
                            vector<int> pool;
                            for (int i=0; i<min(10,int(TarList.size())); ++i) {
                                for (int j=i; j<10; ++j) pool.push_back(lst[i].second);
                            }
                            Plr[i].Tar = pool[rnd(pool.size())];
                        }
                    }
                }
                #warning atk
                while (Plr[i].Atk.size()) {
                    int nw = Plr[i].Atk.front().first;
                    if (!nw) {
                        if ((Odoo)&&(Plr[i].Atk.front().second)) Apply(i,Plr[i].Atk.front().second,0,i);
                        Plr[i].Atk.pop(); continue;
                    }
                    int tar=Plr[i].Tar; ll curtm=clock();
                    //printf("%d : %d -> %d\n",i,nw,tar);
                    if (tar>=0) {
                        if (QuickPlay) {
                            int Mins = int((curtm-Plr[tar].begtm-BegDelay)/60000LL);
                            if (Mins>=11-2*(Plr[tar].ModExpert==2)) nw=nw*3/2+rnd(2)*(nw*3%2);
                            else if (Mins>=9-2*(Plr[tar].ModExpert==2)) nw=nw*5/4+(rnd(4)<nw*5%4);
                            if (Plr[tar].AggDec==12) nw=nw*3/4+(rnd(4)<nw*3%4);
                        }
                        if (Plr[tar].ModStrength) nw*=(1+Plr[tar].ModStrength);
                        if (Plr[tar].ModDivergence==2) nw=(nw/2)+rnd(2)*(nw%2);
                        if (Plr[tar].ModExpert==2) {
                            nw = nw*(200+Plr[tar].RecIncTm/1000);
                            nw = nw/200+(rnd(200)<nw%200);
                        }
                        int E = Plr[i].Atk.front().second;
                        int rnw = nw;
                        if (E==1) {
                            if (Plr[tar].EV[6]) nw=nw*2+(Plr[i].OgTm>0);
                            else if (Plr[tar].EV[2]) nw=nw*3/2+nw*3%2*rnd(2)+(Plr[i].OgTm>0);
                        }
                        if (E==2) {
                            if (Plr[tar].EV[1]) nw=nw*2+(Plr[i].OgTm>0);
                        }
                        if (E==6) {
                            if (Plr[tar].EV[1]) nw=nw*3/2+nw*3%2*rnd(2)+(Plr[i].OgTm>0);
                        }
                        if ((E==4)||(E==5)) {
                            if ((Plr[tar].EV[4])&&(Plr[tar].EV[5])&&(!Plr[tar].EV[1])) ++nw;
                        }
                        if (!E) {
                            if (Plr[tar].ScTm) ++nw;
                        }
                        while ((nw)&&(!Plr[tar].Cy.empty())) {
                            --nw;
                            if ((rnd(2))||(E!=Plr[tar].Cy.front().second)) Plr[tar].Cy.pop_front();
                        }
                        Apply(tar, E, rnw, i);
                        if (nw<1) {
                            Plr[i].Atk.pop(); continue;
                        }
                        nw = min(nw,Plr[tar].LX*5+100);
                        int RecSeg=9999; if (QuickPlay) RecSeg=4*(1+Plr[tar].ModStrength);
                        double InnerMess = 0.01*double(_InnerMess);
                        double SegMess = 0.01*double(_SegMess);
                        bool NoSame = false;
                        if (QuickPlay) {
                            double Mess = 0.03*Plr[tar].QueryFloor();
                            if (Plr[tar].ModMess) Mess+=0.25;
                            if (Plr[tar].ModMess==2) Mess+=0.75;
                            if (Plr[tar].ModExpert) Mess+=0.02*Plr[tar].QueryFloor();
                            if (Plr[tar].ModSpin==2) Mess+=0.3;
                            int Mins = 0;
                            if (Plr[tar].ModExpert==2) Mins=int((curtm-Plr[tar].begtm-BegDelay)/60000LL);
                            InnerMess = Mess;
                            if (Mins<6) InnerMess*=1.0-0.18*double(Plr[tar].AggDec)/12.0;
                            SegMess = Mess*2.5;
                            if (Mins<6) SegMess*=1.0-0.45*double(Plr[tar].AggDec)/12.0;
                            if (Mins>=11) {
                                NoSame=true; InnerMess=SegMess=1.0;
                            }
                        }
                        if ((!QuickPlay)&&(Plrs>2)&&(ShiftCD[tar])) InnerMess=SegMess=0.0;
                        if (Plr[tar].ModDivergence==2) {
                            InnerMess=SegMess=1.0; nw=min(nw,10);
                        }
                        int Luck = _Luck;
                        if (QuickPlay) {
                            Luck = 3-Plr[tar].QueryFloor()*3;
                            if (!Plr[tar].ModExpert) Luck+=33;
                            if (Plr[tar].ModMess) Luck-=25;
                            if (Plr[tar].ModStrength==2) Luck=50;
                        }
                        if (GarbageShape=="board") InnerMess=SegMess=0.0;
                        else if ((rndf()<SegMess)||((Plr[tar].LstHole<1)||(Plr[tar].LstHole>Plr[tar].LY))) Plr[tar].LstHole=Plr[tar].RollHole(Luck,NoSame);
                        int SegV = 0;
                        TemplatePos = 0;
                        if ((GarbageShape=="clear")||(GarbageShape=="arcade")) ClearTemplate=Plr[i].ClearShape;
                        else ClearTemplate.clear();
                        for (int _=0; _<nw; ++_) {
                            if (rndf()<InnerMess) Plr[tar].LstHole=Plr[tar].RollHole(Luck,NoSame);
                            lll gb = Plr[tar].RollGarb();
                            if (!Plr[tar].Rec.empty()) curtm=max(curtm,Plr[tar].Rec.back().second.second);
                            if (++SegV==RecSeg) {
                                curtm+=500LL; SegV=0;
                            }
                            if ((!Plr[tar].Rec.empty())&&((Plr[tar].Rec.back().second.second==curtm)&&(Plr[tar].Rec.back().second.first==gb))) ++Plr[tar].Rec.back().first;
                            else Plr[tar].Rec.push_back(make_pair(1,make_pair(gb,curtm)));
                        }
                        curtm = clock();
                        double fx=Plr[i].ravx-Plr[tar].KX, fy=Plr[i].ravy-Plr[tar].KY;
                        double ex=Plr[tar].ravx-Plr[tar].KX, ey=Plr[tar].ravy-Plr[tar].KY;
                        double ss = 5+2*min(Plr[i].Atk.front().first-1,20);
                        ss/=Plr[tar].sz; ss*=10;
                        int seg=min(20,int(sqrt((fx-ex)*(fx-ex)+(fy-ey)*(fy-ey))/30.0)); double cx=fx, cy=fy;
                        for (int i=0; i<seg; ++i) {
                            cx += (ex-fx)/double(seg+3);
                            cy += (ey-fy)/double(seg+3);
                            Plr[tar].PQu.push_back({cx,cy,0,0,0,0,double(i)/double(seg)*ss,0.2/Plr[tar].sz,0,8,-Mix(0xFFFFFF,0xDF3782,0.6)});
                        }
                        //AtkEff.push_back({Plr[i].KX+Plr[i].DX*Plr[i].sz*0.5,Plr[i].KY+Plr[i].LY*Plr[i].sz*0.5,rndf()*acos(-1.0)*2.0,rndf()*acos(-1.0)*2.0,tar,0xFFFF00,pow(nw,0.2)});
                        Plr[tar].LstAtk = i;
                        int cap = 12;
                        if (Plr[tar].ModExpert==2) cap=max(0,(4+(11-Plr[tar].QueryFloor())*2)/5);
                        Plr[tar].AggDec = min(cap,Plr[tar].AggDec+1);
                        ShiftCD[tar] = 100;
                    }
                    Plr[i].Atk.pop();
                    bool qd = false;
                    if (Plr[i].Atk.size()) {
                        Plr[i].Tar = -1;
                        int att = 10;
                        vector<int> List;
                        if (QuickPlay) List=AggList;
                        else {
                            if (Plr[i].AtkType==6) {
                                for (int j=0; j<Plrs; ++j) {
                                    if ((!Plr[j].Over)&&(TarRem[i][j])) List.push_back(j);
                                }
                            }
                            if (List.empty()) {
                                for (int j=0; j<Plrs; ++j) {
                                    if ((!Plr[j].Over)&&(i!=j)) List.push_back(j);
                                }
                            }
                        }
                        while (att--) {
                            if (List.empty()) break;
                            int nw = List[rnd(List.size())];
                            if (nw!=i) {
                                Plr[i].Tar=nw; qd=true; break;
                            }
                        }
                    }
                    if (QuickPlay) {
                        if ((Plr[i].Tar!=-1)&&(!qd)&&(!rnd(max(1,(Plr[Plr[i].Tar].QueryFloor()-8)/3)))) Plr[i].Tar=-1;
                        break;
                    }
                }
            }
            int OverCnt = 0;
            int Hm=0, HmOver=0;
            for (int i=0; i<Plrs; ++i) {
                if (Plr[i].Over) {
                    ++OverCnt;
                    if ((Plr[i].LstAtk>=0)&&(!KOCount[i])) {
                        if (QuickPlay) Plr[Plr[i].LstAtk].GiveScore((Plr[i].ModExpert<2)?15000:8000);
                        else Plr[Plr[i].LstAtk].SKO+=1+Plr[i].SKO;
                        ++Plr[Plr[i].LstAtk].KO; KOCount[i]=true;
                    }
                }
                if (!Plr[i].Bot) {
                    ++Hm; if (Plr[i].Over) ++HmOver;
                }
            }
            bool ok = false;
            for (int i=0; i<Plrs; ++i) {
                if (!Plr[i].Bot) ok=true;
            }
            if ((ForceAbort)&&(QuickPlay)&&(ok)) {
                ForceAbort = false;
                for (int i=0; i<Plrs; ++i) {
                    if (!Plr[i].Bot) {
                        Plr[i].Over=KOCount[i]=false; Plr[i].ClearAll(time(0)); Obs=i;
                    }
                }
            }
            if ((ForceRound)||(ForceAbort)||((!QuickPlay)&&(((Plrs==1)&&(OverCnt)&&(Zen))||((OverCnt+1>=Plrs)&&(Plrs>1))||((Plrs>1)&&(Hm)&&(Hm==HmOver)&&(!ObserveAI))))) {
                int seed=time(0); Obs=-1; if (!ForceAbort) ++RoundTot;
                memset(TarRem, 0, sizeof(TarRem));
                for (int i=0; i<Plrs; ++i) {
                    ShiftCD[i] = 0;
                    if ((!Plr[i].Over)&&(!ForceAbort)) {
                        ++Plr[i].Wins; Plr[i].Victory();
                    }
                    else Plr[i].ClearAll(0,true);
                }
                if ((Plrs>1)&&(!ForceAbort)) {
                    PaintTm = 0;
                    while (PaintTm<3000) {
                        ll NxtT = clock();
                        int del=int(NxtT-CurT); PaintTm+=del;
                        CurT = NxtT;
                        glClearColor(BackgroundRatio, BackgroundRatio, BackgroundRatio, 0);
                        glClear(GL_COLOR_BUFFER_BIT);
                        glPushMatrix();
                        for (int i=0; i<Plrs; ++i) {
                            if (((!Plr[i].Over)||((Plrs==1)&&(!Zen))||(QuickPlay))&&(i!=Obs)) Plr[i].Paint(del);
                            MX[i] = Plr[i].KX+Plr[i].DX*0.5*Plr[i].sz;
                            MY[i] = Plr[i].KY+Plr[i].LY*0.5*Plr[i].sz;
                        }
                        if ((Obs>=0)&&((!Plr[Obs].Over)||((Plrs==1)&&(!Zen))||(QuickPlay))) Plr[Obs].Paint(del);
                        for (int i=0; i<Plrs; ++i) {
                            int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==i)||(((Plr[i].AtkType==6)&&(TarRem[i][j]))))&&(!Plr[j].Over));
                            if (i!=Obs) Plr[i].PaintParticle(del,tars);
                        }
                        int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==Obs)||(((Plr[Obs].AtkType==6)&&(TarRem[Obs][j]))))&&(!Plr[j].Over));
                        if (Obs>=0) Plr[Obs].PaintParticle(del,tars);
                        Global.PaintGlobal(del);
                        glPopMatrix();
                        SwapBuffers(hDC);
                    }
                }
                for (int i=0; i<Plrs; ++i) {
                    Plr[i].ClearAll(seed,Plr[i].Over); Plr[i].Over=false; 
                    Plr[i].LstAtk=-1; KOCount[i]=false; Plr[i].Tar=-1;
                    if (QuickPlay) ++seed;
                }
                ForceRound=ForceAbort=false;
                //if (Zen) Storage=true;
            }
            if (PaintTm>=PaintLim) {
                glClearColor(BackgroundRatio, BackgroundRatio, BackgroundRatio, 0);
                glClear(GL_COLOR_BUFFER_BIT);
                glPushMatrix();
                for (int i=0; i<Plrs; ++i) {
                    if (((!Plr[i].Over)||((Plrs==1)&&(!Zen))||(QuickPlay))&&(i!=Obs)) Plr[i].Paint(PaintTm);
                }
                if ((Obs>=0)&&((!Plr[Obs].Over)||((Plrs==1)&&(!Zen))||(QuickPlay))) Plr[Obs].Paint(PaintTm);
                for (int i=0; i<Plrs; ++i) {
                    int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==i)||(((Plr[i].AtkType==6)&&(TarRem[i][j]))))&&(!Plr[j].Over));
                    if (i!=Obs) Plr[i].PaintParticle(PaintTm,tars);
                    MX[i] = Plr[i].KX+Plr[i].DX*0.5*Plr[i].sz;
                    MY[i] = Plr[i].KY+Plr[i].LY*0.5*Plr[i].sz;
                }
                int tars=0; for (int j=0; j<Plrs; ++j) tars+=(((Plr[j].Tar==Obs)||(((Plr[Obs].AtkType==6)&&(TarRem[Obs][j]))))&&(!Plr[j].Over));
                if (Obs>=0) Plr[Obs].PaintParticle(PaintTm,tars);
                Global.PaintGlobal(PaintTm);
                PaintTm = 0;
                glPopMatrix();
                SwapBuffers(hDC);
            }
            if (Zen) {
                if (Storage) {
                    Storage = false;
                    StoragePos = (StoragePos<105)?StoragePos+1:1;
                    Plr[StoragePos] = Plr[0];
                    StorageTot = min(100,StorageTot+1);
                }
                if ((Undo)&&(StorageTot>1)) {
                    StoragePos = (StoragePos>1)?StoragePos-1:105;
                    Plr[0] = Plr[StoragePos];
                    for (int i=0; i<256; ++i) {
                        Plr[0].KeyDas[i]=Plr[0].KeySta[i]=false; Plr[0].KeyTime[i]=0;
                    }
                    Plr[0].UndoCD = 100;
                    --StorageTot;
                }
                if (Undo) Undo=false;
            }
        }
    }
    DisableOpenGL(hWnd, hDC, hRC);
    DestroyWindow(hWnd);
    return msg.wParam;
}