using System;
using System.Threading;
using System.Collections;
using System.Diagnostics;
namespace box
{
    class MainClass
    {
        public static string cmd;
        public const int MAXX=20;
        public const int MAXY=21;
        static Block bn;
        public static ArrayList boxcore;
        protected static bool pressed;
        public static bool endAble;
        public static ConsoleColor currentColor;
 
        public static void unlockpress ()
        {
            pressed=false;
        }
 
        public static void Main (string[] args)
        {
        Start:initGame();
        Conf:while(true){
                Thread.Sleep(40);
                if(!endAble){
                bn.run();
                pressed=false;
                if(Console.KeyAvailable && !pressed){
                    ConsoleKeyInfo inf=Console.ReadKey ();
                    if(inf.Key==ConsoleKey.RightArrow){
                        cmd="R";                
                        pressed=true;
                        break;
                    }else if(inf.Key==ConsoleKey.LeftArrow){
                        cmd="L";
                        pressed=true;
                        break;
                    }else if(inf.Key==ConsoleKey.UpArrow){
                        cmd="U";
                        pressed=true;
                        break;
                    }else if(inf.Key==ConsoleKey.DownArrow){
                        cmd="D";
                        pressed=true;
                        break;
                    }
                    else
                    {
                        cmd="T";
                        pressed=true;
                        break;
                    }
                }
                }else{
                    break;
                }
            }
            bn.move (cmd);
            cmd="";
            if(endAble){
                goto End;
            }
            goto Conf;
        End:    Console.Clear ();
            Console.WriteLine ("　　　　　＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆");
            Console.WriteLine ("　　　　　　　　　　　　　Game　Over　　　　　　　");
 
            Console.WriteLine ("     　　　　　　　Score:" + title.score);
            Console.WriteLine ("     　　　　　　　Piece:" + title.piece);
            Console.WriteLine ("     　　　　　　　Replay? Y/N");
            Console.WriteLine ("　　　　　＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆＆");    
            if (Console.ReadLine()=="Y") {
                goto Start;
            }
        }
 
        protected static void initGame ()
        {//init game
        //  ConsoleColor col=Block.RandomColor ();
            bn=new Block(new Box[4]{new Box((int)MAXX/2,0),new Box((int)MAXX/2,1),new Box((int)MAXX/2+1,0),new Box((int)MAXX/2+1,1)});
            if(boxcore!=null){
                boxcore.Clear ();
            }
            boxcore=new ArrayList();
            pressed=false;
            currentColor=ConsoleColor.Cyan;
            Console.ForegroundColor=currentColor;
            title.init ();
            screen.update(bn);
            endAble=false;
 
        }
        public static bool isOver (Block b)
        {
            bool re=false;
            foreach(Box box in b.Arr){
                if(box.Y==0){
                    re=true;
                    break;
                }
            }
            return re;
        }
 
        public static void releaseBlock (Block b)
        {
            //release all box of this block to box pool.
            if (!isOver (b)) {
                Box[] arr = b.Arr;
 
                foreach (Box box in arr) {
                    boxcore.Add (box);
                }
                title.piece += 1;
                b.ca_delay();
                //then must check the line that whether will be clear
                ArrayList checkline = b.getCheckArr ();
                //Debug.Print (debugline (checkline));
                int dropline = 0;
                foreach (int i in checkline) {
                    dropline += check (i);
                }
                if (dropline > 1) {
                    title.addScore (25 * dropline);
                }
 
                foreach (Box box in boxcore) {
                    box.ca_dropline (boxcore);
                }
                ArrayList narr=new ArrayList();
 
                foreach(Box box in boxcore){
                    if(!box.deleteAble){
                        narr.Add (box);
                    }
                }
                boxcore=narr;
                foreach (Box box in boxcore) {
                    box.drop ();
                }
 
                ca_color(); 
            } else {
                MainClass.endAble=true;
            }
        }
        public static void ca_color ()
        {
            //According to minY transfrom color 
            float pre =(float)getMINY ()/MainClass.MAXY ;//
            ConsoleColor col=ConsoleColor.Cyan;
            //Debug.Print (pre.ToString ());
            if (pre <= 0.2f) {
                col = ConsoleColor.Red;
            } else if (pre > 0.2f && pre <= 0.4f) {
                col = ConsoleColor.Magenta;
            } else if (pre > 0.4f && pre <= 0.6f) {
                col = ConsoleColor.Yellow;
            } else if (pre > 0.6f && pre <= 0.8f) {
                col = ConsoleColor.Green;
            } else {
                col=ConsoleColor.Cyan;
            }
            if(currentColor!=col){
                currentColor=col;
                Console.ForegroundColor=currentColor;
            }
        }
        protected static int getMINY ()
        {
            int re=MAXY;
            foreach(Box b in boxcore){
                if(b.Y<re){
                    re=b.Y;
                }
            }
            return re;
        }
        public static string debugline (ArrayList arr)
        {
            string re="";
            for(int i=0;i<arr.Count;i++){
                re+=arr[i].ToString ();
            }
            return re;
        }
        public static int check (int line)
        {
            int x;
            int re=0;
            bool clear=true;
            for(x=0;x<MAXX;x++){
                if(!findPos(x,line)){
                    clear=false;
                    break;
                }
            }
            if(clear){
                Box box=null;
                for(x=0;x<MAXX;x++){
                    box=findBox (x,line);
                    box.deleteAble=true;
                }
                title.addScore (100);
                //
                re=1;
            }
            return re;
        }
        public static Box findBox(int vx,int vy){
            Box re=null;
            foreach(Box b in boxcore){
                if(b.X==vx && b.Y==vy){
                    re=b;
                    break;
                }
            }
            return re;
        }
        public static bool findPos (int vx,int vy)
        {
            //According to the x, y data find box in ArrayList
            bool re=false;
            foreach(Box b in boxcore){
                if(b.X==vx && b.Y==vy){
                    re=true;
                    break;
                }
            }
            return re;
        }
        public static bool onPos (int nx,int ny)
        {//return true means the position nx,ny is blocked
            bool re=false;
            foreach(Box box in boxcore){
                if(box.onpos (nx,ny)){
                    re=true;
                    break;
                }
            }
            return re;
        }
    }
    public static class screen{
        //screen: do update the screen
        public static bool haveBoxOnPool(int x,int y){
            ArrayList arr =MainClass.boxcore;
            bool re=false;
            foreach(Box b in arr){
                if(b.onpos (x,y)){
            //      Console.ForegroundColor=b.Color;
                    re=true;
                    break;
                }
            }
            return re;
        }
        public static void update (Block bl)
        {
            //update the screen
            Console.Clear ();
            int i;
            int j;
            string tmp="＆";
        //  Console.ForegroundColor=ConsoleColor.Gray;
            for(i=0;i<=MainClass.MAXX;i++){
                tmp+="＆";
            }
 
            Console.WriteLine (tmp);
        //  Console.Write ('＆');
            tmp="＆";
            for(i=0;i<MainClass.MAXY;i++){
                for(j=0;j<MainClass.MAXX;j++){
                    if(bl.haveBox(j,i)||haveBoxOnPool(j,i)){
                        tmp+="＊";
                        //Console.Write ('＊');
                    }else{
                        tmp+="　";
                        //Console.Write ('　');
                    }
                }
            //  Console.ForegroundColor=ConsoleColor.Gray;
                //Console.Write('＆');
                //Console.WriteLine (title.updateByLine (i));
                Console.WriteLine (tmp+"＆"+title.updateByLine(i));
                tmp="＆";
                //Console.Write('＆');
                //Console.Write ('\n');
            }
            tmp="＆";
            for(i=0;i<=MainClass.MAXX;i++){
                tmp+="＆";
            }
            Console.WriteLine (tmp);
        }
    }
    public class title{
        //show score,nextblock and game stauts
        public static int next;
        public static int score;
        public static int piece;
        public static void init(){
            score=0;
            piece=0;
            next=0;
        }
        public static void addScore (int scr)
        {
            score+=scr;
        }
        public static string updateByLine(int lin){
            string re=""; 
            switch(lin){
            case 0:
                re="=========Tetris=========";
                break;
            case 1:
                re="       present by";
                break;
            case 2:
                re="     asahix 20141224";
                break;
            case 4:
                re="==========Next==========";
                break;
            case 6:
                if(next==1){
                    re="　　　　　＊";
                }else if(next==2){
                    re="　　　　　　＊";
                }else if(next==3){
                    re="　　　　　＊";
                }else if(next==4){
                    re="　　　　　　＊";
                }else if(next==5){
                    re="　　　　　＊";
                }
                break;
            case 7:
                if(next==0){
                    re="　　　　　＊＊";
                }else if(next==1){
                    re="　　　　　＊＊";
                }else if(next==2){
                    re="　　　　　＊＊";
                }else if(next==3){
                    re="　　　　　＊";
                }else if(next==4){
                    re="　　　　　　＊";
                }else if(next==5){
                    re="　　　　　＊";
                }else if(next==6){
                    re="　　　　　　＊";
                }
                break;
            case 8:
                if(next==0){
                    re="　　　　　＊＊";
                }else if(next==1){
                    re="　　　　　　＊";
                }else if(next==2){
                    re="　　　　　＊";
                }else if(next==3){
                    re="　　　　　＊＊";
                }else if(next==4){
                    re="　　　　　＊＊";
                }else if(next==5){
                    re="　　　　　＊";
                }else if(next==6){
                    re="　　　　　＊＊＊";
                }
                break;
            case 9:                             
                 if(next==5) {
                    re="　　　　　＊";
                }
                break;
            case 10:
 
                break;
            case 11:
                re="==========Info==========";  
                break;
            case 12:
                re="　　　　Score:"+score;
                break;
            case 13:
                re="　　　　Piece:"+piece;
                break;
            case 15:
                re="===========Hint=========";
                break;
            case 16:
                re="　　　　● : rotate";
                break;
            case 17:
                re="　　　　○ : left";
                break;
            case 18:
                re="　　　　★ : right";
                break;
            case 19:
                re="　　　　◎ = down";
                break;
            case 20:
                re="========================";
                break;
            }
            return re;
        }
    }
    public class Box{
        protected int x;
        protected int y;
        public bool deleteAble;
        public int dropline;
        protected ConsoleColor color;
        public ConsoleColor Color {
            get {
                return color;
            }
        }
        public void ca_dropline (ArrayList arr)
        {
            dropline=0;
            if(!this.deleteAble){
                foreach(Box b in arr){
                    if(b.Y>this.Y && b.X==this.X && b.deleteAble){
                        dropline+=1;
                    }
                }
            }
 
        }
        public void drop ()
        {
            y+=dropline;
            dropline=0;
        }
        public int X {
            set {
                x=value;
            }
            get {
                return x;
            }
        }
        public int Y {
            set {
                y = value;
            }
            get {
                return y;
            }
        }
        public Box(int vx,int vy,ConsoleColor col){
            x=vx;
            y=vy;
            deleteAble=false;
            color=col;
            dropline=0;
        }
        public Box (int vx,int vy)
        {
            x=vx;
            y=vy;
            deleteAble=false;
 
            dropline=0;
        }
        public void moveL(){
            x=x>0?x-1:x;
        }
        public void moveR(){
            x=x<MainClass.MAXX-1?x+1:x;
        }
        public void moveU(){
            y=y>0?y-1:y;
        }
        public void moveD(){
            y=y<MainClass.MAXY-1?y+1:y;
        }
        public bool onpos (int vx,int vy)
        {
            return x==vx && y==vy;
        }
        public string show ()
        {
            return "X="+x+" Y="+y;
        }
    }
    public class Block{
        protected Box[] arr;
        protected int tim;
        protected int rotated;
        protected int styleId;
        public bool rotateAble;
        public static int nextStyle;
        protected int delay;
        public ArrayList getCheckArr ()
        {
            //return the line number (box .Y ) that will checked
            ArrayList re=new ArrayList();
            foreach(Box b in arr){
                if(!findNum (re,b.Y)){
                    re.Add (b.Y);
                }
            }
            return re;
        }
        public bool findNum (ArrayList array,int check)
        {//find number in array if finded return true;
            bool re=false;
            foreach(int i in array){
                if(i==check){
                    re=true;
                    break;
                }
            }
            return re;
        }
        public Box[] Arr {
            get {
                return arr;
            }
        }
        public static ConsoleColor RandomColor ()
        {
            ConsoleColor re=ConsoleColor.Black;
            Random rnd=new Random();
            switch(rnd.Next (16)){
            case 0:
                re=ConsoleColor.Blue;
                break;
            case 1:
                re=ConsoleColor.Cyan;
            break;  
            case 2:
                re=ConsoleColor.DarkBlue;
            break;
            case 3:
                re=ConsoleColor.DarkCyan;
            break;
            case 4:
                re=ConsoleColor.DarkGray;
            break;
            case 5:
                re=ConsoleColor.DarkGreen;
            break;
            case 6:
                re=ConsoleColor.DarkMagenta;
            break;
            case 7:
                re=ConsoleColor.DarkRed;
            break;
            case 8:
                re=ConsoleColor.DarkYellow;
            break;
            case 9:
                re=ConsoleColor.Gray;
                break;
            case 10:
                re=ConsoleColor.Green;
                break;
            case 11:
                re=ConsoleColor.Magenta;
                break;
            case 12:
                re=ConsoleColor.Red;
                break;
            case 13:
                re=ConsoleColor.White;
                break;
            case 14:
                re=ConsoleColor.Yellow;
                break;
            }
            return re;
        }
        public void ca_newStyle ()
        {
            Random rnd=new Random();
            int rd=nextStyle;
            styleId=rd;
            nextStyle=rnd.Next (7);//record the next style and put it on screen
            screen.title.next=nextStyle;
            //ConsoleColor col=RandomColor();
            Box[] n=new Box[4]{new Box((int)MainClass.MAXX/2,0),new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2+1,0),new Box((int)MainClass.MAXX/2+1,1)};;
            switch(rd){
            case 1:
                n=new Box[4]{new Box((int)MainClass.MAXX/2,0),new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2+1,1),new Box((int)MainClass.MAXX/2+1,2)};
                break;
            case 2:
                n=new Box[4]{new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2,2),new Box((int)MainClass.MAXX/2+1,0),new Box((int)MainClass.MAXX/2+1,1)};
                break;
            case 3:
                n=new Box[4]{new Box((int)MainClass.MAXX/2,0),new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2,2),new Box((int)MainClass.MAXX/2+1,2)};
                break;
            case 4:
                n=new Box[4]{new Box((int)MainClass.MAXX/2+1,0),new Box((int)MainClass.MAXX/2+1,1),new Box((int)MainClass.MAXX/2+1,2),new Box((int)MainClass.MAXX/2,2)};
                break;
            case 5:
                n=new Box[4]{new Box((int)MainClass.MAXX/2,0),new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2,2),new Box((int)MainClass.MAXX/2,3)};
                break;
            case 6:
                n=new Box[4]{new Box((int)MainClass.MAXX/2,0),new Box((int)MainClass.MAXX/2-1,1),new Box((int)MainClass.MAXX/2,1),new Box((int)MainClass.MAXX/2+1,1)};
                break;
            }
            setArr (n);
        }
        public void rotate ()
        {
            Box tmp;
            Box tmpC;
            rotateAble=false;
            switch(styleId){
            case 1:
                tmpC=arr[1];
                if(rotated==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y+1;
                     
                    rotated=180;
                }else{
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
                    rotated=0;
                }
                break;
            case 2:
 
                tmpC=arr[0];
                if(rotated==0){
                    tmp=arr[1];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    rotated=180;
                }else{
                    tmp=arr[1];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    rotated=0;
                }           break;
            case 3:
                tmpC=arr[1];
                if(rotated==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y+1;
                    rotated=90;
                    //to 90
                }else if(rotated==270){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
                    rotated=0;
                }else if(rotated==90){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y-1;
                    rotated=180;
                }else if(rotated==180){
                    tmp=arr[0];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y-1;
                    rotated=270;
                }
                    break;
            case 4:
                tmpC=arr[1];
                if(rotated==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y-1;
                    rotated=90;
                    //to 90
                }else if(rotated==270){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y+1;
                    rotated=0;
                }else if(rotated==90){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y-1;
                    rotated=180;
                }else if(rotated==180){
                    tmp=arr[0];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
                    rotated=270;
                }
                    break;
            case 5:
                tmpC=arr[1];
                if(rotated==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-2;
                    tmp.Y=tmpC.Y;
                    rotated=180;
                }else{
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+2;
                    rotated=0;
                }
                break;
            case 6:
                tmpC=arr[2];
                if(rotated==0){
                    tmp=arr[1];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    rotated=90;
                    //to 90
                }else if(rotated==270){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[1];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    rotated=0;
                }else if(rotated==90){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[1];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    rotated=180;
                }else if(rotated==180){
                    tmp=arr[0];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[1];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    rotated=270;
                }
                break;
            }
 
            if(is_RotateErr()){
 
                if(styleId==3 || styleId==4){
 
                    rotateByNum(rotated-90);//once that block can not rotate then resume.
                }else{
                    rotate ();
                }
            }
        }
        public void rotateByNum (int rot)
        {
            Box tmp;
            Box tmpC=arr[1];
            if(rot<0){
                rot=270;
            }
            rotated=rot;
            if (styleId == 3) { 
 
                if(rot==90){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y+1;
 
                    //to 90
                }else if(rot==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
 
                }else if(rot==180){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y-1;
                 
                }else if(rot==270){
                    tmp=arr[0];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y-1;
                }
            } else {
                if(rot==90){
                    tmp=arr[0];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y-1;
 
                    //to 90
                }else if(rot==0){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[3];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y+1;
                 
                }else if(rot==180){
                    tmp=arr[0];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y+1;
                    tmp=arr[2];
                    tmp.X=tmpC.X;
                    tmp.Y=tmpC.Y-1;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y-1;
 
                }else if(rot==270){
                    tmp=arr[0];
                    tmp.X=tmpC.X-1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[2];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y;
                    tmp=arr[3];
                    tmp.X=tmpC.X+1;
                    tmp.Y=tmpC.Y+1;
 
                }
            }
        }
        public bool is_RotateErr ()
        {
            bool re=false;
            foreach(Box b in arr){
                if(b.X>=MainClass.MAXX || b.X<0 || b.Y>=MainClass.MAXY || b.Y<0 || MainClass.onPos (b.X,b.Y)){
                    re=true;
                    break;
                }
            }
            return re;
        }
        public void run ()
        {
            tim+=1;
            rotateAble=true;
            if(tim>delay){
                tim=0;
                if(move("D")){
                    MainClass.releaseBlock(this);
                    this.ca_newStyle ();
                }   
                //MainClass.unlockpress();
                screen.update(this);
            }
        }
        public void setArr (Box[] bn)
        {
            tim=0;
            rotated=0;
            rotateAble=true;
            arr=bn;
        }
        public Block (Box[] bn)
        {
            Random rnd=new Random();
            nextStyle=rnd.Next (6);
            delay=25;
            ca_newStyle ();
        }
        public void ca_delay ()
        {
            if (title.piece < 100) {
                delay = 25;
            } else if (title.piece >= 100 && title.piece < 200) {
                delay = 20;
            } else {
                delay=15;
            }
        }
        protected bool can_move (string cmd)
        {
            bool re=true;
            switch (cmd) {
            case"R":
                foreach (Box b in arr) {    
                    if(b.X+1>=MainClass.MAXX || MainClass.onPos(b.X+1,b.Y)){
                        re=false;
                        break;
                    }
                }
                break;
            case"L":
                foreach (Box b in arr ) {
                    if(b.X-1<0 || MainClass.onPos(b.X-1,b.Y)){
                        re=false;
                        break;
                    }
                }
                break;
            case"D":
                foreach (Box b in arr) {
                    if(b.Y+1>=MainClass.MAXY || MainClass.onPos(b.X,b.Y+1)){
                        re=false;
                        break;
                    }
                }
                break;
            }
            return re;
        }
        public bool move (string cmd)
        {
            //return true :create new Style and put data in ArrayList
            bool re = can_move (cmd);
            if (re) {
                switch (cmd) {
                case"R":
                    foreach (Box b in arr) {
                        b.moveR ();
                    }
                    screen.update (this);
                    break;
                case"L":
                    foreach (Box b in arr) {
                        b.moveL ();
                    }
                    screen.update (this);
                    break;
                case"U":
                    foreach (Box b in arr) {
                        b.moveU ();
                    }
                    screen.update (this);
                    break;
                case"D":
                    foreach (Box b in arr) {
                        b.moveD ();
                    }
                    screen.update (this);
                    break;
                case"T":
                    rotate();
                    screen.update (this);
                    break;
                }
            }
            if (!re && cmd == "D") {
                re = true;
            } else {
                re=false;
            }
            return re;
        }
        public bool haveBox (int x, int y)
        {
            bool re=false;
            foreach (Box b in arr) {
                if(b.onpos(x,y)){
                    re=true;
                    break;
                }
            }
            return re;
        }
    }
}
