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;
}
}
}
}
}