#include<bits/stdc++.h>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include<time.h>
using namespace std;
const double pi=3.1415926536;
int toint(float a){return ((int)(a*10+5))/10;}
void Color(int a){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_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);}
//0123456
void Setpos(float x,float y){int xx=toint(x),yy=toint(y);COORD pos;pos.X=xx*2,pos.Y=yy;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);}
int T,Sco,sco,color,col,colortime,colormax,speed,board,Blen,Rcolor,board2;
float X,Y,vx,vy,ax,ay,g=0.12;
int turn,bluetime=3;float bluea=0.5,bluepause=0.7,greenpause=0.9,purpleS=5,blackF=2,WD,WDmax=10;
int D[2][4]={{1,-1,0,0},{0,0,1,-1}};
struct node{int t,c,die,turn;}C[100001];int cl,cr;
void Go(float t)//使用正坐标轴  边界:0-20 
{
	float x2=X,y2=Y;int out;bool vxe=0,vye=0; 
	ax=0,ay=g;
	if(color==1) {ax=bluea*D[0][turn],ay=bluea*D[1][turn];if(D[0][turn]!=0) vy*=bluepause;else vx*=bluepause;}
	if(color==2) vx*=greenpause,vy*=greenpause;
	if(color==6) {float Ax=10-X,Ay=10-Y,Dis=sqrt(Ax*Ax+Ay*Ay)*1.0;
		if(Dis>1&&abs(Ax)>1&&abs(Ay)>1) {float ac=blackF/(Dis*Dis)*1.0,afx,afy;float d=abs(Ax/Ay*1.0)+1;
			afy=sqrt(ac/(1+d*d))*1.0,afx=sqrt(ac/(1+d*d))*d*1.0;if(Ax>0) afx*=-1;if(Ay>0) afy*=-1;vx-=afx;vy-=afy;}}
	if(vx<0) vxe=1,vx*=-1;if(vy<0) vye=1,vy*=-1;
	vx=fmin(2.0,fmax(0.1,vx)),vy=fmin(2.0,fmax(0.1,vy));
	if(vx<=0.2&&vy<=0.2&&color==2) color=4;
	if(vxe==1) vx*=-1;if(vye==1) vy*=-1;
	if(color==1) x2+=vx*t,y2+=vy*t;
	else if(color==2||color==5||color==6) ax=ay=0,x2+=vx*t,y2+=vy*t;
	else x2+=vx*t,y2+=vy*t+0.5*g*t*t;
	if(y2<0||y2>20){X=fmax(0.4,fmin(19.5,x2));Y=fmax(0.4,fmin(19.5,y2));
		if(color==1&&turn>=2&&colortime==0) colortime=bluetime;
		else if(color==1&&turn>=2&&colortime!=0) color=4;
		if(color==2) color=4;
		if(color==6) vy=0;else vy*=-1;
		if(Y>=19.5){board2=5;
			if((board-0.4>X||board+Blen+0.4<X)&&WD==0) system("Color C"),Sleep(500),system("Color F"),Sco-=5,WD=WDmax;
			else if(color!=6){Sco++;vx=(float)(rand()%50)/20.0-1.25;vy*=0.9+(rand()%40)/200.0;}
			if(abs(vx)>=2) vx*=0.9;if(abs(vy)<=1.7) vy*=1.2;if(abs(vy)>=2.2) vy*=0.9;if(abs(vy)<=1||color==6) vy=-1;
		}return;}
	else if(x2<0||x2>20){X=fmax(0.4,fmin(19.5,x2));Y=fmax(0.4,fmin(19.5,y2));
		if(color==1&&turn<2&&colortime==0) colortime=bluetime;
		else if(color==1&&turn<2&&colortime!=0) color=4;
		if(color==2) color=4;
		if(color==6) vx=0;else vx*=-1;if(abs(vx)>=2) vx*=0.85;return;}
	else X=x2,Y=y2,vx+=ax*t,vy+=ay*t;
}
void Board(int a){//1:动弹板 
	Setpos(board,20);Color(0);
	for(int i=1;i<=Blen;i++) {if(a==0) cout<<"  ";if(a==1) cout<<"●";}
}
void Line(int c,int t,int tur,int a){Color(c);
	if(tur==0) for(int i=1;i<=19;i+=2) {Setpos(20-t*2,i);if(a==0) cout<<' ';else if(c==1) cout<<'@';else cout<<'#';}
	if(tur==1) for(int i=1;i<=19;i+=2) {Setpos(t*2,i);if(a==0) cout<<' ';else if(c==1) cout<<'@';else cout<<'#';}
	if(tur==2) for(int i=1;i<=19;i+=2) {Setpos(i,20-t*2);if(a==0) cout<<' ';else if(c==1) cout<<'@';else cout<<'#';}
	if(tur==3) for(int i=1;i<=19;i+=2) {Setpos(i,t*2);if(a==0) cout<<' ';else if(c==1) cout<<'@';else cout<<'#';}
}
float Sin(int a) {return sin(3.1416*a/180);}float Cos(int a) {return cos(3.1416*a/180);}
void Circle(int c,int t,int a){
	int rx=10,ry=10,r=t,num=10,next=360/num,start=t*7; 
	for(register int i=0;i<num;i++){
		Setpos(rx+Sin(i*next+start)*r,ry+Cos(i*next+start)*r);
		Color(c);if(a==0) cout<<' ';else if(c==0) cout<<'&';else if(c==2) cout<<'*';else if(c==4) cout<<'$';else if(c==5) cout<<'%';else cout<<'X';}
}
void ChangeColor(int c)
{color=c;colortime=0;
	if(color==3) Setpos(X,Y),cout<<"  ",X+=D[0][turn]*purpleS,Y+=D[1][turn]*purpleS,X=fmax(0.5,fmin(19.5,X)),Y=fmax(0.5,fmin(19.5,Y)),colortime=5;
	else if(color==5) {int exspeed=1.5;vx*=exspeed;vy*=exspeed;colormax=colortime=10+rand()%50;}
	else if(color==6) colormax=colortime=10+rand()%30;
	else if(color==0) vy=-1.5,vx*=0.8,colortime=5;
} 
void Remind(int n,int c,int t,int tur){
	if(c==1||c==3) {if(t!=10) Line(c,t+1,tur,0);if(t!=0) Line(c,t,tur,1);}
	else {if(t!=10) Circle(c,t+1,0);if(t!=0) Circle(c,t,1);}
	if(t==0) turn=tur,ChangeColor(c),C[n].die=1;
}
void Start()
{
	char g;Color(5);system("cls");
	Setpos(1,1);cout<<"      ---●-- 小胎弹弹乐 --●---";Color(0);
	Setpos(1,3);cout<<"  -- 一个看似简单但你却无法通关的游戏...";
	Setpos(1,4);cout<<"  ----------  作者:胎神大大  ---------";
	Setpos(1,5);cout<<"游戏规则:";
	Setpos(1,7);cout<<"1.相信大家都玩过弹弹乐吧!";
	Setpos(1,8);Color(5),cout<<"  ←→键控制跳板接住球即可得分!";Color(0);
	Setpos(1,9);cout<<"2.但是在这个游戏,会出现 不同颜色 的魔法攻击来 扰乱 球的轨道!";
	Setpos(1,11);cout<<"3.  ";Color(4),cout<<"普通颜色:红";
	Setpos(3,12);Color(1),cout<<"蓝色攻击:重力";Color(5),cout<<"  黄色攻击:匀速";
	Setpos(3,13);Color(2),cout<<"绿色攻击:束缚";Color(3),cout<<"  紫色攻击:瞬移";
	Setpos(3,14);Color(0),cout<<"白色攻击:上推";Color(6),cout<<"  黑色攻击:引力";
	Setpos(1,15);Color(0),cout<<"   ( 记法:愤怒的小鸟 + 传说之下 )";
	Setpos(1,16);cout<<"4.按下 空格 可以暂停";
	Setpos(1,17);cout<<"5.板长与变色概率随分数改变!";Color(5),cout<<"100分通关!";Color(0);
	Setpos(1,19);cout<<"  开始游戏:";system("pause");
}
int main()
{
	system("mode con cols=43 lines=21");
	CONSOLE_CURSOR_INFO cursor_info={1,0};
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
	srand((unsigned)time(NULL));St:Start();system("cls");
	X=2,Y=5,vx=0.2,vy=0,color=4,speed=50,Sco=0,board=5,Blen=7,cl=1,cr=0;
	Color(0);Board(1);
	while(1)
	{
		T++;
		if(Sco>=100) break;Sco=max(0,Sco);
		if(Sco!=sco||T%100==1){if(T%200==1||Sco<sco) system("cls"),Board(1);
			Color(0),Setpos(1,1),cout<<"分数:"<<Sco<<' ';sco=Sco;
			Rcolor=(int)(90-0.6*Sco);
			int blen=(int)(7-(Sco+20)/30);if(Blen<blen&&board>=21-Blen) Board(0),board--;if(Blen!=blen) Board(0),Blen=blen,Board(1);
		}
		if(GetAsyncKeyState(VK_LEFT)&0x8000&&board>0) Board(0),board--,Board(1);
		if(GetAsyncKeyState(VK_RIGHT)&0x8000&&board<21-Blen) Board(0),board++,Board(1);
		if(kbhit()){char c=_getch();if(c==' ') Color(0),Setpos(1,2),system("pause"),Setpos(1,2),cout<<"                           ";}
		if(colortime==1) color=4;
		if(colortime>0) {Setpos(1,2),colortime--;if(color==5||color==6){for(int i=1;i<=colortime-1;i+=colormax/9) Color(color),cout<<"▂";cout<<"                   ";}}
		if(WD>0) WD--;
		if(rand()%Rcolor==0) {cr++;CC:C[cr].c=rand()%7; 
			if(C[cr].c==4) goto CC;C[cr].t=10;C[cr].die=0;C[cr].turn=rand()%4;}
		while(C[cl].die==1) cl++;if(cr<cl) cr=0,cl=1,memset(C,0,sizeof(C));
		for(int i=cl;i<=cr;i++) {Remind(i,C[i].c,C[i].t,C[i].turn);C[i].t--;}
		Setpos(X,Y);cout<<"  ";
		Go(1);
		if(board2>0) Board(1),board2--;
		if(color!=col) Setpos(1,2),cout<<"                                  ";
		if(color==6) Color(color),Setpos(10,10),cout<<"○";
		else if(col==6) Setpos(10,10),cout<<"  ";col=color;
		Color(color),Setpos(X,Y);cout<<"●";
		Sleep(speed);
	}
	if(Sco<100) {Setpos(6,9);system("color 7F");Color(11);cout<<"   GAME OVER...";}
	else {Setpos(6,9);system("color 6E");Color(5);cout<<"LEVEL VICTORY !";}
	Setpos(4,11);Sleep(1000);cout<<"play again? (y/n)";Sleep(1000);char g;
	A:if(kbhit()) g=_getch();if(g=='n') return 0;else if(g!='y') goto A;else if(g=='y') goto St;
}