// -std=c++14 -lOpengl32
#pragma GCC optimize(3)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <random>
#include <algorithm>
#include <windows.h>
#include <conio.h>
#include <gl/gl.h>
using std::min; using std::max;
using std::swap; using std::reverse;
using std::sort; using std::stable_sort;
using std::pair; using std::make_pair;
using std::string; using std::vector;
using std::stack; using std::queue;
using std::deque; using std::set;
using std::mt19937; using std::shuffle;
using std::sprintf; using std::memset;
typedef long long ll;
typedef unsigned long long llu;
typedef __int128 lll;
WNDCLASS wc; HWND hWnd; HDC hDC; HGLRC hRC;
MSG msg; bool bQuit=false;
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));
}
/*template<typename T>
T** NewGrid(int x, int y) {
T** p = new T*[x];
for (int i=0; i<x; ++i) p[i]=new int[y];
return p;
}
template<typename T>
void DeleteGrid(T **p, int x, int y=0) {
for (int i=0; i<x; ++i) delete[] p[i];
delete[] p;
}*/
char PlaceholderString[10000];
#define Format(fmt,...) (sprintf(PlaceholderString,fmt,__VA_ARGS__),string(PlaceholderString))
vector<string> Char[256];
const int SToIErr = -998244353;
string IToS(ll x) {
if (!x) return "0";
string res=""; bool f=false;
if (x<0LL) {
x=-x; f=true;
}
while (x) {
res=char(x%10LL+'0')+res; x/=10LL;
}
if (f) res='-'+res;
return res;
}
string IToSH(ll x) {
if (!x) return "000000";
string res=""; bool f=false;
if (x<0LL) {
x=-x; f=true;
}
while (x) {
int u = int(x%16LL);
if (u<10) res=char(u+'0')+res;
else res=char(u-10+'A')+res;
x /= 16LL;
}
while (res.size()<6) res='0'+res;
if (f) res='-'+res;
return res;
}
string ToLower(string s) {
for (char &ch : s) {
if ((ch>='A')&&(ch<='Z')) ch+='a'-'A';
}
return s;
}
string Str(char ch) {
return {ch};
}
int SToI(string s) {
s = ToLower(s);
if (s=="max") return 9999999;
if (s=="true") return 1;
if (s=="false") return 0;
int res=0; bool f=false;
for (int i=0; i<s.size(); ++i) {
char ch = s[i];
if (ch=='-') {
if (!i) f=true;
else return SToIErr;
}
else if ((ch>='0')&&(ch<='9')) res=min(9999999,res*10+ch-'0');
else return SToIErr;
}
return (f)?-res:res;
}
const vector<string> KeyList = {"q","w","e","r","t","y","u","i","o","p",
"a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m",
"0","1","2","3","4","5","6","7","8","9",
"up","down","left","right","space","enter",
"ctrl","shift","tab","caps","none"};
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=="caps") return VK_CAPITAL;
if (str=="ctrl") return VK_CONTROL;
if (str=="none") return VK_F24;
return 0;
}
string KeyChar(string str) {
if (str.empty()) return 0;
char ch = str[0];
if (str=="up") return string("")+char(10);
if (str=="down") return string("")+char(11);
if (str=="left") return string("")+char(12);
if (str=="right") return string("")+char(13);
if (str=="space") return string("")+char(14);
if (str=="shift") return string("")+char(15);
if (str=="tab") return string("")+char(16);
if (str=="enter") return string("")+char(17);
if (str=="caps") return string("")+char(18);
if (str=="ctrl") return string("")+char(19);
if (str=="esc") return string("")+char(3);
if (str=="none") return string("")+char(4);
if ((ch>='a')&&(ch<='z')) return string("")+char(ch+'A'-'a');
if ((ch>='A')&&(ch<='Z')) return string("")+char(ch);
if ((ch>='0')&&(ch<='9')) return string("")+char(ch);
return "";
}
string KeyChar(char ch) {
if (ch==VK_UP) return string("")+char(10);
if (ch==VK_DOWN) return string("")+char(11);
if (ch==VK_LEFT) return string("")+char(12);
if (ch==VK_RIGHT) return string("")+char(13);
if (ch==VK_SPACE) return string("")+char(14);
if (ch==VK_SHIFT) return string("")+char(15);
if (ch==VK_TAB) return string("")+char(16);
if (ch==VK_RETURN) return string("")+char(17);
if (ch==VK_CAPITAL) return string("")+char(18);
if (ch==VK_CONTROL) return string("")+char(19);
if (ch==VK_ESCAPE) return string("")+char(3);
if (ch==VK_F24) return string("")+char(4);
if ((ch>='a')&&(ch<='z')) return string("")+char(ch+'A'-'a');
if ((ch>='A')&&(ch<='Z')) return string("")+char(ch);
if ((ch>='0')&&(ch<='9')) return string("")+char(ch);
return "";
}
struct ConfigContent {
string first, second;
ConfigContent() {
first=second="";
}
ConfigContent(string Name, string Val) {
first=Name; second=Val;
}
ConfigContent(string Name, int Val) {
first=Name; second=IToS(Val);
}
ConfigContent(pair<string,string> o) {
first=o.first; second=o.second;
}
ConfigContent(pair<string,int> o) {
first=o.first; second=IToS(o.second);
}
};
int Scale = 500;
namespace PaintManager {
const int PS = 20;
void Plot(double x, double y, int clr) {
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);
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, px);
}
pair<double,double> RotatePos(double x, double y, double th, double rx, double ry) {
if (fabs(th)<0.001) return make_pair(x,y);
double d = sqrt((x-rx)*(x-rx)+(y-ry)*(y-ry));
if (d<=0.001) return make_pair(x,y);
th += atan2(y-ry,x-rx);
return make_pair(rx+d*cos(th),ry+d*sin(th));
}
void Rect(double x, double y, double dx, double dy, int clr, double th=0.0, double rx=0.0, double ry=0.0) {
glBegin(GL_POLYGON);
pair<double,double> o = RotatePos(x,y,th,rx,ry);
Plot(o.first, o.second, clr);
o = RotatePos(x+dx,y,th,rx,ry);
Plot(o.first, o.second, clr);
o = RotatePos(x+dx,y+dy,th,rx,ry);
Plot(o.first, o.second, clr);
o = RotatePos(x,y+dy,th,rx,ry);
Plot(o.first, o.second, clr);
glEnd();
}
void Square(double x, double y, double d, int clr) {
Rect(x, y, d, d, clr);
}
void Poly(double x, double y, double sz, int n, int clr, double th=0.0) {
glBegin(GL_POLYGON);
double dth = acos(-1.0)*2.0/double(n);
th += 0.5*dth;
for (int i=0; i<=n; ++i) {
Plot(x+sz*cos(th), y+sz*sin(th), clr);
th += dth;
}
glEnd();
}
void PrintChar(int ch, double x, double y, double sz, int clr, double bd=0.12, 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 PrintStrR(string str, double x, double y, double sz, int clr, double bd=0.12, double dis=1.0, string eff="", double th=0.0, double sc=0.0) {
dis *= sz;
reverse(str.begin(), str.end());
for (char ch : str) {
//if (sp) Rect(x+oo*sz*0.1-sz*0.2,y-sz*0.2,sz*1.5,sz,0xFF3333);
PrintChar(int(ch), x, y, sz, clr, bd, th, sc);
y -= dis;
}
}
void PrintStrL(string str, double x, double y, double sz, int clr, double bd=0.12, double dis=1.0, string eff="", double th=0.0, double sc=0.0) {
PrintStrR(str, x, y+dis*sz*double(str.size()-1), sz, clr, bd, dis, eff, th, sc);
}
void PrintStrM(string str, double x, double y, double sz, int clr, double bd=0.12, double dis=1.0, string eff="", double th=0.0, double sc=0.0) {
PrintStrR(str, x, y+dis*sz*double(str.size()-1)*0.5, sz, clr, bd, dis, eff, th, sc);
}
}
class Piece {
int **B[4], LX, Color, Dir;
string Name;
const Piece *From;
public :
Piece(int _LX=1, vector<vector<int> > _B=vector<vector<int> >(), int _Color=0xAAAAAA, string _Name="") {
LX = max(1,min(100,_LX));
Color = _Color;
Name = _Name;
Dir = 0;
From = nullptr;
for (int d=0; d<4; ++d) {
B[d] = new int*[LX];
for (int i=0; i<LX; ++i) B[d][i]=new int[LX];
}
for (int i=0; i<LX; ++i) {
int pi = LX-i-1;
for (int j=0; j<LX; ++j) {
if ((_B.size()<=pi)||((_B[pi].size()<=j)||(!_B[pi][j]))) B[0][i][j]=0;
else B[0][i][j]=_B[pi][j];
}
}
for (int d=1; d<4; ++d) {
for (int i=0; i<LX; ++i) {
for (int j=0; j<LX; ++j) B[d][i][j]=B[d-1][j][LX-i-1];
}
}
}
Piece(const Piece &_From) {
if (_From.From==nullptr) From=&_From;
else From=_From.From;
LX = From->LX;
Color = From->Color;
Dir = _From.Dir;
}
Piece operator=(const Piece &_From) {
if (&_From==this) return *this;
if ((From==nullptr)&&(_From.From==this)) {
Color=_From.Color; Dir=_From.Dir; return *this;
}
if (From==nullptr) {
for (int d=0; d<4; ++d) {
for (int i=0; i<LX; ++i) delete[] B[d][i];
delete[] B[d];
}
}
if (_From.From==nullptr) From=&_From;
else From=_From.From;
LX = From->LX;
Color = From->Color;
Dir = _From.Dir;
return *this;
}
~Piece() {
if (From!=nullptr) return;
for (int d=0; d<4; ++d) {
for (int i=0; i<LX; ++i) delete[] B[d][i];
delete[] B[d];
}
}
inline int GetLX() const {
return LX;
}
inline int GetRealGrid(int x, int y, int d=-1) const {
if ((d<0)||(d>3)) d=Dir;
if (((x<0)||(y<0))||((x>=LX)||(y>=LX))) return 0;
int val = 0;
if (From==nullptr) val=B[d][x][y];
else val=From->B[d][x][y];
return val;
}
inline int GetGrid(int x, int y, int d=-1) const {
if ((d<0)||(d>3)) d=Dir;
if (((x<0)||(y<0))||((x>=LX)||(y>=LX))) return 0;
int val = 0;
if (From==nullptr) val=B[d][x][y];
else val=From->B[d][x][y];
if (val==1) return Color;
if (val==-1) return -Color;
return val;
}
inline int GetShapeMid() const {
int mn=LX-1, mx=0;
for (int j=0; j<LX; ++j) {
for (int i=0; i<LX; ++i) {
if (GetGrid(i,j,Dir)) {
mn=min(mn,j); mx=max(mx,j);
break;
}
}
}
if ((mn<=(LX>>1))&&((LX>>1)<=mx)) return LX>>1;
return (mx+mn)>>1;
}
inline int GetColor() const {
if (From==nullptr) return Color;
return From->Color;
}
string GetRealName() const {
if (From==nullptr) return Name;
return From->Name;
}
string GetName() const {
if (From==nullptr) return Name;
string tmp = From->Name;
if ((tmp.size()<3)||(tmp[tmp.size()-2]!='@')) return tmp;
return tmp.substr(0,tmp.size()-2);
}
int GetDir() const {
return Dir;
}
void SetDir(int val) {
Dir = val%4;
if (Dir<0) Dir+=4;
}
pair<int,int> GetAnchor(int d=-1) {
if ((d<0)||(d>3)) d=Dir;
for (int i=0; i<LX; ++i) {
for (int j=0; j<LX; ++j) {
if (GetGrid(i,j,d)) return make_pair(i,j);
}
}
return make_pair(0,0);
}
llu GetHash() const {
if (From!=nullptr) return llu(From);
return llu(this);
}
};
bool Focus = false;
bool UniformKeySta[256];
void UpdateKeySta() {
for (int i=0; i<256; ++i) {
if (Focus) UniformKeySta[i]=bool(GetAsyncKeyState(i)&0x8000);
else UniformKeySta[i]=false;
}
}
bool CheckKey(int ch) {
if ((ch<0)||(ch>255)) return false;
return UniformKeySta[ch];
}
bool LeftClick, RightClick, MidClick;
int LeftUp, RightUp;
int LeftHold, RightHold;
double randf() {
return double(rand()&32767)/32767.0;
}
#warning const
const int Garb=-0x888888, Solid=-0x555555, GarbZone=-0xFDD000, GarbRound=-0xCCCCCC, GarbLock=-0xFF6666, GarbBomb=-0xFFFF99, GarbQuest=-0x9E00FF;
const vector<int> C2ComboBase = {2440,1120,400,60,-160,-330,-470,-600,-710,-830,-940,-1050,-1160,-1260};
const vector<int> C2ComboBonus = {1220,610,300,180,120,90,70,50,40,30,30,20};
const vector<int> QPLevelScore =
{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};
const vector<int> LevelColor = {
0x666666,0xC23A30,0x006098,0xEE0000,0x008E9C,
0xA6217F,0xD29700,0xF6C582,0x009B6B,0x8FC13F,
0x009BC0,0xED796B,0x995D35,0xFFE211,0xD5A7A1,
0x5B2C68,0x76A32E,0x39C5BB,0x9999FF,0xEE82EE,
0x203864,0x73E9DB,0xFFCCCC,0x86001A,0xE40077,
0xE46022,0xB35A20,0xD97DAD,0x395C00,0xFF5353,
0xC6E002,0x999900,0x006666,0xFDD000,0xA29BBB,
0x0080FF,0x66CCFF,0xCB35BD,0x00DEB4,0xB9A567,
0xFFFFFF};
const vector<int> QPRiseTime = {8*60,8*60+2,10*60,10*60+2,10*60+4,12*60,12*60+2,12*60+4,12*60+8,12*60+10};
const vector<int> QPRevMod9RiseTime = {8*60,8*60+2,8*60+4,10*60,10*60+2,10*60+4,10*60+6,10*60+8,
12*60,12*60+2,12*60+4,12*60+6,12*60+8,12*60+10,12*60+12,12*60+14,12*60+16,12*60+18,12*60+20,12*60+22};
const vector<int> QPProtectDec = {4800,4800,3900,2100,1400,1300,900,600,400,300,200};
//const vector<int> QPProtectDec = {4800,4800,3900,2100,1400,1300,900,600};
const int BackgroundColor = 0x222222;
const int BoardColor = 0x333333;
const int ShadowColor = 0x666666;
const int GridColor=0x555555, OverGridColor=0x444444, RoundColor=0x777777, VanishColor=0x000033;
vector<pair<int,int> > RS, RS_I, RS_O, RS_C;
vector<Piece*> CustomPiece;
const Piece P_Empty;
const Piece P_Default(1, {{1}}, 0xBBBBBB, "*");
const Piece P_A(1, {{1}}, 0x228888, "A");
const Piece P_B(2, {{1,1}}, 0x89E5E5, "B");
const Piece P_C(2, {{1},{1,1}}, 0xFFAFBE, "C");
const Piece P_D(3, {{},{1,1,1}}, 0x00E5B7, "D");
const Piece P_I(4, {{},{1,1,1,1}}, 0x66CCFF, "I");
const Piece P_J(3, {{1},{1,1,1}}, 0x0080FF, "J");
const Piece P_L(3, {{0,0,1},{1,1,1}}, 0xFFA500, "L");
const Piece P_O(2, {{1,1},{1,1}}, 0xFFE211, "O");
const Piece P_S(3, {{0,1,1},{1,1}}, 0x2DD600, "S");
const Piece P_T(3, {{0,1,0},{1,1,1}}, 0xEE82EE, "T");
const Piece P_Z(3, {{1,1},{0,1,1}}, 0xEE3333, "Z");
const Piece P_I5(5, {{},{},{1,1,1,1,1}}, 0x66CCAA, "I5");
const Piece P_T5(3, {{0,1},{0,1},{1,1,1}}, 0xDF3782, "T5");
const Piece P_U(3, {{1,0,1},{1,1,1}}, 0xB17D43, "U");
const Piece P_V(3, {{1},{1},{1,1,1}}, 0x9E00FF, "V");
const Piece P_X(3, {{0,1},{1,1,1},{0,1}}, 0x9999FF, "X");
const Piece P_F(3, {{1},{1,1,1},{0,1}}, 0x00AAAA, "F");
const Piece P_E(3, {{0,0,1},{1,1,1},{0,1}}, 0xD29700, "E");
const Piece P_S5(3, {{1},{1,1,1},{0,0,1}}, 0x00AA00, "S5");
const Piece P_Z5(3, {{0,0,1},{1,1,1},{1}}, 0xAA0000, "Z5");
const Piece P_J5(4, {{},{1},{1,1,1,1}}, 0x6666FF, "J5");
const Piece P_L5(4, {{},{0,0,0,1},{1,1,1,1}}, 0xFF5000, "L5");
const Piece P_Y(4, {{},{0,0,1},{1,1,1,1}}, 0x00AAFF, "Y");
const Piece P_R(4, {{},{0,1},{1,1,1,1}}, 0xCC99FF, "R");
const Piece P_H(4, {{},{0,0,1,1},{1,1,1}}, 0x99E55B, "H");
const Piece P_N(4, {{},{1,1},{0,1,1,1}}, 0xFF6666, "N");
const Piece P_Q(3, {{0,1,1},{1,1,1}}, 0xCCCC00, "Q");
const Piece P_P(3, {{1,1},{1,1,1}}, 0xFDD000, "P");
const Piece P_W(3, {{1},{1,1},{0,1,1}}, 0x72752A, "W");
const Piece P_30(6, {{},{},{1,1,1,1,1,1}}, 0x96D6CB, "I6");
const Piece P_31(4, {{},{0,1,1},{1,1,1,1}}, 0x62FFE0, "B6");
const Piece P_32(3, {{0,1},{1,1,1},{1,1}}, 0xEB22B9, "A6");
const Piece P_33(3, {{1,1,1},{1,1,1}}, 0xCCCC99, "O6");
const Piece P_34(3, {{1},{1,1},{1,1,1}}, 0xC4A179, "E6");
const Piece P_35(4, {{0,0,0,1},{1,1,1,1},{0,0,0,1}}, 0x9A1751, "T6");
const Piece P_36(4, {{0,0,1},{1,1,1,1},{0,0,1}}, 0xD1D1FF, "X6");
const Piece P_37(3, {{0,1},{1,1,1},{1,0,1}}, 0x6F9B, "V6");
const Piece P_38(4, {{1,0,0,1},{1,1,1,1}}, 0xF3BDBD, "U6");
const Piece P_39(5, {{},{0,0,1},{1,1,1,1,1}}, 0x686998, "t6");
const Piece P_40(5, {{},{0,0,0,0,1},{1,1,1,1,1}}, 0xFFD17C, "L6");
const Piece P_41(5, {{},{1},{1,1,1,1,1}}, 0x48A4FF, "J6");
const Piece P_42(5, {{},{0,1},{1,1,1,1,1}}, 0xB59ECD, "Y6");
const Piece P_43(5, {{},{0,0,0,1},{1,1,1,1,1}}, 0x7ED0F8, "y6");
const Piece P_44(5, {{},{1,1},{0,1,1,1,1}}, 0xFF8F66, "N6");
const Piece P_45(5, {{},{0,0,0,1,1},{1,1,1,1}}, 0x7ECD3F, "n6");
const Piece P_46(4, {{1,1},{1,1,1,1}}, 0xCBB344, "P6");
const Piece P_47(4, {{0,0,1,1},{1,1,1,1}}, 0xDCE654, "Q6");
const Piece P_48(4, {{1,0,1},{1,1,1,1}}, 0x3A96B5, "F6");
const Piece P_49(4, {{0,1,0,1},{1,1,1,1}}, 0xE2B977, "f6");
const Piece P_50(4, {{0,0,0,1},{0,0,0,1},{1,1,1,1}}, 0xFFBF00, "V6");
const Piece P_51(4, {{1},{1},{1,1,1,1}}, 0x93B0CC, "v6");
const Piece P_52(4, {{0,1},{0,1},{1,1,1,1}}, 0xA879A7, "R6");
const Piece P_53(4, {{0,0,1},{0,0,1},{1,1,1,1}}, 0xC6F82F, "r6");
const Piece P_54(4, {{1},{1,1,1,1},{0,1}}, 0x1D9C58, "tf");
const Piece P_55(4, {{0,0,0,1},{1,1,1,1},{0,0,1}}, 0xED396F, "TF");
const Piece P_56(4, {{0,1},{1,1,1,1},{0,0,0,1}}, 0x8F9878, "lf");
const Piece P_57(4, {{0,0,1},{1,1,1,1},{1}}, 0x92837C, "LF");
const Piece P_58(4, {{1},{1,1,1,1},{0,0,0,1}}, 0x72FF72, "S6");
const Piece P_59(4, {{0,0,0,1},{1,1,1,1},{1}}, 0xFF9999, "Z6");
const Piece P_60(4, {{0,1},{1,1,1,1},{0,0,1}}, 0xE1CD68, "Xl");
const Piece P_61(4, {{0,0,1},{1,1,1,1},{0,1}}, 0x658666, "Xr");
const Piece P_62(4, {{0,0,1},{0,0,1,1},{1,1,1}}, 0x6B3131, "tv");
const Piece P_63(4, {{0,1},{1,1},{0,1,1,1}}, 0x6B5531, "TV");
const Piece P_64(4, {{},{0,1,1,1},{1,1,0,1}}, 0xD44AD6, "G6");
const Piece P_65(4, {{},{1,1,1},{1,0,1,1}}, 0xB56AFF, "g6");
const Piece P_66(5, {{},{1,1,1},{0,0,1,1,1}}, 0xA8C080, "z6");
const Piece P_67(5, {{},{0,0,1,1,1},{1,1,1}}, 0xA8C09F, "s6");
const Piece P_68(4, {{},{1,1,1},{0,1,1,1}}, 0x3B5224, "LZ");
const Piece P_69(4, {{},{0,1,1,1},{1,1,1}}, 0x334514, "LS");
const Piece P_70(4, {{0,0,1,1},{1,1,1},{0,0,1}}, 0x5F3C91, "GF");
const Piece P_71(4, {{1,1},{0,1,1,1},{0,1}}, 0x913C72, "GE");
const Piece P_72(3, {{1,1},{1,1,1},{1}}, 0x8CE7CC, "K6");
const Piece P_73(3, {{0,1,1},{1,1,1},{0,0,1}}, 0x96DCFF, "k6");
const Piece P_74(4, {{0,1},{1,1,1},{0,0,1,1}}, 0x5E91D8, "ZJ");
const Piece P_75(4, {{0,0,1},{0,1,1,1},{1,1}}, 0xCC5DE8, "SL");
const Piece P_76(4, {{1,1},{0,1},{0,1,1,1}}, 0x65CF70, "Zv");
const Piece P_77(4, {{0,0,1,1},{0,0,1},{1,1,1}}, 0x65B3CF, "Sv");
const Piece P_78(4, {{1},{1,1},{0,1,1,1}}, 0x6D6D14, "W6");
const Piece P_79(4, {{0,0,0,1},{0,0,1,1},{1,1,1}}, 0x84334B, "M6");
const Piece P_80(3, {{0,0,1},{1,0,1},{1,1,1}}, 0xA2FF00, "j6");
const Piece P_81(3, {{1},{1,0,1},{1,1,1}}, 0x1CFF18, "l6");
const Piece P_82(3, {{1},{1,1,1},{1,0,1}}, 0x18E0FF, "H6");
const Piece P_83(3, {{0,0,1},{1,1,1},{1,0,1}}, 0x5D54FF, "h6");
const Piece P_84(4, {{1},{1,1,1},{0,0,1,1}}, 0xBA4C4C, "w6");
const Piece P_85(4, {{0,0,0,1},{0,1,1,1},{1,1}}, 0xBAA147, "m6");
const Piece P_86(3, {{0,1,1},{1,1},{1,1}}, 0x7B60D3, "p6");
const Piece P_87(3, {{1,1},{0,1,1},{0,1,1}}, 0x60D395, "q6");
const Piece P_88(4, {{1,1},{0,1,1},{0,0,1,1}}, 0x834BEB, "MW");
const Piece P_89(4, {{0,0,1,1},{0,1,1},{1,1}}, 0xBC79B9, "WM");
const Piece P_MZ1(1, {{1}}, 0xEE0000, "Z-1");
const Piece P_ML1(3, {{},{1,1,1}}, 0xFFA500, "L-1");
const Piece P_MO1(2, {{1},{0,1}}, 0xFFE211, "O-1");
const Piece P_MS1(2, {{1,1},{1,0}}, 0x2DD600, "S-1");
const Piece P_MI1(5, {{},{},{1,1,1,1,1}}, 0x66CCFF, "I-1");
const Piece P_MJ1(3, {{1},{0,1,1}}, 0x0080FF, "J-1");
const Piece P_RMJ1(3, {{0,0,1},{1,1}}, 0xFFA500, "RJ-1");
const Piece P_MT1(3, {{0,1},{1,0,1}}, 0xEE82EE, "T-1");
const Piece P_MZ2(4, {{},{1,1},{0,0,1,1}}, 0xEE0000, "Z-2");
const Piece P_ML2(4, {{},{0,0,0,1},{1,1,1,1}}, 0xFFA500, "L-2");
const Piece P_MO2(3, {{1,0,1},{1,0,1}}, 0xFFE211, "O-2");
const Piece P_MS2(4, {{},{0,0,1,1},{1,1}}, 0x2DD600, "S-2");
const Piece P_MI2(5, {{},{},{1,1,1,0,1}}, 0x66CCFF, "I-2");
const Piece P_MJ2(4, {{},{1},{1,1,1,1}}, 0x0080FF, "J-2");
const Piece P_MT2(4, {{0,0,1,0},{1,1,1,1}}, 0xEE82EE, "T-2");
const Piece P_MZ3(5, {{},{1,1,1,1},{0,1,1,1,1}}, 0xEE0000, "Z-3");
const Piece P_ML3(4, {{},{0,0,0,1},{1,0,1,1}}, 0xFFA500, "L-3");
const Piece P_RML3(4, {{},{1},{1,1,0,1}}, 0x0080FF, "RL-3");
const Piece P_MO3(3, {{1,1,1},{1,1,1},{1,1,1}}, 0xFFE211, "O-3");
const Piece P_MS3(5, {{},{0,1,1,1,1},{1,1,1,1}}, 0x2DD600, "S-3");
const Piece P_MI3(4, {{},{1,1,1,1},{1,1,1,1}}, 0x66CCFF, "I-3");
const Piece P_MJ3(3, {{1},{1,1,1},{0,1}}, 0x0080FF, "J-3");
const Piece P_MT3(3, {{0,1},{0,1},{1,1,1}}, 0xEE82EE, "T-3");
const Piece P_MZ4(4, {{},{1,1,1,0},{0,0,1,1}}, 0xEE0000, "Z-4");
const Piece P_ML4(3, {{0,0,1},{0,0,1},{1,1,1}}, 0xFFA500, "L-4");
const Piece P_MO4(3, {{1,1},{1,1,1}}, 0xFFE211, "O-4");
const Piece P_MS4(4, {{},{0,1,1,1},{1,1}}, 0x2DD600, "S-4");
const Piece P_MI4(4, {{},{0,1},{1,0,1,1}}, 0x66CCFF, "I-4");
const Piece P_MJ4(3, {{1},{1},{0,1,1}}, 0x0080FF, "J-4");
const Piece P_MT4(3, {{0,1},{1,1,1},{1,0,1}}, 0xEE82EE, "T-4");
const Piece P_MZ5(3, {{1,1},{0,1},{0,1,1}}, 0xEE0000, "Z-5");
const Piece P_ML5(3, {{1,0,1},{1,1,1}}, 0xFFA500, "L-5");
const Piece P_MO5(3, {{0,1},{1,1,1},{1,1,1}}, 0xFFE211, "O-5");
const Piece P_MS5(3, {{0,1,1},{0,1},{1,1}}, 0x2DD600, "S-5");
const Piece P_MI5(5, {{},{0,0,0,0,1},{1,1,1,1}}, 0x66CCFF, "I-5");
const Piece P_MJ5(3, {{0,1},{1},{0,1,1}}, 0x0080FF, "J-5");
const Piece P_RMJ5(3, {{0,1},{0,0,1},{1,1}}, 0xFFA500, "RJ-5");
const Piece P_MT5(5, {{},{0,0,1},{1,1,1,1,1}}, 0xEE82EE, "T-5");
const Piece P_MZ6(4, {{},{1,0,1},{0,0,1,1}}, 0xEE0000, "Z-6");
const Piece P_RMZ6(4, {{},{0,1,0,1},{1,1}}, 0x2DD600, "RZ-6");
const Piece P_ML6(4, {{},{1,0,1},{1,1,1,1}}, 0xFFA500, "L-6");
const Piece P_MO6(3, {{0,1},{1,0,1},{0,1}}, 0xFFE211, "O-6");
const Piece P_MS6(3, {{0,1,1},{1,1},{1}}, 0x2DD600, "S-6");
const Piece P_MI6(4, {{1,1,1,1},{},{1,1,1,1}}, 0x66CCFF, "I-6");
const Piece P_MJ6(4, {{},{0,1,0,1},{1,1,1,1}}, 0x0080FF, "J-6");
const Piece P_MT6(4, {{0,0,1},{1,1,1,1},{1,1}}, 0xEE82EE, "T-6");
const Piece P_MZ7(4, {{1,1,1},{0,1,1},{0,1,1,1}}, 0xEE0000, "Z-7");
const Piece P_ML7(4, {{0,0,0,1},{1,1,1,1},{0,0,1}}, 0xFFA500, "L-7");
const Piece P_MO7(4, {{0,0,1},{1,1,1},{0,1,1,1},{0,1}}, 0xFFE211, "O-7");
const Piece P_RMO7(4, {{0,1,0},{0,1,1,1},{1,1,1},{0,0,1}}, 0xFFE211, "RO-7");
const Piece P_MS7(4, {{0,1,1,1},{0,1,1},{1,1,1}}, 0x2DD600, "S-7");
const Piece P_MI7(4, {{},{0,1,0,1},{1,0,1}}, 0x66CCFF, "I-7");
const Piece P_MJ7(4, {{},{1,0,0,1},{1,1,1,1}}, 0x0080FF, "J-7");
const Piece P_MT7(5, {{},{0,0,1},{0,1,1,1},{1,1,0,1,1}}, 0xEE82EE, "T-7");
const Piece P_MZ8(4, {{0,1,1},{0,0,1},{0,1},{0,1,1}}, 0xEE0000, "Z-8");
const Piece P_ML8(5, {{},{0,0,1,0,1},{1,1,0,1,1}}, 0xFFA500, "L-8");
const Piece P_MO8(4, {{0,1,1},{1,0,1},{1,0,1},{1,1}}, 0xFFE211, "O-8");
const Piece P_MS8(4, {{0,1,1},{0,1},{0,0,1},{0,1,1}}, 0x2DD600, "S-8");
const Piece P_MI8(4, {{1,0,0,1},{1,1,1,1},{1,0,0,1}}, 0x66CCFF, "I-8");
const Piece P_MJ8(5, {{},{1,0,1},{1,1,0,1,1}}, 0x0080FF, "J-8");
const Piece P_MT8(5, {{0,0,1},{0,1,1,1},{0,0,1},{0,1,1,1},{0,0,1}}, 0xEE82EE, "T-8");
const Piece P_MZ9(7, {{},{},{1,0,1,1},{0,0,0,1,1,0,1}}, 0xEE0000, "Z-9");
const Piece P_ML9(7, {{},{},{0,0,0,0,1,0,1},{1,0,1,1,1}}, 0xFFA500, "L-9");
const Piece P_MO9(6, {{0,0,1},{},{0,0,1,1},{0,0,1,1},{},{0,0,0,1}}, 0xFFE211, "O-9");
const Piece P_MS9(7, {{},{},{0,0,0,1,1,0,1},{1,0,1,1}}, 0x2DD600, "S-9");
const Piece P_MI9(7, {{1},{},{0,0,1},{},{0,0,0,0,1},{},{0,0,0,0,0,0,1}}, 0x66CCFF, "I-9");
const Piece P_MJ9(7, {{},{},{1,0,1},{0,0,1,1,1,0,1}}, 0x0080FF, "J-9");
const Piece P_MT9(6, {{0,0,1},{},{0,0,1},{0,1,1,1},{0},{0,0,1}}, 0xEE82EE, "T-9");
const Piece P_MZ10(6, {{0,0,1,1},{0,1,0,1,1},{0,0,0,1},{0,0,1},{0,1,1,0,1},{0,0,1,1}}, 0xEE0000, "Z-10");
const Piece P_ML10(6, {{},{0,0,0,0,1},{1,0,0,0,0,1},{1,1,1,1,1,1}}, 0xFFA500, "L-10");
const Piece P_MO10(6, {{0,0,1,1},{0,1,1,1,1},{1,1,0,0,1,1},{1,1,0,0,1,1},{0,1,1,1,1},{0,0,1,1}}, 0xFFE211, "O-10");
const Piece P_MS10(6, {{0,0,1,1},{0,1,1,0,1},{0,0,1},{0,0,0,1},{0,1,0,1,1},{0,0,1,1}}, 0x2DD600, "S-10");
const Piece P_MI10(7, {{},{},{0,1,1,1,1,0,1},{1,0,1,1,1,1}}, 0x66CCFF, "I-10");
const Piece P_MJ10(6, {{},{0,1},{1,0,0,0,0,1},{1,1,1,1,1,1}}, 0x0080FF, "J-10");
const Piece P_MT10(5, {{1,1,1,1,1},{1,0,1,0,1},{0,0,1},{0,0,1},{0,1,1,1}}, 0xEE82EE, "T-10");
const Piece P_Bag3(1, {{1}}, 0xBBBBBB, "Bag3");
const Piece P_Bag4(1, {{1}}, 0xBBBBBB, "Bag4");
const Piece P_Bag5(1, {{1}}, 0xBBBBBB, "Bag5");
const Piece P_Bag6(1, {{1}}, 0xBBBBBB, "Bag6");
const vector<Piece> QPModM_I = {P_MI1,P_MI2,P_MI3,P_MI4,P_MI5,P_MI6,P_MI7,P_MI8,P_MI9,P_MI10};
const vector<Piece> QPModM_J = {P_MJ1,P_MJ2,P_MJ3,P_MJ4,P_MJ5,P_MJ6,P_MJ7,P_MJ8,P_MJ9,P_MJ10};
const vector<Piece> QPModM_L = {P_ML1,P_ML2,P_ML3,P_ML4,P_ML5,P_ML6,P_ML7,P_ML8,P_ML9,P_ML10};
const vector<Piece> QPModM_O = {P_MO1,P_MO2,P_MO3,P_MO4,P_MO5,P_MO6,P_MO7,P_MO8,P_MO9,P_MO10};
const vector<Piece> QPModM_S = {P_MS1,P_MS2,P_MS3,P_MS4,P_MS5,P_MS6,P_MS7,P_MS8,P_MS9,P_MS10};
const vector<Piece> QPModM_T = {P_MT1,P_MT2,P_MT3,P_MT4,P_MT5,P_MT6,P_MT7,P_MT8,P_MT9,P_MT10};
const vector<Piece> QPModM_Z = {P_MZ1,P_MZ2,P_MZ3,P_MZ4,P_MZ5,P_MZ6,P_MZ7,P_MZ8,P_MZ9,P_MZ10};
const Piece P_B02(3, {{0},{1,0,1}}, 0x89E5E5, "B02");
const Piece P_B03(4, {{0},{1,0,0,1}}, 0x89E5E5, "B03");
const Piece P_B04(5, {{0},{0},{1,0,0,0,1}}, 0x89E5E5, "B04");
const Piece P_B05(6, {{0},{0},{1,0,0,0,0,1}}, 0x89E5E5, "B05");
const Piece P_B11(2, {{1},{0,1}}, 0x89E5E5, "B11");
const Piece P_B12(3, {{1},{0,0,1}}, 0x89E5E5, "B12");
const Piece P_B13(4, {{0},{1},{0,0,0,1}}, 0x89E5E5, "B13");
const Piece P_B14(5, {{0},{1},{0,0,0,0,1}}, 0x89E5E5, "B14");
const Piece P_B15(6, {{0},{0},{1},{0,0,0,0,0,1}}, 0x89E5E5, "B15");
const Piece P_B22(3, {{1},{0},{0,0,1}}, 0x89E5E5, "B22");
const Piece P_B23(4, {{1},{0},{0,0,0,1}}, 0x89E5E5, "B23");
const Piece P_B24(5, {{0},{1},{0},{0,0,0,0,1}}, 0x89E5E5, "B24");
const Piece P_B25(6, {{0},{1},{0},{0,0,0,0,0,1}}, 0x89E5E5, "B25");
const Piece P_B33(4, {{1},{0},{0},{0,0,0,1}}, 0x89E5E5, "B33");
const Piece P_B34(5, {{1},{0},{0},{0,0,0,0,1}}, 0x89E5E5, "B34");
const Piece P_B35(6, {{0},{1},{0},{0},{0,0,0,0,0,1}}, 0x89E5E5, "B35");
const Piece P_B44(5, {{1},{0},{0},{0},{0,0,0,0,1}}, 0x89E5E5, "B44");
const Piece P_B45(6, {{1},{0},{0},{0},{0,0,0,0,0,1}}, 0x89E5E5, "B45");
const Piece P_B55(6, {{1},{0},{0},{0},{0},{0,0,0,0,0,1}}, 0x89E5E5, "B55");
const vector<Piece> HomePool = {P_I,P_J,P_L,P_O,P_S,P_T,P_Z};
/*{P_A,P_B,P_C,P_D,P_I,P_J,P_L,P_O,P_S,P_T,P_Z,
P_I5,P_T5,P_U,P_V,P_X,P_F,P_E,P_S5,P_Z5,P_J5,
P_L5,P_Y,P_R,P_H,P_N,P_Q,P_P,P_W};*/
const vector<Piece> PieceList = {P_Empty,P_Empty,P_A,P_Empty,P_B,P_Empty,P_Bag3,P_C,P_D,P_Empty,
P_Bag4,P_I,P_J,P_L,P_O,P_S,P_T,P_Z,P_Empty,P_Empty,
P_Bag5,P_I5,P_T5,P_U,P_V,P_X,P_F,P_E,P_S5,P_Z5,P_J5,
P_L5,P_Y,P_R,P_H,P_N,P_Q,P_P,P_W,P_Bag6,
P_30,P_31,P_32,P_33,P_34,P_35,P_36,P_37,P_38,P_39,
P_40,P_41,P_42,P_43,P_44,P_45,P_46,P_47,P_48,P_49,
P_50,P_51,P_52,P_53,P_54,P_55,P_56,P_57,P_58,P_59,
P_60,P_61,P_62,P_63,P_64,P_65,P_66,P_67,P_68,P_69,
P_70,P_71,P_72,P_73,P_74,P_75,P_76,P_77,P_78,P_79,
P_80,P_81,P_82,P_83,P_84,P_85,P_86,P_87,P_88,P_89};
const Piece P_Garbage(1, {{1}}, Garb, "G");
const vector<Piece> TetraminoPool = {P_I,P_J,P_L,P_O,P_S,P_T,P_Z};
const vector<Piece> PentominoPool = {P_I5,P_T5,P_U,P_V,P_X,P_F,P_E,P_S5,P_Z5,P_J5,P_L5,P_Y,P_R,P_H,P_N,P_Q,P_P,P_W};
const vector<Piece> HexaminoPool = {P_30,P_31,P_32,P_33,P_34,P_35,P_36,P_37,P_38,P_39,P_40,P_41,P_42,P_43,P_44,P_45,P_46,P_47,P_48,P_49,P_50,P_51,P_52,P_53,P_54,P_55,P_56,P_57,P_58,P_59,P_60,P_61,P_62,P_63,P_64,P_65,P_66,P_67,P_68,P_69,P_70,P_71,P_72,P_73,P_74,P_75,P_76,P_77,P_78,P_79,P_80,P_81,P_82,P_83,P_84,P_85,P_86,P_87,P_88,P_89};
const vector<Piece> DefaultPool = TetraminoPool;
vector<Piece> CustomPiecePrototypes;
//const vector<Piece> DefaultPool = {P_A,P_B,P_C,P_D};
//const vector<Piece> DefaultPool = {P_A,P_B,P_C,P_D,P_I,P_J,P_L,P_O,P_S,P_T,P_Z,P_I5,P_T5,P_U,P_V,P_X,P_F,P_E,P_S5,P_Z5,P_J5,P_L5,P_Y,P_R,P_H,P_N,P_Q,P_P,P_W};
enum EGenerationType {
G_Random, G_Bag, G_Fixed
};
enum EBlockStyle {
S_Default, S_Active, S_Garbage, S_Simple
};
enum EBaseRule {
BSR_Default, BSR_Equal, BSR_Classic, BSR_ASC, BSR_Arcade, BSR_None
};
enum EComboRule {
CR_Default, CR_Guildline, CR_Techmino, CR_Friends, CR_Expert, CR_Battle,
CR_99, CR_PPT, CR_Effect, CR_Zone, CR_C2, CR_Classic, CR_Arcade, CR_None
};
enum EClutchRule {
CLR_Default, CLR_None, CLR_Always
};
enum ESpinRule {
SR_Default, SR_AllMini, SR_Guildline, SR_AllSpin, SR_AllSemi, SR_IO, SR_Easy, SR_None
};
enum EB2BRule {
BR_Guildline, BR_Chain, BR_Surge, BR_QP, BR_Techmino, BR_None
};
enum EAllClearRule {
AR_Default, AR_IO, AR_Guildline, AR_QP, AR_Techmino, AR_Arcade, AR_None
};
enum EIntRule {
IR_Floor, IR_Accumulate, IR_Random, IR_Ceil
};
enum ERotateSystem {
R_Default, R_SRSPlus, R_StrictSRSPlus, R_ASCDX, R_ASC,
R_LNRS, R_RNRS, R_ARS, R_C2, R_Sega, R_New,
R_DX, R_Atari, R_TetraX, R_Zhoumetry, R_None
};
enum ELevScaleMode {
LS_Default, LS_Div, LS_Dec, LS_Exp
};
enum EGarbageShape {
GS_Default, GS_Full, GS_Empty, GS_Bubble, GS_Random, GS_Board, GS_Stair, GS_Copy
};
enum EGarbageType {
GT_Default, GT_Solid, GT_Lock, GT_Bomb, GT_Bricks
};
enum EGarbageActive {
GA_Default, GA_Attack, GA_None, GA_Instant
};
enum EGravityType {
GV_Default, GV_Cascade, GV_None, GV_Sticky, GV_Color, GV_Separate, GV_Avalanche, GV_Fall
};
enum ETargetType {
TT_None, TT_All, TT_Even, TT_Elimination, TT_Random, TT_Payback, TT_Badges, TT_Attackers, TT_Backfire
};
#warning enum
class PieceGenerator {
vector<int> His;
mt19937 rng;
EGenerationType Type;
int H, R, E;
public :
vector<Piece> Pool;
vector<Piece> RemPool;
PieceGenerator(vector<Piece> _Pool=DefaultPool, EGenerationType _Type=G_Bag, int Seed=0, int _H=0, int _R=0, int _E=0) {
rng = mt19937(Seed);
Pool = _Pool;
Type = _Type;
H=_H; R=_R; E=_E;
}
Piece Roll() {
int n = Pool.size();
if (!n) return P_Default;
if (Type==G_Random) {
RemPool.clear();
int r = rng()%n;
for (int i=0; i<R; ++i) {
bool f = false;
for (int j : His) {
if (r==j) f=true;
}
if (f) r=rng()%n;
else break;
}
His.push_back(r);
while (His.size()>H) {
for (int i=1; i<His.size(); ++i) His[i-1]=His[i];
His.pop_back();
}
return Pool[r];
}
if (Type==G_Bag) {
if (RemPool.empty()) {
int cnt=E/n+1, rem=E%n;
if (rem) {
RemPool=Pool; shuffle(RemPool.begin(),RemPool.end(),rng);
RemPool.resize(rem);
}
for (int i=1; i<=cnt; ++i) {
for (Piece x : Pool) RemPool.push_back(x);
}
}
int m=RemPool.size(), pos=rng()%m;
Piece res=RemPool[pos]; swap(RemPool[pos],RemPool[m-1]);
RemPool.pop_back();
return res;
}
if (Type==G_Fixed) {
if (RemPool.empty()) {
RemPool=Pool; reverse(RemPool.begin(),RemPool.end());
}
Piece res = RemPool.back();
RemPool.pop_back(); return res;
}
return P_Default;
}
};
enum Action {
A_Left, A_Right, A_SoftDrop, A_HardDrop, A_SonicDrop,
A_Rotate, A_CW, A_CCW, A_Half, A_Hold, A_Retry,
A_Pause, A_Click, A_RightClick, A_MidClick, A_Quit,
A_Up, A_Flip, A_Waste, A_Reset, A_Lock,
A_CursorMode, A_TargetMode, A_Undo, A_Redo, A_Action
};
const vector<pair<string,Action> > KeyToAct = {{"KeyLeft",A_Left},
{"KeyRight",A_Right},
{"KeySoft",A_SoftDrop},
{"KeyHard",A_HardDrop},
{"KeySonic",A_SonicDrop},
{"KeyRotate",A_Rotate},
{"KeyCW",A_CW},
{"KeyCCW",A_CCW},
{"KeyHalf",A_Half},
{"KeyHold",A_Hold},
{"KeyRetry",A_Retry},
{"KeyPause",A_Pause},
{"KeyUp",A_Up},
{"KeyReset",A_Reset},
{"KeyFlip",A_Flip},
{"KeyWaste",A_Waste},
{"KeyCursorMode",A_CursorMode},
{"KeyTargetMode",A_TargetMode},
{"KeyUndo",A_Undo},
{"KeyRedo",A_Redo},
{"KeyAction",A_Action}};
class Monitor {
bool Sta; int KeyDownTime, IgnoredTime;
public :
int DAS, ARR, DCD; Monitor *Opposite;
int Key, DCDRem; bool Enabled, DASEnable;
Action Result;
Monitor(Action _Action, int _Key=0, bool _Enabled=true, int _DAS=-1, int _ARR=-1, int _DCD=0) {
Result = _Action;
Key=_Key; Enabled=_Enabled; DAS=_DAS; ARR=_ARR;
DCD=_DCD; Opposite=nullptr;
Sta=DASEnable=false; KeyDownTime=IgnoredTime=DCDRem=0;
}
int Output(int TimeDel, bool Ignore=false) {
bool NewSta = ((CheckKey(Key))&&(Enabled));
if (!NewSta) DCDRem=0;
else if ((Opposite>=0)&&(DCD>0)&&((Opposite!=nullptr)&&((Opposite->Sta)&&(!Opposite->DASEnable)))) DCDRem=DCD;
else DCDRem=max(0,DCDRem-TimeDel);
if (DCDRem) Ignore=true;
int res = 0;
if (!NewSta) {
DASEnable=false; KeyDownTime=IgnoredTime=0;
}
else if (Ignore) {
NewSta=Sta; IgnoredTime+=TimeDel;
}
else if (NewSta) {
KeyDownTime += TimeDel;
if (IgnoredTime) {
KeyDownTime+=IgnoredTime; IgnoredTime=0;
if (DASEnable) KeyDownTime=min(KeyDownTime,max(0,ARR));
else KeyDownTime=min(KeyDownTime,max(0,DAS));
}
if (!DAS) DASEnable=true;
if ((!Sta)&&(!DASEnable)) res=1;
else {
if (DASEnable) {
if ((ARR>=0)&&(KeyDownTime>=ARR)) {
res=1; KeyDownTime=min(max(0,KeyDownTime-ARR),ARR+5000);
}
}
else if ((DAS>=0)&&(KeyDownTime>=DAS)) {
res=1; DASEnable=true;
KeyDownTime = min(max(0,KeyDownTime-DAS),DAS+5000);
}
}
}
if (!Ignore) IgnoredTime=0;
Sta = NewSta;
return res;
}
bool CheckDAS() {
return DASEnable;
}
};
const vector<ConfigContent> HomeConfig =
{{"StartDelay",0},{"Stock",-1},{"Bot",1},{"BotType",6},{"BotSpeed",300},{"LCD",300},{"LockDelay",2000},{"ResetLim",9999999},{"AutoRespawn",1},{"HideStat",1},{"UseClick",0},{"RotateSystem",R_SRSPlus}};
const vector<ConfigContent> SettingConfig =
{{"StartDelay",0},{"Stock",-1},{"UseUp",1},{"UseZone",1},{"UseFlip",1},{"UseWaste",1},{"UseUndo",1},{"UseLock",1},{"UsePlace",1},{"HideStat",1},{"AutoRespawn",1},{"ResetLim",9999999},{"DropDelay",-1},{"LockDelay",-1},{"HoldType",2}};
const vector<ConfigContent> SelectConfig = {{"Player",0}};
vector<pair<int,int> > ASC_CW, ASC_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}};
vector<pair<int,int> > SRS[4][4], SRS_I[4][4];
vector<pair<int,int> > DefRot[4][4], DefRot_I[4][4], DefRot_O[4][4], ASCDX_O[4][4];
vector<pair<int,int> > SRS_C[4][4], DefRot_C[4][4];
vector<pair<int,int> > None = {{0,0}};
vector<pair<int,int> > ASCDX_CCW, ASCDX_CW, ASCDX_FLIP, ASCDX_RFLIP;
vector<pair<int,int> > DefRot_CCW, DefRot_CW, DefRot_FLIP, DefRot_RFLIP;
vector<pair<int,int> > C2;
vector<pair<int,int> > TX[4][4], TX_I[4][4];
void InitKick() {
SRS[0][3]={{0,0},{-1,0},{-1,+1},{0,-2},{-1,-2},{-1,-1},{0,+1},{0,-1}};
SRS[3][0]={{0,0},{+1,0},{+1,-1},{0,+2},{+1,+2},{+1,+1},{0,-1},{0,+1}};
SRS[3][2]={{0,0},{+1,0},{+1,-1},{0,+2},{+1,+2},{+1,+1},{0,-1},{0,+1}};
SRS[2][3]={{0,0},{-1,0},{-1,+1},{0,-2},{-1,-2},{-1,-1},{0,+1},{0,-1}};
SRS[2][1]={{0,0},{+1,0},{+1,+1},{0,-2},{+1,-2},{+1,-1},{0,+1},{0,-1}};
SRS[1][2]={{0,0},{-1,0},{-1,-1},{0,+2},{-1,+2},{-1,+1},{0,-1},{0,+1}};
SRS[1][0]={{0,0},{-1,0},{-1,-1},{0,+2},{-1,+2},{-1,+1},{0,-1},{0,+1}};
SRS[0][1]={{0,0},{+1,0},{+1,+1},{0,-2},{+1,-2},{+1,-1},{0,+1},{0,-1}};
SRS[0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
SRS[2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
SRS[1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
SRS[3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};
/*SRS_I[0][3]={{0,0},{-2,0},{+1,0},{-2,-1},{+1,+2}};
SRS_I[3][0]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
SRS_I[3][2]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
SRS_I[2][3]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
SRS_I[2][1]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
SRS_I[1][2]={{0,0},{-2,0},{+1,0},{-2,-1},{+1,+2}};
SRS_I[1][0]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
SRS_I[0][1]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
SRS_I[0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
SRS_I[2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
SRS_I[1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
SRS_I[3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};*/
SRS_I[0][3]={{0,0},{+1,0},{-2,0},{-2,-1},{+1,+2}};
SRS_I[3][0]={{0,0},{-1,0},{+2,0},{-1,-2},{+2,+1}};
SRS_I[3][2]={{0,0},{-1,0},{+2,0},{-1,+2},{+2,-1}};
SRS_I[2][3]={{0,0},{-2,0},{+1,0},{-2,+1},{+1,-2}};
SRS_I[2][1]={{0,0},{+2,0},{-1,0},{+2,+1},{-1,-2}};
SRS_I[1][2]={{0,0},{+1,0},{-2,0},{+1,+2},{-2,-1}};
SRS_I[1][0]={{0,0},{+1,0},{-2,0},{+1,-2},{-2,+1}};
SRS_I[0][1]={{0,0},{-1,0},{+2,0},{+2,-1},{-1,+2}};
SRS_I[0][2]={{0,0},{0,+1},{+1,+1},{-1,+1},{+1,0},{-1,0}};
SRS_I[2][0]={{0,0},{0,-1},{-1,-1},{+1,-1},{-1,0},{+1,0}};
SRS_I[1][3]={{0,0},{-1,0},{-1,+2},{-1,+1},{0,+2},{0,+1}};
SRS_I[3][1]={{0,0},{+1,0},{+1,+2},{+1,+1},{0,+2},{0,+1}};
// DefRot
SRS_C[0][1]={{0,0},{-1,0},{+1,0},{-2,0},{+2,0}};
SRS_C[1][0]={{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
SRS_C[3][2]={{0,0},{-1,0},{+1,0},{-2,0},{+2,0}};
SRS_C[2][3]={{0,0},{+1,0},{-1,0},{+2,0},{-2,0}};
SRS_C[3][0]={{0,0},{+1,0},{-1,0},{0,-1},{0,+1}};
SRS_C[0][3]={{0,0},{-1,0},{+1,0},{0,+1},{0,-1}};
SRS_C[2][1]={{0,0},{-1,0},{+1,0},{0,-1},{0,+1}};
SRS_C[1][2]={{0,0},{+1,0},{-1,0},{0,+1},{0,-1}};
SRS_C[3][1]={{0,0},{-1,0},{-1,+1},{0,+1},{+1,+1}};
SRS_C[1][3]={{0,0},{+1,0},{+1,-1},{0,-1},{-1,-1}};
SRS_C[2][0]={{0,0},{+1,0},{+1,+1},{0,+1},{-1,+1}};
SRS_C[0][2]={{0,0},{-1,0},{-1,-1},{0,-1},{+1,-1}};
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) {
DefRot[i][j]=SRS[i][j]; DefRot_I[i][j]=SRS_I[i][j]; DefRot_C[i][j]=SRS_C[i][j];
if ((i&1)!=(j&1)) {
while (SRS[i][j].size()>5) SRS[i][j].pop_back();
}
}
}
for (pair<int,int> o : ASC_CCW) ASC_CW.push_back(make_pair(-o.first,o.second));
vector<pair<int,int> > CCW, CW, FLIP, RFLIP;
CCW = {{0,0},{0,-1},{1,0},{1,-1},{0,-2},{1,-2},{0,-3},{2,0},{2,-1},{3,0},{3,-1},{2,-2},{1,-3},{3,-2},{2,-3},{3,-3}, // 15
{-1,0},{-1,-1},{0,1},{1,1},{2,1},{-1,-2},{3,1},{-1,-3},{-2,0},{0,2},{1,2},{2,2},{3,2},{-2,-1},{-2,-2},//30
{-1,1},{-2,-2},{1,3},{2,3},{3,3},{-3,-1},{-3,-2},{-3,-3},{-2,1},{-1,2},{-2,2},{-3,0},{0,3},{-3,1},{-1,3},{-3,2},{-2,3},{-3,3}};
/*
35 34 33 43 45 47 48
28 27 26 25 40 41 46
22 20 19 18 31 39 44
_9 _7 _1 _0 16 24 42
10 _8 _3 _2 17 29 36
13 11 _5 _4 21 30 37
15 14 12 _6 23 32 38
*/
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));
ASCDX_CCW=CCW; ASCDX_CW=CW;
ASCDX_FLIP=FLIP; ASCDX_RFLIP=RFLIP;
stable_sort(CCW.begin(), CCW.end(), [](pair<int,int> x, pair<int,int> y) {
return x.first*x.first+x.second*x.second<y.first*y.first+y.second*y.second;
});
stable_sort(CW.begin(), CW.end(), [](pair<int,int> x, pair<int,int> y) {
return x.first*x.first+x.second*x.second<y.first*y.first+y.second*y.second;
});
stable_sort(FLIP.begin(), FLIP.end(), [](pair<int,int> x, pair<int,int> y) {
return x.first*x.first+x.second*x.second<y.first*y.first+y.second*y.second;
});
stable_sort(RFLIP.begin(), RFLIP.end(), [](pair<int,int> x, pair<int,int> y) {
return x.first*x.first+x.second*x.second<y.first*y.first+y.second*y.second;
});
DefRot_CCW=CCW; DefRot_CW=CW;
DefRot_FLIP=FLIP; DefRot_RFLIP=RFLIP;
DefRot[0][2] = {{0,0},{+1,0},{+2,0},{0,-1},{+1,-1},{+2,-1},{-1,0},{-2,0},{-1,-1},{-2,-1},{+3,0},{-3,0}};
DefRot[3][1] = {{0,0},{0,-1},{0,-2},{-1,-1},{-1,-2},{0,-1},{+1,0},{0,-3},{-1,0}};
DefRot[2][0] = {{0,0},{0,-1},{-1,0},{-2,0},{0,+1},{+1,0},{+2,0},{-3,0},{+3,0},{0,+1}};
DefRot[1][3] = {{0,0},{0,-1},{0,-2},{+1,-1},{+1,-2},{0,-1},{-1,0},{0,-3},{+1,0}};
for (int i=0; i<4; ++i) {
DefRot_I[i][(i+2)&3] = DefRot[i][(i+2)&3];
DefRot_C[i][(i+2)&3] = DefRot[i][(i+2)&3];
}
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) {
vector<pair<int,int> > NK;
if (j==((i+1)&3)) NK=CCW;
if (j==((i+2)&3)) NK=(i<2)?FLIP:RFLIP;
if (j==((i+3)&3)) NK=CW;
for (pair<int,int> _gg : NK) {
bool ok = true;
pair<int,int> gg = _gg;
/*if ((i&1)!=(j&1)) {
if ((i==3)||(j==3)) gg.first=-gg.first;
if (i&1) {
gg.first=-gg.first; gg.second=-gg.second;
}
if (((i+3)&3)==j) gg.first=-gg.first;
}*/
for (pair<int,int> hh : DefRot[i][j]) {
if (gg==hh) ok=false;
}
if (ok) DefRot[i][j].push_back(gg);
ok = true;
for (pair<int,int> hh : DefRot_I[i][j]) {
if (gg==hh) ok=false;
}
if (ok) DefRot_I[i][j].push_back(gg);
ok = true;
for (pair<int,int> hh : DefRot_C[i][j]) {
if (gg==hh) ok=false;
}
if (ok) DefRot_C[i][j].push_back(gg);
}
}
}
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) DefRot_O[i][j]=ASCDX_O[i][j]={{0,0}};
}
vector<pair<int,int> > tmp;
for (int i=1; i<=3; ++i) {
tmp.push_back({0,-i});
for (int j=1; j<=1; ++j) {
tmp.push_back({j,-i}); tmp.push_back({-j,-i});
}
}
tmp.push_back({0,0});
DefRot_O[2][0] = tmp;
tmp.clear();
for (int i=1; i<=3; ++i) {
tmp.push_back({-i,0});
for (int j=1; j<=1; ++j) {
tmp.push_back({-i,j}); tmp.push_back({-i,-j});
}
}
tmp.push_back({0,0});
DefRot_O[1][3] = tmp;
tmp.clear();
for (int i=1; i<=3; ++i) {
tmp.push_back({i,0});
for (int j=1; j<=1; ++j) {
tmp.push_back({i,j}); tmp.push_back({i,-j});
}
}
tmp.push_back({0,0});
DefRot_O[3][1] = tmp;
tmp.clear();
for (int i=1; i<=5; ++i) {
tmp.push_back({0,-i});
for (int j=1; j<=min(i,1); ++j) {
tmp.push_back({j,-i}); tmp.push_back({-j,-i});
}
}
for (int i=1; i<=5; ++i) {
tmp.push_back({0,-i});
for (int j=min(i,1)+1; j<=3; ++j) {
tmp.push_back({j,-i}); tmp.push_back({-j,-i});
}
}
tmp.push_back({0,0});
ASCDX_O[2][0] = tmp;
tmp.clear();
for (int i=1; i<=5; ++i) {
tmp.push_back({-i,0});
for (int j=1; j<=min(i,1); ++j) {
tmp.push_back({-i,j}); tmp.push_back({-i,-j});
}
}
for (int i=1; i<=5; ++i) {
tmp.push_back({-i,0});
for (int j=min(i,1)+1; j<=3; ++j) {
tmp.push_back({-i,j}); tmp.push_back({-i,-j});
}
}
tmp.push_back({0,0});
ASCDX_O[1][3] = tmp;
tmp.clear();
for (int i=1; i<=5; ++i) {
tmp.push_back({i,0});
for (int j=1; j<=min(i,1); ++j) {
tmp.push_back({i,j}); tmp.push_back({i,-j});
}
}
for (int i=1; i<=5; ++i) {
tmp.push_back({i,0});
for (int j=min(i,1)+1; j<=3; ++j) {
tmp.push_back({i,j}); tmp.push_back({i,-j});
}
}
tmp.push_back({0,0});
ASCDX_O[3][1] = tmp;
// C2
C2 = {{0,0},{-1,0},{+1,0},{0,-1},{-1,-1},{+1,-1},{-2,0},{+2,0}};
// TetraX
for (int i=0; i<4; ++i) {
for (int j=0; j<4; ++j) {
if (((i+2)&3)==j) TX[i][j]={{0,0},{0,+1},{0,-1},{-1,0},{+1,0}};
else if (((i+3)&3)==j) TX[i][j]={{0,0},{0,+1},{-1,0},{+1,0},{-1,+1},{+1,+1},{0,-1},{-1,-1},{+1,-1}};
else if (((i+1)&3)==j) TX[i][j]={{0,0},{0,+1},{+1,0},{-1,0},{+1,+1},{-1,+1},{0,-1},{+1,-1},{-1,-1}};
}
}
TX_I[0][3] = {{0,0},{0,-1},{0,-2},{0,+1},{+1,-1},{-1,-1},{+1,-2},{-1,-2}};
TX_I[3][0]=TX_I[3][2]={{0,0},{0,-1},{0,-2},{0,+1},{-1,0},{+1,0},{+2,0}};
TX_I[2][3] = {{0,0},{0,+1},{0,+2},{0,-1},{-1,+1},{+1,+1},{-1,+2},{+1,+2}};
TX_I[2][1] = {{0,0},{0,+1},{0,+2},{0,-1},{+1,+1},{-1,+1},{+1,+2},{-1,+2}};
TX_I[1][2]=TX_I[1][0]={{0,0},{0,-1},{0,-2},{0,-1},{+1,0},{-1,0},{-2,0}};
TX_I[0][1] = {{0,0},{0,-1},{0,-2},{0,+1},{-1,-1},{+1,-1},{-1,-2},{+1,-2}};
}
vector<string> LineClearWord;
void InitText() {
LineClearWord.resize(27); LineClearWord[0]="VOID";
LineClearWord[1]="SINGLE"; LineClearWord[2]="DOUBLE"; LineClearWord[3]="TRIPLE"; LineClearWord[4]="QUAD";
LineClearWord[5]="PENTA"; LineClearWord[6]="HEXA"; LineClearWord[7]="HEPTA"; LineClearWord[8]="OCTA";
LineClearWord[9]="ENNEA"; LineClearWord[10]="DECA"; LineClearWord[11]="HENDECA"; LineClearWord[12]="DODECA";
LineClearWord[13]="TRIADECA"; LineClearWord[14]="TESSARADECA"; LineClearWord[15]="PENTEDECA"; LineClearWord[16]="HEXADECA";
LineClearWord[17]="HEPTADECA"; LineClearWord[18]="OCTADECA"; LineClearWord[19]="ENNEADECA"; LineClearWord[20]="EICOSA";
LineClearWord[21]="ULTIMATRIS"; LineClearWord[22]="KIRBTRIS"; LineClearWord[23]="INFINITRIS"; LineClearWord[24]="KAGARIS"; LineClearWord[25]="ELECTRIS";
LineClearWord[26] = "PERFECTRIS";
}
void InitChar() {
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['*'] = {"f3","jz"};
Char['/'] = {"e4"};
Char['\\'] = {"a8"};
Char[','] = {"y7"};
Char['.'] = {"5"};
Char['?'] = {"fbdjorw","6"};
Char['!'] = {"cw","6"};
Char[':'] = {"h","w"};
Char['#'] = {"fj","uy","b5","d7"};
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[4] = {"r"};
Char[10] = {"pht","1h"};
Char[11] = {"p1t","1h"};
Char[12] = {"hp1","pt"};
Char[13] = {"ht1","pt"};
Char[14] = {"uz3y"};
Char[15] = {"kco","0c","2c"};
Char[16] = {"msw","ps","j3"};
Char[17] = {"jyu","qu0"};
Char[18] = {"ae","4m8","vx"};
Char[19] = {"r","ht1ph","f","j","z","3"};
Char[22] = {"jfz","l3","o0"};
Char[23] = {"akoyw6"};
Char[24] = {"gv","ix","p1t"};
Char[25] = {"cpt6"};
Char[26] = {"mz","m3","uz0","23y","g","i"};
Char[27] = {"hm","nj","st","x3","w1","vz","qp","lf"};
Char[28] = {"0uph","fhr","ioy6","w68"};
Char[29] = {"z3","p0","t2","h1"};
Char[30] = {"pt","f3","jz"};
}
bool IsHardOType(string Name) {
if ((Name=="A")||(Name=="X")||(Name=="Z-1")||(Name=="O-3")
||(Name=="O-6")||(Name=="O-7")||(Name=="RO-7")||(Name=="O-10")) return true;
//if ((Name.empty())||(Name[0]!='?')) return false;
return false;
//int n=Name.size(); if (n<3) return false;
//return ((Name[n-2]=='-')&&(Name[n-1]=='1'));
}
bool IsBigOType(string Name) {
if ((Name.size()>=2)&&((Name[0]=='O')&&(Name[1]==':'))) return true;
return ((Name=="O-3")||(Name=="O-7")||(Name=="RO-7")||(Name=="O-10"));
}
bool IsHalfSame(string Name) {
return ((Name=="S")||(Name=="Z")||(Name=="O")||(Name=="I")
||(Name=="A")||(Name=="B")||(Name=="D")
||(Name=="I5")||(Name=="S5")||(Name=="Z5")||(Name=="X")
||(Name=="I6")||(Name=="O6")||(Name=="S6")||(Name=="Z6")
||(Name=="s6")||(Name=="z6")||(Name=="LZ")||(Name=="LS")
||(Name=="MW")||(Name=="WM"));
}
bool IsStrictHalfSame(string Name) {
if ((Name.size()>=2)&&((Name[0]=='h')&&(Name[1]==':'))) return true;
return ((Name=="D")||(Name=="I5")||(Name=="S5")||(Name=="Z5"));
}
bool IsOType(string Name) {
if ((Name.size()>=2)&&(((Name[0]=='o')||(Name[0]=='O'))&&(Name[1]==':'))) return true;
return ((Name=="O")||(IsHardOType(Name)));
}
bool IsEvenOType(string Name) {
return ((Name=="O")||(Name=="A")||(Name=="Z-1")
||(Name=="O-6")||(Name=="O-7")||(Name=="RO-7")||(Name=="O-10"));
}
bool IsCType(string Name) {
return ((Name=="C")||(Name=="V")||(Name=="W")||(Name=="A6")||(Name=="E6")||(Name=="J-4"));
}
bool IsComplex(string Name) {
return !((Name=="A")||(Name=="B")||(Name=="C")||
(Name=="I")||(Name=="J")||(Name=="L")||(Name=="O")||(Name=="S")||(Name=="T")||(Name=="Z"));
}
pair<int,int> GetShift(int Dir, string Name, ERotateSystem Rule) {
Dir = (Dir%4+4)&3;
if (Rule==R_ASC) {
if (IsEvenOType(Name)) return vector<pair<int,int> >({{0,0},{0,-1},{-1,-1},{-1,0}})[Dir];
if (Name=="I") return vector<pair<int,int> >({{0,0},{0,+1},{+1,+1},{+1,0}})[Dir];
}
if (Rule==R_RNRS) {
if ((Name=="I")||(Name=="B")||(Name=="I6")||(Name=="S")||(Name=="Z"))
return vector<pair<int,int> >({{0,-1},{-1,0},{0,0},{0,0}})[Dir];
}
if (Rule==R_LNRS) {
if ((Name=="I")||(Name=="B")||(Name=="I6")||(Name=="S")||(Name=="Z"))
return vector<pair<int,int> >({{0,-1},{-1,0},{0,0},{0,0}})[Dir];
}
if ((Rule==R_ARS)||(Rule==R_Sega)) {
if (Name=="I") return vector<pair<int,int> >({{0,0},{0,0},{0,+1},{+1,0}})[Dir];
if ((Name=="J")||(Name=="L")||(Name=="S")||(Name=="T")||(Name=="Z")
||(Name=="B")||(Name=="U")||(Name=="P")||(Name=="Q")) {
if (!Dir) return {0,-1};
}
if ((Name=="L5")||(Name=="J5")||(Name=="Y")||(Name=="R")||(Name=="N")||(Name=="H")) {
if (!(Dir&1)) return {0,-1};
}
if ((Name=="S")&&(Dir==1)) return {-1,0};
if ((Name=="Z")&&(Dir==3)) return {+1,0};
}
if (Rule==R_New) {
if (Name=="I")
return vector<pair<int,int> >({{0,-1},{-1,0},{0,0},{0,0}})[Dir];
if (Name=="J")
return vector<pair<int,int> >({{0,0},{0,0},{0,+1},{+1,0}})[Dir];
if (Name=="L")
return vector<pair<int,int> >({{0,0},{-1,0},{0,+1},{0,0}})[Dir];
if (Name=="S")
return vector<pair<int,int> >({{0,0},{0,0},{0,+1},{+1,0}})[Dir];
if (Name=="Z")
return vector<pair<int,int> >({{0,0},{-1,0},{0,+1},{0,0}})[Dir];
}
if (Rule==R_Atari) {
if (Name=="I")
return vector<pair<int,int> >({{0,+1},{-1,0},{0,+2},{0,0}})[Dir];
if (IsOType(Name)) return make_pair(0,0);
return vector<pair<int,int> >({{0,0},{-1,0},{0,+1},{0,0}})[Dir];
}
if (Rule==R_Zhoumetry) {
if (Name=="I") {
if (Dir) return make_pair(0,-1);
}
if (!IsOType(Name)) {
if (Dir==1) return make_pair(-1,0);
if (Dir==2) return make_pair(0,+1);
}
}
return make_pair(0,0);
}
int dx[4] = {1,0,-1,0};
int dy[4] = {0,-1,0,1};
pair<int,int> GetDXOffset(int Dir, string Name) {
if (IsOType(Name)) return make_pair(0,0);
return make_pair(dx[Dir],dy[Dir]);
}
vector<pair<int,int> > GetKick(int Dir, int Dest, string Name, ERotateSystem Rule) {
if (Dir==Dest) Dest=((Dir+2)&3);
if (Dir&1) Dir^=2;
if (Dest&1) Dest^=2;
if (Rule==R_SRSPlus) {
if (Name=="I") return SRS_I[Dir][Dest];
if (Name=="C") return SRS_C[Dir][Dest];
if ((Name=="B")||(Name=="D")||(Name=="J")||(Name=="L")||(Name=="O")||(Name=="S")||(Name=="T")||(Name=="Z")) return SRS[Dir][Dest];
//if (IsHardOType(Name)) return DefRot_O[Dir][Dest];
if (((Dir+3)&3)==Dest) return ASCDX_CW;
if (((Dir+1)&3)==Dest) return ASCDX_CCW;
if (Dir<2) return ASCDX_FLIP;
return ASCDX_RFLIP;
}
if (Rule==R_Default) {
if (Name=="I") return DefRot_I[Dir][Dest];
if (Name=="C") return DefRot_C[Dir][Dest];
if (IsBigOType(Name)) return ASCDX_O[Dir][Dest];
if (IsOType(Name)) return DefRot_O[Dir][Dest];
if ((((Dir+2)&3)==Dest)&&(IsStrictHalfSame(Name))) return DefRot_O[Dir][Dest];
if ((Name=="B")||(Name=="D")||(Name=="J")||(Name=="L")||(Name=="S")||(Name=="T")||(Name=="Z")) return DefRot[Dir][Dest];
if (((Dir+3)&3)==Dest) return DefRot_CW;
if (((Dir+1)&3)==Dest) return DefRot_CCW;
if (Dir<2) return DefRot_FLIP;
return DefRot_RFLIP;
}
if (Rule==R_ASCDX) {
if (IsOType(Name)) return ASCDX_O[Dir][Dest];
if ((((Dir+2)&3)==Dest)&&(IsStrictHalfSame(Name))) return ASCDX_O[Dir][Dest];
if (((Dir+3)&3)==Dest) return ASCDX_CW;
if (((Dir+1)&3)==Dest) return ASCDX_CCW;
if (Dir<2) return ASCDX_FLIP;
return ASCDX_RFLIP;
}
if (Rule==R_StrictSRSPlus) {
if (Name=="I") return SRS_I[Dir][Dest];
if (IsCType(Name)) return SRS_C[Dir][Dest];
return SRS[Dir][Dest];
}
if (Rule==R_ASC) {
if (((Dir+3)&3)==Dest) return ASC_CW;
if (((Dir+1)&3)==Dest) return ASC_CCW;
if (Dir<2) return ASC_CCW;
return ASC_CW;
}
if (Rule==R_C2) return C2;
if (Rule==R_DX) {
pair<int,int> os=GetDXOffset(Dir,Name), ot=GetDXOffset(Dest,Name);
return {{0,0},{os.second-ot.second,os.first-ot.first}};
}
if (Rule==R_ARS) {
if (IsComplex(Name)) {
if ((Dir&1)&&(!(Dest&1))) {
if ((Name=="I5")||(Name=="J5")||(Name=="L5")||(Name=="Y")||(Name=="R"))
return {{0,0},{+1,0},{-1,0},{0,-1},{0,+1},{2,0},{-2,0}};
}
return {{0,0},{+1,0},{-1,0},{0,-1}};
}
if ((((Dir&1)&&(!(Dest&1))))&&(Name=="I")) return {{0,0},{0,+1},{0,+2}};
if ((((Dir&1)&&(!Dest)))&&(Name=="T")) return {{0,0},{+1,0},{-1,0},{0,+1}};
if (Name!="I") return {{0,0},{+1,0},{-1,0}};
}
if (Rule==R_New) {
if (((Dir+3)&3)==Dest) return {{0,0},{+1,0},{0,-1},{-1,0},{0,+1}};
if (((Dir+1)&3)==Dest) return {{0,0},{-1,0},{0,-1},{+1,0},{0,+1}};
}
if (Rule==R_TetraX) {
if (Name=="I") return TX_I[Dir][Dest];
return TX[Dir][Dest];
}
if (Rule==R_Zhoumetry) {
if ((((Dir+2)&3)==Dest)&&((Name=="J")||(Name=="L")))
return {{0,0},{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,1},
{0,2},{0,-2},{1,-1},{-1,-1},{2,0},{-2,0},
{1,2},{-1,2},{2,1},{-2,1},{2,-1},{-2,-1}};
return {{0,0},{0,-1},{0,-2},{1,-1},{-1,-1},{1,-2},{-1,-2},
{0,1},{0,2},{1,0},{-1,0},{2,0},
{-2,0},{1,1},{-1,1},{2,1},{-2,1},{2,-1},
{-2,-1},{1,2},{-1,2},{2,2},{-2,2}};
}
return None;
}
vector<pair<int,int> > GetKickTable(int Dir, int Dest, string Name, ERotateSystem Rule) {
if ((Name.size()>=2)&&(Name[Name.size()-2]=='@')) {
int del = 0;
if (Name.back()=='R') del=1;
if (Name.back()=='D') del=2;
if (Name.back()=='L') del=3;
Dir = ((Dir+del)&3);
Dest = ((Dest+del)&3);
Name.pop_back(); Name.pop_back();
}
vector<pair<int,int> > res = GetKick(Dir,Dest,Name,Rule);
pair<int,int> FromShift=GetShift(Dir,Name,Rule), ToShift=GetShift(Dest,Name,Rule);
for (pair<int,int> &o : res) {
o.first += ToShift.first-FromShift.first;
o.second += ToShift.second-FromShift.second;
}
return res;
}
struct AccessMap {
int LX, LY; bool **B[4];
AccessMap(int _LX, int _LY) {
LX=max(2,min(100,_LX)); LY=max(1,min(100,_LY));
for (int d=0; d<4; ++d) {
B[d] = new bool*[LX+2];
for (int i=0; i<=LX+1; ++i) {
B[d][i]=new bool[LY+2]; memset(B[d][i],0,LY+2);
}
}
}
bool Query(int d, int x, int y) {
if ((d<0)||(d>3)) return false;
if (((x<0)||(y<0))||((x>LX)||(y>LY))) return false;
return B[d][x][y];
}
~AccessMap() {
for (int d=0; d<4; ++d) {
for (int i=0; i<=LX+1; ++i) delete[] B[d][i];
delete[] B[d];
}
}
};
struct Instruction {
int ord, d, x, y; bool sp;
bool operator !=(Instruction _) const {
return ((ord!=_.ord)||(d!=_.d)||(x!=_.x)||(y!=_.y));
}
bool operator ==(Instruction _) const {
return ((ord==_.ord)&&(d==_.d)&&(x==_.x)&&(y==_.y));
}
};
struct Status {
int LX, LY;
bool **B; Piece Cur; vector<Piece> Hold, Next;
ll AccEval; Instruction Inst;
int Combo, LineAfterPC; bool Clutch;
pair<string,int> LastClearType;
Status(int _LX, int _LY) {
LX=max(2,min(100,_LX)); LY=max(1,min(100,_LY)); Inst=(Instruction){-1,0,0,0,false};
B = new bool*[LX+2];
for (int i=0; i<=LX+1; ++i) {
B[i]=new bool[LY+2]; memset(B[i],0,LY+2);
}
Combo = 0;
}
Status(const Status &_From) {
LX=_From.LX; LY=_From.LY;
LineAfterPC = _From.LineAfterPC;
LastClearType = _From.LastClearType;
B = new bool*[LX+2];
Hold=_From.Hold; Next=_From.Next;
Inst=_From.Inst; AccEval=_From.AccEval;
for (int i=0; i<=LX+1; ++i) {
B[i]=new bool[LY+2]; memset(B[i],0,LY+2);
}
for (int i=1; i<=LX; ++i) {
for (int j=1; j<=LY; ++j) B[i][j]=_From.B[i][j];
}
Combo = _From.Combo;
Clutch = _From.Clutch;
}
void operator=(const Status &_From) {
if ((LX!=_From.LX)||(LY!=_From.LY)) {
if (B!=nullptr) {
for (int i=0; i<=LX+1; ++i) {
if (B[i]!=nullptr) delete[] B[i];
}
delete[] B; B=nullptr;
}
}
LX=_From.LX; LY=_From.LY;
LineAfterPC = _From.LineAfterPC;
LastClearType = _From.LastClearType;
if (B==nullptr) B=new bool*[LX+2];
Hold=_From.Hold; Next=_From.Next;
Inst=_From.Inst; AccEval=_From.AccEval;
for (int i=0; i<=LX+1; ++i) {
if (B[i]==nullptr) {
B[i]=new bool[LY+2]; for (int j=0; j<=LY+1; ++j) B[i][j]=0;
}
}
for (int i=1; i<=LX; ++i) {
for (int j=1; j<=LY; ++j) B[i][j]=_From.B[i][j];
}
Combo = _From.Combo;
Clutch = _From.Clutch;
}
bool CheckGrid(int x, int y) {
if (((x<1)||(y<1))||((x>LX)||(y>LY))) return true;
return B[x][y];
}
bool CheckPlace(Piece &p, int x, int y) {
int LX = p.GetLX();
for (int i=0; i<LX; ++i) {
for (int j=0; j<LX; ++j) {
if ((p.GetGrid(i,j))&&(CheckGrid(x+i,y+j))) return false;
}
}
return true;
}
llu GetHash(int HoldLen) {
llu res = 0LLU;
vector<llu> PieceOpt; PieceOpt.push_back(Cur.GetHash());
for (Piece p : Hold) PieceOpt.push_back(p.GetHash());
int tot = 0;
for (Piece p : Next) {
if (PieceOpt.size()>=HoldLen+1) break;