专栏文章

qqwq

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqaxbmg
此快照首次捕获于
2025/12/04 01:49
3 个月前
此快照最后确认于
2025/12/04 01:49
3 个月前
查看原文
CPP
// -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;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...