diff --git a/MusicBox/MusicBox.csproj b/MusicBox/MusicBox.csproj new file mode 100644 index 0000000..6d25f41 --- /dev/null +++ b/MusicBox/MusicBox.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp1.1 + + + \ No newline at end of file diff --git a/MusicBox/Program.cs b/MusicBox/Program.cs new file mode 100644 index 0000000..1c4a4d1 --- /dev/null +++ b/MusicBox/Program.cs @@ -0,0 +1,130 @@ +using System; +using System.Threading; + +/// +/// By XeeX from https://gist.github.com/XeeX/6220067 +/// +namespace MusicBox +{ + class Program + { + static void Main(string[] args) + { + Console.Beep(658, 125); + Console.Beep(1320, 500); + Console.Beep(990, 250); + Console.Beep(1056, 250); + Console.Beep(1188, 250); + Console.Beep(1320, 125); + Console.Beep(1188, 125); + Console.Beep(1056, 250); + Console.Beep(990, 250); + Console.Beep(880, 500); + Console.Beep(880, 250); + Console.Beep(1056, 250); + Console.Beep(1320, 500); + Console.Beep(1188, 250); + Console.Beep(1056, 250); + Console.Beep(990, 750); + Console.Beep(1056, 250); + Console.Beep(1188, 500); + Console.Beep(1320, 500); + Console.Beep(1056, 500); + Console.Beep(880, 500); + Console.Beep(880, 500); + Thread.Sleep(250); + Console.Beep(1188, 500); + Console.Beep(1408, 250); + Console.Beep(1760, 500); + Console.Beep(1584, 250); + Console.Beep(1408, 250); + Console.Beep(1320, 750); + Console.Beep(1056, 250); + Console.Beep(1320, 500); + Console.Beep(1188, 250); + Console.Beep(1056, 250); + Console.Beep(990, 500); + Console.Beep(990, 250); + Console.Beep(1056, 250); + Console.Beep(1188, 500); + Console.Beep(1320, 500); + Console.Beep(1056, 500); + Console.Beep(880, 500); + Console.Beep(880, 500); + Thread.Sleep(500); + Console.Beep(1320, 500); + Console.Beep(990, 250); + Console.Beep(1056, 250); + Console.Beep(1188, 250); + Console.Beep(1320, 125); + Console.Beep(1188, 125); + Console.Beep(1056, 250); + Console.Beep(990, 250); + Console.Beep(880, 500); + Console.Beep(880, 250); + Console.Beep(1056, 250); + Console.Beep(1320, 500); + Console.Beep(1188, 250); + Console.Beep(1056, 250); + Console.Beep(990, 750); + Console.Beep(1056, 250); + Console.Beep(1188, 500); + Console.Beep(1320, 500); + Console.Beep(1056, 500); + Console.Beep(880, 500); + Console.Beep(880, 500); + Thread.Sleep(250); + Console.Beep(1188, 500); + Console.Beep(1408, 250); + Console.Beep(1760, 500); + Console.Beep(1584, 250); + Console.Beep(1408, 250); + Console.Beep(1320, 750); + Console.Beep(1056, 250); + Console.Beep(1320, 500); + Console.Beep(1188, 250); + Console.Beep(1056, 250); + Console.Beep(990, 500); + Console.Beep(990, 250); + Console.Beep(1056, 250); + Console.Beep(1188, 500); + Console.Beep(1320, 500); + Console.Beep(1056, 500); + Console.Beep(880, 500); + Console.Beep(880, 500); + Thread.Sleep(500); + Console.Beep(660, 1000); + Console.Beep(528, 1000); + Console.Beep(594, 1000); + Console.Beep(495, 1000); + Console.Beep(528, 1000); + Console.Beep(440, 1000); + Console.Beep(419, 1000); + Console.Beep(495, 1000); + Console.Beep(660, 1000); + Console.Beep(528, 1000); + Console.Beep(594, 1000); + Console.Beep(495, 1000); + Console.Beep(528, 500); + Console.Beep(660, 500); + Console.Beep(880, 1000); + Console.Beep(838, 2000); + Console.Beep(660, 1000); + Console.Beep(528, 1000); + Console.Beep(594, 1000); + Console.Beep(495, 1000); + Console.Beep(528, 1000); + Console.Beep(440, 1000); + Console.Beep(419, 1000); + Console.Beep(495, 1000); + Console.Beep(660, 1000); + Console.Beep(528, 1000); + Console.Beep(594, 1000); + Console.Beep(495, 1000); + Console.Beep(528, 500); + Console.Beep(660, 500); + Console.Beep(880, 1000); + Console.Beep(838, 2000); + } + } +} \ No newline at end of file diff --git a/Tetris.Core/Brick.cs b/Tetris.Core/Brick.cs index cda9d75..1dd9067 100644 --- a/Tetris.Core/Brick.cs +++ b/Tetris.Core/Brick.cs @@ -38,5 +38,7 @@ public void Draw(Graphics graphics, int cellWidth, int cellHeight) } public bool Intersect(int x, int y) => x == X && y == Y; + + public override string ToString() => $"X:{X} | Y:{Y}"; } } diff --git a/Tetris.Core/Figures/BaseFigure.cs b/Tetris.Core/Figures/BaseFigure.cs index e46b545..a78ada7 100644 --- a/Tetris.Core/Figures/BaseFigure.cs +++ b/Tetris.Core/Figures/BaseFigure.cs @@ -14,7 +14,7 @@ public abstract class BaseFigure public bool IsActive { get; set; } protected Brick RotationBrick; - + protected List Bricks; public BaseFigure() @@ -24,17 +24,21 @@ public BaseFigure() } public abstract void Rotate(); + public abstract void CounterRotate(); public void Draw(Graphics graphics, int cellWidth, int cellHeight) => Bricks.ForEach(b => b.Draw(graphics, cellWidth, cellHeight)); - public void SetRelativePosition(int x, int y) => + public void Move(int x, int y) + { Bricks.ForEach(b => b.SetRelativePosition(x, y)); - public virtual bool Intersect(int x, int y) => !Bricks.TrueForAll(b => !b.Intersect(x, y)); - public virtual bool Intersect(Brick brick) => !Bricks.TrueForAll(b => !b.Intersect(brick.X, brick.Y)); + } + + public virtual bool Intersect(int x, int y) => Bricks.Any(b => b.Intersect(x, y)); + public virtual bool Intersect(Brick brick) => Bricks.Any(b => b.Intersect(brick.X, brick.Y)); - public virtual bool Intersect(BaseFigure figure) => !figure.Bricks.TrueForAll(b => !Intersect(b)); + public virtual bool Intersect(BaseFigure figure) => figure.Bricks.Any(b => Intersect(b)); } } \ No newline at end of file diff --git a/Tetris.Core/Figures/Border.cs b/Tetris.Core/Figures/Border.cs index 772c830..2bc762c 100644 --- a/Tetris.Core/Figures/Border.cs +++ b/Tetris.Core/Figures/Border.cs @@ -20,6 +20,9 @@ public Border(int x, int y, int width, int height) public override void Rotate() { } + + public override void CounterRotate() => Rotate(); + public new void Draw(Graphics graphics, int cellWidth, int cellHeight) { diff --git a/Tetris.Core/Figures/Square.cs b/Tetris.Core/Figures/Square.cs new file mode 100644 index 0000000..3832a36 --- /dev/null +++ b/Tetris.Core/Figures/Square.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tetris.Core.Figures +{ + public class Square : BaseFigure + { + public Square() + { + for (int i = 0; i < 2; i++) + for (int o = 0; o < 2; o++) + Bricks.Add(new Brick { X = o, Y = i }); + } + + public override void Rotate() + { + } + public override void CounterRotate() => Rotate(); + + } +} diff --git a/Tetris.Core/Figures/Stab.cs b/Tetris.Core/Figures/Stab.cs index ff91f45..134cbb7 100644 --- a/Tetris.Core/Figures/Stab.cs +++ b/Tetris.Core/Figures/Stab.cs @@ -38,5 +38,7 @@ public override void Rotate() } } } + public override void CounterRotate() => Rotate(); + } } diff --git a/Tetris.Core/Figures/Tee.cs b/Tetris.Core/Figures/Tee.cs new file mode 100644 index 0000000..5f1cc82 --- /dev/null +++ b/Tetris.Core/Figures/Tee.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tetris.Core.Figures +{ + public class Tee : BaseFigure + { + public Brick this[int x, int y] + { + get + { + var originX = RotationBrick.X - 1; + var originY = RotationBrick.Y - 1; + + return Bricks.FirstOrDefault(o => o.X == x + originX && o.Y == y + originY); + } + } + Brick a; + Brick b; + Brick c; + Brick d; + + public Tee() + { + var rotBrick = new Brick { X = 1, Y = 1 }; + + var b = new List { + new Brick { X = 0, Y = 1 }, + new Brick { X = 2, Y = 1 }, + new Brick { X = 1, Y = 0 }, + rotBrick, }; + Bricks.AddRange(b); + RotationBrick = rotBrick; + + } + + public override void Rotate() + { + /* + [0,1] (x+1 y+1)=> [1,2] + [1,0] (x-1 y+1)=> [0,1] + [2,1] (x-1 y-1)=> [1,0] + [1,2] (x+1 y-1)=> [2,1] + */ + a = this[0, 1]; + b = this[1, 0]; + c = this[2, 1]; + d = this[1, 2]; + if (a != null) + a.SetRelativePosition(1, 1); + if (b != null) + b.SetRelativePosition(-1, 1); + if (c != null) + c.SetRelativePosition(-1, -1); + if (d != null) + d.SetRelativePosition(1, -1); + } + + public override void CounterRotate() + { + for (int i = 0; i < 3; i++) + Rotate(); + } + + } +} diff --git a/Tetris.Core/Game.cs b/Tetris.Core/Game.cs index 77c88c0..45c9556 100644 --- a/Tetris.Core/Game.cs +++ b/Tetris.Core/Game.cs @@ -20,6 +20,7 @@ public class Game public int CellHeight { get; set; } public BaseFigure CurrentFigure { get; set; } public List AllFigures { get; set; } + public List BlockTypes { get; set; } /// /// Used for Input. Check if Key is pressed @@ -27,10 +28,11 @@ public class Game Dictionary> KeyDictionary; System.Timers.Timer timer; - Stab stab; + BaseFigure stab; Border bottom; Border left; Border right; + Random random; ulong frames = 0; @@ -47,12 +49,14 @@ public Game(int width, int height) [Keys.Up] = new KeyValuePair(false, 0) }; - stab = new Stab(); + stab = new Tee(); CurrentFigure = stab; left = new Border(-1, 0, 1, Height); right = new Border(Width, 0, 1, Height); bottom = new Border(0, Height, Width, 1); AllFigures = new List { stab, bottom, left, right }; + BlockTypes = new List {typeof(Square), typeof(Stab), typeof(Tee) }; + random = new Random(); timer = new System.Timers.Timer() { @@ -68,58 +72,37 @@ private void Timer_Elapsed(object sender, ElapsedEventArgs e) { frames++; - //KeyDictionary.Where( - // x => x.Key == Keys.Right || x.Key == Keys.Left).Where( - // x => x.Value.Key).Select( - // x => x.Value.Value).ToList().ForEach( - // x => CurrentFigure.SetRelativePosition( - // x > 0 ? - // CurrentFigure.Intersect(right) ? 0 : 1 :// stab.X + stab.Width + 1 > Width ? 0 : x : - // CurrentFigure.Intersect(left) ? 0 : -1, 0)); - - if (KeyDictionary[Keys.Down].Key) - if (!CurrentFigure.Intersect(bottom)) - CurrentFigure.SetRelativePosition(0, 1); - if (frames % 4 == 0) { if (KeyDictionary[Keys.Up].Key) { KeyDictionary[Keys.Up] = new KeyValuePair(false, 0); - CurrentFigure.Rotate(); + TryRotate(CurrentFigure); } } - if (frames % 10 == 0) - CurrentFigure.SetRelativePosition(0, 1); + KeyDictionary.Where( + x => x.Key == Keys.Right || x.Key == Keys.Left).Where( + x => x.Value.Key).Select( + x => x.Value.Value).ToList().ForEach( + x => TryMove( + x < 0 ? -1 : 1, 0, CurrentFigure)); - bool intersect = false; - foreach (var item in AllFigures.Where(x => x != CurrentFigure)) - { - if (intersect) - continue; - intersect = CurrentFigure.Intersect(item); - } - if(!intersect) - KeyDictionary.Where( - x => x.Key == Keys.Right || x.Key == Keys.Left).Where( - x => x.Value.Key).Select( - x => x.Value.Value).ToList().ForEach( - x => CurrentFigure.SetRelativePosition( - x > 0 ? intersect ? -1 : 1 : intersect ? 1 : -1, 0)); - - while (CurrentFigure.Intersect(bottom)) - { - CurrentFigure.SetRelativePosition(0, -1); - CurrentFigure.IsActive = false; - CurrentFigure = new Stab(); - AllFigures.Add(CurrentFigure); - } + if (KeyDictionary[Keys.Down].Key || frames % 10 == 0) + if (!TryMove(0, 1, CurrentFigure)) + { + CurrentFigure.IsActive = false; + CurrentFigure = (BaseFigure)Activator.CreateInstance(BlockTypes[random.Next(0, BlockTypes.Count)]); + if(Collision(CurrentFigure)) + AllFigures.RemoveAll(x=> !(x is Border)); + AllFigures.Add(CurrentFigure); + } } public void OnDraw(Graphics graphics) { - AllFigures.ForEach(f => { + AllFigures.ForEach(f => + { if (!(f is Border)) f.Draw(graphics, CellWidth, CellHeight); }); @@ -132,5 +115,29 @@ public void MoveBrick(KeyEventArgs keyEventArgs, bool keyUp) if (KeyDictionary.TryGetValue(keyEventArgs.KeyCode, out var val)) KeyDictionary[keyEventArgs.KeyCode] = new KeyValuePair(keyUp, val.Value); } + + public bool Collision(BaseFigure figure) => AllFigures.Where(f => f != CurrentFigure).Any(b => CurrentFigure.Intersect(b)); + + public bool TryMove(int x, int y, BaseFigure figure) + { + figure.Move(x, y); + + if (!Collision(figure)) + return true; + + figure.Move(-x, -y); + return false; + } + + public bool TryRotate(BaseFigure figure) + { + figure.Rotate(); + + if (!Collision(figure)) + return true; + + figure.CounterRotate(); + return false; + } } } diff --git a/Tetris.Core/Tetris.Core.csproj b/Tetris.Core/Tetris.Core.csproj index acd8b59..994e691 100644 --- a/Tetris.Core/Tetris.Core.csproj +++ b/Tetris.Core/Tetris.Core.csproj @@ -46,6 +46,8 @@ + + diff --git a/Tetris.sln b/Tetris.sln index 3cd0217..aa0edfc 100644 --- a/Tetris.sln +++ b/Tetris.sln @@ -1,12 +1,14 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.14 +VisualStudioVersion = 15.0.26430.16 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tetris", "Tetris\Tetris.csproj", "{8AC7C5FD-F8BE-43CE-9AE7-CA7379CE7D1E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tetris.Core", "Tetris.Core\Tetris.Core.csproj", "{B8D0EDBD-D20C-4137-974F-D04E895C8FE3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MusicBox", "MusicBox\MusicBox.csproj", "{3046371D-BA49-405A-BF4D-75A5A0DC9F7A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {B8D0EDBD-D20C-4137-974F-D04E895C8FE3}.Debug|Any CPU.Build.0 = Debug|Any CPU {B8D0EDBD-D20C-4137-974F-D04E895C8FE3}.Release|Any CPU.ActiveCfg = Release|Any CPU {B8D0EDBD-D20C-4137-974F-D04E895C8FE3}.Release|Any CPU.Build.0 = Release|Any CPU + {3046371D-BA49-405A-BF4D-75A5A0DC9F7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3046371D-BA49-405A-BF4D-75A5A0DC9F7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3046371D-BA49-405A-BF4D-75A5A0DC9F7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3046371D-BA49-405A-BF4D-75A5A0DC9F7A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE