分类:Application

[C#]俄罗斯方块

[C#]俄罗斯方块

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RussianBlock
{
    class Program
    {
        static int[,] Squre = new int[22, 12];
        static Random R = new Random();
        static int CurrBlockType;
        static int CurrBlockStat;
        static object[] ObjGenData;
        static void Main(string[] args)
        {
            for (int i = 0; i < 22; i++)
            {
                Squre[i, 0] = -1;
                Squre[i, 11] = -1;
            }
            for (int i = 0; i < 12; i++)
            {
                Squre[0, i] = -1;
                Squre[21, i] = -1;
            }
            for (int iii=0;;iii++)
            {
                ObjGenData = GenBlock();
                int[] X = (int[])ObjGenData[0];
                int[] Y = (int[])ObjGenData[1];
                for (int i = 0; i < X.Length; i++)
                {
                    Squre[Y[i] + 1, X[i] + 1] = 1;
                }
                Console.Clear();
                for (int i = 1; i < 21; i++)
                {
                    for (int j = 1; j < 11; j++)
                    {
                        Console.Write(Squre[i, j] == 1 ? "■" : "  ");
                    }
                    Console.WriteLine();
                }
                Console.WriteLine("□□□□□□□□□□");
                while (Drop())
                {
                    if (Console.KeyAvailable)
                    {
                        ConsoleKeyInfo Cki = Console.ReadKey(true);
                        if (Cki.Key == ConsoleKey.LeftArrow) LeftMove();
                        if (Cki.Key == ConsoleKey.RightArrow) RightMove();
                        if (Cki.Key == ConsoleKey.UpArrow) Reverse();
                        if (Cki.Key == ConsoleKey.DownArrow) continue;
                        
                    }
                    Thread.Sleep(500);
                    Console.Clear();
                    for (int i = 1; i < 21; i++)
                    {
                        for (int j = 1; j < 11; j++)
                        {
                            Console.Write(Squre[i, j] == 1 ? "■" : "  ");
                        }
                        Console.WriteLine();
                    }
                    Console.WriteLine("□□□□□□□□□□");
                }
                Console.WriteLine();
                if (CheckFail()) { Console.WriteLine("Fail {0}",iii); break; }
                DoClear();


            }
            Console.ReadKey();
        }

        static bool CheckFail()
        {
            //If the top line of squre is filled then fail
            bool Flag = false;
            for (int j = 1; j < 11; j++)
            {
                if (Squre[1, j] == 1) Flag = true;
            }
            return Flag;
        }

        static bool RightMove()
        {
            int[] X = (int[])ObjGenData[0];
            int[] Y = (int[])ObjGenData[1];
            //Thread.Sleep(1000);
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                if (Squre[Y[i] + 1, X[i] + 2] == 1 || Squre[Y[i] + 1, X[i] + 2] == -1)
                {
                    for (int j = 0; j < X.Length; j++)
                    {
                        Squre[Y[j] + 1, X[j] + 1] = 1;
                    }
                    return false;
                }
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                X[i]++;
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 1;
            }
            return true;
        }
        static bool LeftMove()
        {
            int[] X = (int[])ObjGenData[0];
            int[] Y = (int[])ObjGenData[1];
            //Thread.Sleep(1000);
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                if (Squre[Y[i] + 1, X[i]] == 1 || Squre[Y[i] + 1, X[i]] == -1)
                {
                    for (int j = 0; j < X.Length; j++)
                    {
                        Squre[Y[j] + 1, X[j] + 1] = 1;
                    }
                    return false;
                }
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                X[i]--;
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 1;
            }
            return true;
        }
        static bool Drop()
        {
            int[] X = (int[])ObjGenData[0];
            int[] Y = (int[])ObjGenData[1];
            //Thread.Sleep(1000);
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                if (Squre[Y[i] + 2, X[i] + 1] == 1 || Squre[Y[i] + 2, X[i] + 1] == -1)
                {
                    for (int j = 0; j < X.Length; j++)
                    {
                        Squre[Y[j] + 1, X[j] + 1] = 1;
                    }
                    return false;
                } 
            }
            for (int i=0;i<X.Length;i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                Y[i]++;
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 1;
            }
            return true;
        }

        static bool Reverse()
        {
            int[] X = (int[])ObjGenData[0];
            int[] Y = (int[])ObjGenData[1];
            //Thread.Sleep(1000);
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            int[] NextX = new int[4], NextY = new int[4], PrevX = new int[4], PrevY = new int[4];
            switch (CurrBlockType)
            {
                case 0://Type: T
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockAXS2; NextY = BlockAYS2; PrevX = BlockAXS1; PrevY = BlockAYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockAXS3; NextY = BlockAYS3; PrevX = BlockAXS2; PrevY = BlockAYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockAXS4; NextY = BlockAYS4; PrevX = BlockAXS3; PrevY = BlockAYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockAXS1; NextY = BlockAYS1; PrevX = BlockAXS4; PrevY = BlockAYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 1://Type: L
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockBXS2; NextY = BlockBYS2; PrevX = BlockBXS1; PrevY = BlockBYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockBXS3; NextY = BlockBYS3; PrevX = BlockBXS2; PrevY = BlockBYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockBXS4; NextY = BlockBYS4; PrevX = BlockBXS3; PrevY = BlockBYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockBXS1; NextY = BlockBYS1; PrevX = BlockBXS4; PrevY = BlockBYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 2://Type: Reverse L
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockCXS2; NextY = BlockCYS2; PrevX = BlockCXS1; PrevY = BlockCYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockCXS3; NextY = BlockCYS3; PrevX = BlockCXS2; PrevY = BlockCYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockCXS4; NextY = BlockCYS4; PrevX = BlockCXS3; PrevY = BlockCYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockCXS1; NextY = BlockCYS1; PrevX = BlockCXS4; PrevY = BlockCYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 3://Type: -
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockDXS2; NextY = BlockDYS2; PrevX = BlockDXS1; PrevY = BlockDYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockDXS3; NextY = BlockDYS3; PrevX = BlockDXS2; PrevY = BlockDYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockDXS4; NextY = BlockDYS4; PrevX = BlockDXS3; PrevY = BlockDYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockDXS1; NextY = BlockDYS1; PrevX = BlockDXS4; PrevY = BlockDYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 4://Type: Block
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockEXS2; NextY = BlockEYS2; PrevX = BlockEXS1; PrevY = BlockEYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockEXS3; NextY = BlockEYS3; PrevX = BlockEXS2; PrevY = BlockEYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockEXS4; NextY = BlockEYS4; PrevX = BlockEXS3; PrevY = BlockEYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockEXS1; NextY = BlockEYS1; PrevX = BlockEXS4; PrevY = BlockEYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 5://Type: Z
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockFXS2; NextY = BlockFYS2; PrevX = BlockFXS1; PrevY = BlockFYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockFXS3; NextY = BlockFYS3; PrevX = BlockFXS2; PrevY = BlockFYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockFXS4; NextY = BlockFYS4; PrevX = BlockFXS3; PrevY = BlockFYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockFXS1; NextY = BlockFYS1; PrevX = BlockFXS4; PrevY = BlockFYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
                case 6://Type: Reverse Z
                    {
                        switch (CurrBlockStat)
                        {
                            case 0: NextX = BlockGXS2; NextY = BlockGYS2; PrevX = BlockGXS1; PrevY = BlockGYS1; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 1: NextX = BlockGXS3; NextY = BlockGYS3; PrevX = BlockGXS2; PrevY = BlockGYS2; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 2: NextX = BlockGXS4; NextY = BlockGYS4; PrevX = BlockGXS3; PrevY = BlockGYS3; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                            case 3: NextX = BlockGXS1; NextY = BlockGYS1; PrevX = BlockGXS4; PrevY = BlockGYS4; CurrBlockStat = (CurrBlockStat + 1) % 4; break;
                        }
                    };
                    break;
            }
            for (int i = 0; i < X.Length; i++)
            {
                if (Squre[Y[i] + 1 - PrevY[i] + NextY[i], X[i] + 1 - PrevX[i] + NextX[i]] == 1 || Squre[Y[i] + 1 - PrevY[i] + NextY[i], X[i] + 1 - PrevX[i] + NextX[i]] == -1)
                {
                    for (int j = 0; j < X.Length; j++)
                    {
                        Squre[Y[j] + 1, X[j] + 1] = 1;
                    }
                    return false;
                }
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 0;
            }
            for (int i = 0; i < X.Length; i++)
            {
                X[i] = X[i] - PrevX[i] + NextX[i];
                Y[i] = Y[i] - PrevY[i] + NextY[i];
            }
            for (int i = 0; i < X.Length; i++)
            {
                Squre[Y[i] + 1, X[i] + 1] = 1;
            }
            return true;
        }

        //Type: T
        static int[] BlockAXS1 = new int[] { 1, 0, 1, 2 };
        static int[] BlockAYS1 = new int[] { 0, 1, 1, 1 };

        static int[] BlockAXS2 = new int[] { 1, 0, 1, 1 };
        static int[] BlockAYS2 = new int[] { 0, 1, 1, 2 };

        static int[] BlockAXS3 = new int[] { 0, 1, 2, 1 };
        static int[] BlockAYS3 = new int[] { 0, 0, 0, 1 };

        static int[] BlockAXS4 = new int[] { 0, 0, 1, 0 };
        static int[] BlockAYS4 = new int[] { 0, 1, 1, 2 };

        //Type: L
        static int[] BlockBXS1 = new int[] { 0, 0, 0, 1 };
        static int[] BlockBYS1 = new int[] { 0, 1, 2, 2 };

        static int[] BlockBXS2 = new int[] { 2, 0, 1, 2 };
        static int[] BlockBYS2 = new int[] { 0, 1, 1, 1 };

        static int[] BlockBXS3 = new int[] { 0, 1, 1, 1 };
        static int[] BlockBYS3 = new int[] { 0, 0, 1, 2 };

        static int[] BlockBXS4 = new int[] { 0, 1, 2, 0 };
        static int[] BlockBYS4 = new int[] { 0, 0, 0, 1 };

        //Type: Reverse L
        static int[] BlockCXS1 = new int[] { 1, 1, 0, 1 };
        static int[] BlockCYS1 = new int[] { 0, 1, 2, 2 };

        static int[] BlockCXS2 = new int[] { 0, 1, 2, 2 };
        static int[] BlockCYS2 = new int[] { 0, 0, 0, 1 };

        static int[] BlockCXS3 = new int[] { 0, 1, 0, 0 };
        static int[] BlockCYS3 = new int[] { 0, 0, 1, 2 };

        static int[] BlockCXS4 = new int[] { 0, 0, 1, 2 };
        static int[] BlockCYS4 = new int[] { 0, 1, 1, 1 };

        //Type: -
        static int[] BlockDXS1 = new int[] { 0, 1, 2, 3 };
        static int[] BlockDYS1 = new int[] { 0, 0, 0, 0 };

        static int[] BlockDXS2 = new int[] { 0, 0, 0, 0 };
        static int[] BlockDYS2 = new int[] { 0, 1, 2, 3 };

        static int[] BlockDXS3 = new int[] { 0, 1, 2, 3 };
        static int[] BlockDYS3 = new int[] { 0, 0, 0, 0 };

        static int[] BlockDXS4 = new int[] { 0, 0, 0, 0 };
        static int[] BlockDYS4 = new int[] { 0, 1, 2, 3 };

        //Type: Block
        static int[] BlockEXS1 = new int[] { 0, 1, 0, 1 };
        static int[] BlockEYS1 = new int[] { 0, 0, 1, 1 };

        static int[] BlockEXS2 = new int[] { 0, 1, 0, 1 };
        static int[] BlockEYS2 = new int[] { 0, 0, 1, 1 };

        static int[] BlockEXS3 = new int[] { 0, 1, 0, 1 };
        static int[] BlockEYS3 = new int[] { 0, 0, 1, 1 };

        static int[] BlockEXS4 = new int[] { 0, 1, 0, 1 };
        static int[] BlockEYS4 = new int[] { 0, 0, 1, 1 };

        //Type: Z
        static int[] BlockFXS1 = new int[] { 0, 1, 1, 2 };
        static int[] BlockFYS1 = new int[] { 0, 0, 1, 1 };

        static int[] BlockFXS2 = new int[] { 1, 0, 1, 0 };
        static int[] BlockFYS2 = new int[] { 0, 1, 1, 2 };

        static int[] BlockFXS3 = new int[] { 0, 1, 1, 2 };
        static int[] BlockFYS3 = new int[] { 0, 0, 1, 1 };

        static int[] BlockFXS4 = new int[] { 1, 0, 1, 0 };
        static int[] BlockFYS4 = new int[] { 0, 1, 1, 2 };

        //Type: Reverse Z
        static int[] BlockGXS1 = new int[] { 1, 2, 0, 1 };
        static int[] BlockGYS1 = new int[] { 0, 0, 1, 1 };

        static int[] BlockGXS2 = new int[] { 0, 0, 1, 1 };
        static int[] BlockGYS2 = new int[] { 0, 1, 1, 2 };

        static int[] BlockGXS3 = new int[] { 1, 2, 0, 1 };
        static int[] BlockGYS3 = new int[] { 0, 0, 1, 1 };

        static int[] BlockGXS4 = new int[] { 0, 0, 1, 1 };
        static int[] BlockGYS4 = new int[] { 0, 1, 1, 2 };

        static object[] GenBlock()
        {
            //Using Example
            //ObjGenData = GenBlock();
            //int[] X = (int[])ObjGenData[0];
            //int[] Y = (int[])ObjGenData[1];
            object[] Res = new object[2];
            //Type: T
            int[] BlockAX = new int[] { 1, 0, 1, 2 };
            int[] BlockAY = new int[] { 0, 1, 1, 1 };
            //Type: L
            int[] BlockBX = new int[] { 0, 0, 0, 1 };
            int[] BlockBY = new int[] { 0, 1, 2, 2 };
            //Type: Reverse L
            int[] BlockCX = new int[] { 1, 1, 0, 1 };
            int[] BlockCY = new int[] { 0, 1, 2, 2 };
            //Type: -
            int[] BlockDX = new int[] { 0, 1, 2, 3 };
            int[] BlockDY = new int[] { 0, 0, 0, 0 };
            //Type: Block
            int[] BlockEX = new int[] { 0, 1, 0, 1 };
            int[] BlockEY = new int[] { 0, 0, 1, 1 };
            //Type: Z
            int[] BlockFX = new int[] { 0, 1, 1, 2 };
            int[] BlockFY = new int[] { 0, 0, 1, 1 };
            //Type: Reverse Z
            int[] BlockGX = new int[] { 1, 2, 0, 1 };
            int[] BlockGY = new int[] { 0, 0, 1, 1 };

            int Type = R.Next() % 7;
            switch (Type)
            {
                case 0: Res[0] = BlockAX; Res[1] = BlockAY; CurrBlockType = 0; return Res;
                case 1: Res[0] = BlockBX; Res[1] = BlockBY; CurrBlockType = 1; return Res;
                case 2: Res[0] = BlockCX; Res[1] = BlockCY; CurrBlockType = 2; return Res;
                case 3: Res[0] = BlockDX; Res[1] = BlockDY; CurrBlockType = 3; return Res;
                case 4: Res[0] = BlockEX; Res[1] = BlockEY; CurrBlockType = 4; return Res;
                case 5: Res[0] = BlockFX; Res[1] = BlockFY; CurrBlockType = 5; return Res;
                case 6: Res[0] = BlockGX; Res[1] = BlockGY; CurrBlockType = 6; return Res;
            }
            CurrBlockStat = 0;
            throw (new Exception("Generater Error"));
        }
        static void DoClear()
        {
            //Use to Clear the Full Lines
            for (int i = 0; i < 20; i++)
            {
                bool Flag = false;
                for (int j = 0; j < 10; j++)
                {
                    if (Squre[i + 1, j + 1] == 0) Flag = true;
                }
                if (Flag) continue;

                for (int j = i + 1; j > 1; j--)
                {
                    for (int k = 0; k < 10; k++)
                    {
                        Squre[j, k + 1] = Squre[j - 1, k + 1];
                    }
                }
                for (int k = 0; k < 10; k++)
                {
                    Squre[1, k + 1] = 0;
                }
            }
        }
    }
}