#include<bits/stdc++.h>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<time.h>
#include<cmath>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
using namespace std;
int m[51][51];
int T,S,mS,Die;
int G,gx,sx;
void Color(int a)
{
    if(a==-1) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY);
    if(a==0) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
    if(a==1) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
    if(a==2) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
    if(a==3) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);
    if(a==4) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
    if(a==5) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);
    if(a==6) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
    if(a==11) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_BLUE);
    if(a==12) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
    if(a==13) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE);
    if(a==14) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED);
    if(a==15) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN);
    if(a==16) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}
void SetPos(int x,int y)
{
    COORD pos;
    pos.X=y*2+2,pos.Y=18-x;
    if(y==-1) pos.X++;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void Map()
{
    if(mS<S) mS=S;Color(0);
    SetPos(17,1),cout<<"Score: "<<max(0,S)<<"      ";
    SetPos(16,1),cout<<"MaxScore: "<<mS<<"      ";
    for(int i=1;i<=11;i++)
    for(int j=1;j<=10;j++)
    {
        if(m[i][j]==0&&i!=11) SetPos(i,j),cout<<"  ";
        if(m[i][j]==1) SetPos(i,j),Color(5),cout<<"█",m[i][j]=0;
        if(m[i][j]==120) SetPos(i,j),Color(5),cout<<"★";
        else if(m[i][j]>=100)
        {
            int R=m[i][j]/100;
            SetPos(i,j),Color(m[i][j]%100);
            if(R==1) cout<<"▉";if(R==2) cout<<"█▉";if(R==3) cout<<"██▉";
			if(R==4) cout<<"███▉";if(R==5) cout<<"████▉";
            j+=R-1;
        }
    }
}
void Down(int a,int x)
{
    int B=0,s[11];
    if(a==0)
    {
        for(int i=2;i<=10;i++)
        for(int j=1;j<=10;j++)
        {
            if(m[i][j]>=100)
            {
                int b=0,R=m[i][j]/100;
                memset(s,0,sizeof(s));
                for(int k=1;k<=10;k++) {if(m[i-1][k]>=100) {int R=m[i-1][k]/100;for(int l=k;l<=k+R-1;l++) s[l]=1;k+=R-1;}}
                for(int k=j;k<j+R;k++) if(s[k]!=0) b=1;
                if(b==0) {x++;swap(m[i-1][j],m[i][j]);B=1;if(x>10) Sleep(10);else if(x>5) Sleep(50);else Sleep(100);Map();}
            }
        }
    }
    if(a==1)
    {
        for(int i=9;i>=1;i--)
        for(int j=1;j<=10;j++)
        {
            if(m[i][j]>=100)
            {
                int b=0,R=m[i][j]/100;
                memset(s,0,sizeof(s));
                for(int k=1;k<=10;k++) {if(m[i+1][k]>=100) {int R=m[i+1][k]/100;for(int l=k;l<=k+R-1;l++) s[l]=1;k+=R-1;}}
                for(int k=j;k<j+R;k++) if(s[k]!=0) b=1;
                if(b==0) {x++;swap(m[i+1][j],m[i][j]);B=1;if(x>10) Sleep(10);else if(x>5) Sleep(50);else Sleep(100);Map();}
            }
        }
    }
    if(B!=0) Down(a,x);
}
void Ji(int y,int a);
void Sheng()
{
    int n=0,f=0;
    N: S++;n++;
    if(G==0) for(int i=12;i>0;i--) swap(m[i],m[i-1]);
    if(G==1) for(int k=1;k<=10;k++) if(m[1][k]>=100) f=1;
    if(f==1) return;
    M: int B,C; B=C=0;
    for(int i=1;i<=10;i++)
    {
        int r=rand()%6+1,R=rand()%max(10,30-S/20)+1; 
        if(T%2==0) r+=10; if(T>30&&R==6) R=rand()%2+3;
        if(R<=3||(T>5&&R==4)||(T>40&&R==5)) {B=1;if(10-i+1<R) R=10-i+1;m[1][i]=R*100+r;i+=R-1;}
        else C=1;
    }
    if(B==0||C==0) goto M;
    if(T!=0&&T%7==0&&n==1) {int rr=rand()%10+1;Ji(rr,1);m[1][rr]=120;}
    for(int k=1;k<=10;k++) if(m[8][k]>=100) return;
    if(T>20&&n<2) {Map();Sleep(500);goto N;}
    if(T>50&&n<3) {Map();Sleep(500);goto N;}
}
void Star(int x,int y);
int Lie()
{
    int f=0;
    for(int i=1;i<=10;i++)
    for(int j=1;j<=10;j++)
    {
        int R=m[i][j];
        if(m[i][j]>=400) f=1;
        if(m[i][j]>=510) m[i][j]=m[i][j+2]=m[i][j+4]=R-400,m[i][j+1]=m[i][j+3]=R-410;
        else if(m[i][j]>=500) m[i][j]=m[i][j+2]=m[i][j+4]=R-400,m[i][j+1]=m[i][j+3]=R-390;
        else if(m[i][j]>=410) m[i][j]=m[i][j+2]=R-300,m[i][j+1]=m[i][j+3]=R-310;
        else if(m[i][j]>=400) m[i][j]=m[i][j+2]=R-300,m[i][j+1]=m[i][j+3]=R-290;
    }return f;
}
void Ji(int y,int a)
{
    int st=0,t[11][2],x=10;
    if(a==1) x=1;
    for(int i=1;i<=x;i++)
    {
        if(m[i][y]==120) st++,t[st][0]=i,t[st][1]=y;
        else if(m[i][y]>=200) m[i][y+1]=m[i][y]-100;
        else if(m[i][y-4]>=500) m[i][y-4]-=100;
        else if(m[i][y-3]>=400) m[i][y-3]-=100;
        else if(m[i][y-2]>=300) m[i][y-2]-=100;
        else if(m[i][y-1]>=200) m[i][y-1]-=100;
        m[i][y]=1;
    }
    for(int i=1;i<=st;i++) Star(t[i][0],t[i][1]);
}
bool Kline();
void Star(int x,int y)
{
    K:
    int D;int R=rand()%5+1;Color(5);S+=5;
    SetPos(15,1); cout<<"                       ";SetPos(14,1); cout<<"                       ";SetPos(13,1); cout<<"                       ";
    if(R==1) {SetPos(14,1),cout<<"激光!";Sleep(1000);int r=y+(rand()%2)*2-1;if(y==1) r=y+1;if(y==10) r=y-1;Ji(y,0);Ji(r,0);Ji(y,0);Ji(r,0);Map();Sleep(500);Map();}
    if(R==2) {SetPos(14,1),cout<<"反重力!";Sleep(1000);gx+=6;G=1;Down(G,0);while(Kline());}
    if(R==3) {SetPos(14,1),cout<<"封冻时间!";Sleep(1000);sx+=6;Map();}
    if(R==4) {for(int i=1;i<=10;i++) if(m[10-G*9][i]!=0||m[9-G*7][i]!=0) {D=1;break;}if(D==1) goto K;SetPos(14,1),cout<<"下雨!";Sleep(1000);for(int i=1;i<=10;i++) {if(m[10-G*9][i]>=100) i+=m[10-G*9][i]/100-1; else m[10-G*9][i]=101+5*(i%3);}while(Kline());}
    if(R==5) {if(Lie()==0) goto K;SetPos(14,1),cout<<"四分五裂!";Sleep(1000);Map();while(Kline());}
}
bool Kline()
{
    int B=0,b,st=0,t[11][2];
    Down(G,0);
    for(int i=1;i<=10;i++)
    {
        b=0;
        for(int j=1;j<=10;j++)
        {
            if(m[i][j]>=100)
            {
                int R=m[i][j]/100;
                j+=R-1;
            }
            else b=1;
        }
        if(b==0)
        {
            for(int k=1;k<=10;k++) {if(m[i][k]==120) st++,t[st][0]=i,t[st][1]=k;m[i][k]=1;}
            B=1;S+=10;Map();Sleep(200);Map();Down(G,0);
        }
    }for(int i=1;i<=st;i++) Star(t[i][0],t[i][1]);
    return B;
}
void Move()
{
    int q,w,s[12],d,dd;
    char e;
    M:
    Color(0);SetPos(15,1); cout<<"请输入需要移动块的";
    SetPos(14,1); cout<<"任意方块的行,列数。      "; 
    SetPos(13,1); Color(5),cout<<"回车";Color(0),cout<<"确定,按 0";
    if(sx==0) cout<<" 跳过。";else Color(1),cout<<"终止冻结.";Color(0);
    SetPos(12,1); cout<<"   →              ";
    SetPos(12,4); Color(5);scanf("%d",&q);
    if(q==0&&sx!=0) sx=0;
    else if(q!=0)
    {
		scanf("%d",&w);
    	if(m[q][w]>=100) w=w;
    	else if(m[q][w-1]>=200) w--;
    	else if(m[q][w-2]>=300) w-=2;
    	else if(m[q][w-3]>=400) w-=3;
    	else if(m[q][w-4]>=500) w-=4;
		else
    	{
    	    Color(3); 
    	    SetPos(12,3); cout<<"无效输入。";Sleep(800);
    	    SetPos(12,1); cout<<"                   ";
    	    goto M;
    	}
    	d=dd=w;
    	SetPos(q,w);Color(0);
    	int R=m[q][w]/100;
    	if(m[q][w]==120) cout<<"★";
    	else{if(R==1) cout<<"▉";if(R==2) cout<<"█▉";if(R==3) cout<<"██▉";if(R==4) cout<<"███▉";if(R==5) cout<<"████▉";}
    	
    	SetPos(15,1); cout<<"                       ";SetPos(14,1); cout<<"                       ";SetPos(13,1); cout<<"                       ";
    	SetPos(14,1); cout<<"按←→水平控制白亮块。";
    	SetPos(13,1); cout<<"按↓确定,按↑撤销。";
    	memset(s,0,sizeof(s));
    	for(int i=1;i<=10;i++) {if(m[q][i]>=100&&i!=w) {R=m[q][i]/100;for(int j=i;j<=i+R-1;j++) s[j]=1;i+=R-1;}}
    	R=m[q][w]/100;
    	while(e!=80)
    	{
    	    e=_getch();
    	    if(e==75&&s[d-1]==0&&d>1) swap(m[q][d],m[q][d-1]),d--,Map();
    	    if(e==77&&s[d+R]==0&&d+R<=10) swap(m[q][d],m[q][d+1]),d++,Map();
    	    if(e==72) {swap(m[q][d],m[q][dd]),Map();goto M;}
    	}
    }SetPos(13,1); cout<<"                       ";SetPos(14,1);Color(0); cout<<"正在处理...请稍后...    ";SetPos(15,1); cout<<"                       ";
  	while(Kline());
}	
void Start()
{
    system("cls");Color(0);
    SetPos(17,2); cout<<"重 力 消 消 乐 2.0";
    SetPos(16,2); cout<<"Gravity  Blast";Color(1); 
    SetPos(15,-1); cout<<"-------------[ 键盘操作 ]-";Color(0);
    SetPos(14,2); cout<<"这是胎神大大编的";
    SetPos(13,2); cout<<"第一个益智游戏。"; 
    SetPos(12,-1); cout<<"--------------------------";
    SetPos(11,-1); cout<<"游戏规则:";
    SetPos(10,0); cout<<"每一回合会从底部产生块。"; 
    SetPos(8,0); cout<<"选择一个块来水平移动,"; 
    SetPos(6,0); cout<<"落下后形成一行可消除得分!";
    SetPos(4,0); cout<<"若有块被刺破,游戏结束。"; 
    SetPos(3,-1); cout<<"--------------------------";
    SetPos(2,-1); cout<<"另:星星被消后有特殊效果!";
    SetPos(0,1); cout<<"按y开始游戏!";
    char e;while(e!='y') e=_getch();system("cls");
    SetPos(0,1); cout<<"1 2 3 4 5 6 7 8 9 10";
    for(int i=1;i<=10;i++) SetPos(i,11),cout<<' '<<i,SetPos(i,-1),cout<<setw(2)<<i;
    SetPos(14,1); cout<<"正在准备...请稍后...    ";
    SetPos(11,0);Color(4);
    cout<<"▼▼▼▼▼▼▼▼▼▼▼▼";
}
int main()
{
    system("mode con cols=28 lines=20");
    CONSOLE_CURSOR_INFO cursor_info={1,0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
    srand((unsigned)time(NULL));
    St: S=T=-5;Die=G=gx=sx=0;
    memset(m,0,sizeof(m)); Start();
    for(int i=1;i<=4;i++) {T++,Sheng(),Map();while(Kline());Sleep(500);}
    while(1)
    {
        T++;int f=0;
        if(gx!=0) gx--;if(gx==0) G=0;Down(G,0);
        if(sx!=0) sx--;else Sheng();Map();
        for(int i=1;i<=10;i++) {if(m[11][i]!=0) Die=1;} if(Die==1) break;
        while(Kline());Move();
        Sleep(500);
    }
    system("color 4F");Sleep(1000);
    SetPos(17,6),Color(0),cout<<" You Die! ";
    SetPos(16,6),cout<<" 按y重玩。";
    char e;while(e!='y') e=_getch(); goto St; 
    return 0;
}