diff --git a/ConsoleSnake/Program.cs b/ConsoleSnake/Program.cs index 03c1cea..d63397a 100644 --- a/ConsoleSnake/Program.cs +++ b/ConsoleSnake/Program.cs @@ -1,4 +1,6 @@ -namespace ConsoleSnake +using System.ComponentModel.Design; + +namespace ConsoleSnake { internal class Program { @@ -10,24 +12,166 @@ Right } + private struct PlayArea + { + public PlayArea(Int32 left, Int32 top, Int32 right, Int32 bottom) + { + LeftEdge = left; + TopEdge = top; + RightEdge = right; + BottomEdge = bottom; + } + public Int32 LeftEdge { get; set; } + public Int32 TopEdge { get; set; } + public Int32 RightEdge { get; set; } + public Int32 BottomEdge { get; set; } + } + + private struct Position2D + { + public Position2D(Int32 x, Int32 y) { X = x; Y = y; } + public Int32 X { get; set; } + public Int32 Y { get; set; } + } + + private static PlayArea _playArea; private static bool _running = true; + private static bool _growing = false; private static Direction _direction = Direction.Up; + private static List _snakeSegments = new List(); + private static Position2D _food = new Position2D(-1,-1); + private static Random rng = new Random(); static void Main(string[] args) { - Console.SetCursorPosition(Console.WindowWidth/2, Console.WindowHeight/2); - while(_running) + Console.ReadKey(); + Console.WindowWidth -= Console.WindowWidth % 2; + Console.WindowHeight -= Console.WindowHeight % 2; + Console.SetBufferSize(Console.WindowWidth, Console.WindowHeight); + + DrawPlayArea(); + + //Console.WindowWidth -= 1; + Console.ReadKey(true); + Reset(); + + + while (_running) { HandleInput(); - ProcessMovement(); - DrawSnake(); - Thread.Sleep(100); + AllSnakeThings(); + Thread.Sleep(50); } } - private static void DrawSnake() + private static void DrawPlayArea() { + Console.BackgroundColor = ConsoleColor.DarkGray; + for(Int32 top = 0; top < Console.WindowHeight; ++top) + { + Console.CursorTop = top; + Console.CursorLeft = 0; + if (top == 0 || top == Console.WindowHeight - 1) + for (Int32 row = 0; row < Console.WindowWidth; ++row) + Console.Write(' '); + else + { + Console.Write(' '); + Console.CursorLeft = Console.WindowWidth-1; + Console.Write(' '); + } + } + /*for (Int32 top = _playArea.Top; top < _playArea.Height; ++top) + { + + } + for (Int32 left = _playArea.Left; left < _playArea.Width; ++left) + { + Console.SetCursorPosition(left, top); + Console.Write(' '); + }*/ + Console.BackgroundColor = ConsoleColor.Black; + } + private static void Reset() + { + _playArea = new PlayArea(1, 1, Console.WindowWidth - 2, Console.WindowHeight - 2); + _running = true; + _growing = false; + _direction = Direction.Up; + _snakeSegments.Clear(); + + // Set up anew + _snakeSegments.Add(new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2)); + SpawnFood(); + MoveCursor(_snakeSegments.Last()); + + } + + private static void SpawnFood() + { + Position2D oldCursorPos = new Position2D(Console.CursorLeft, Console.CursorTop); + do + { + _food = new Position2D(rng.Next(3, Console.WindowWidth - 10), rng.Next(3, Console.WindowHeight - 3)); + } while (_snakeSegments.Contains(_food)); + MoveCursor(_food); + Console.ForegroundColor = ConsoleColor.Red; + Console.Write('@'); + Console.ForegroundColor = ConsoleColor.Green; + MoveCursor(oldCursorPos); + } + + private static void MoveCursor(Position2D pos) => MoveCursor(pos.X, pos.Y); + private static void MoveCursor(Int32 left, Int32 top) + { + Console.SetCursorPosition(left, top); + Console.CursorVisible = false; + } + + private static void GrowSnake() => GrowSnake(Console.CursorLeft, Console.CursorTop); + private static void GrowSnake(Int32 x, Int32 y) + { + _snakeSegments.Add(new Position2D(x, y)); + } + + private static void DeleteAt(Position2D pos) => DeleteAt(pos.X, pos.Y); + private static void DeleteAt(Int32 x, Int32 y) + { + Int32 curX = Console.CursorLeft; + Int32 curY = Console.CursorTop; + MoveCursor(x, y); + Console.Write(' '); + MoveCursor(curX, curY); + } + + private static bool Collision(Position2D pos1, Position2D pos2) + { + return (pos1.X == pos2.X && pos1.Y == pos2.Y); + } + + private static void AllSnakeThings() + { + if (!_growing) + { + DeleteAt(_snakeSegments.First()); + _snakeSegments.Remove(_snakeSegments.First()); + } + else + _growing = false; + ProcessMovement(); + if (_snakeSegments.Contains(new Position2D(Console.CursorLeft, Console.CursorTop))) + { + _running = false; + return; + } + + GrowSnake(); Console.Write('#'); --Console.CursorLeft; + if(_food.X == Console.CursorLeft && _food.Y == Console.CursorTop) + { + _growing = true; + SpawnFood(); + } } private static void ProcessMovement() @@ -35,16 +179,28 @@ switch (_direction) { case Direction.Up: - --Console.CursorTop; + if (Console.CursorTop - 1 < _playArea.TopEdge) + Console.CursorTop = _playArea.BottomEdge; + else + --Console.CursorTop; break; case Direction.Down: - ++Console.CursorTop; - break; - case Direction.Right: - ++Console.CursorLeft; + if (Console.CursorTop + 1 > _playArea.BottomEdge) + Console.CursorTop = _playArea.TopEdge; + else + ++Console.CursorTop; break; case Direction.Left: - --Console.CursorLeft; + if (Console.CursorLeft - 1 < _playArea.LeftEdge) + Console.CursorLeft = _playArea.RightEdge; + else + --Console.CursorLeft; + break; + case Direction.Right: + if (Console.CursorLeft + 1 > _playArea.RightEdge) + Console.CursorLeft = _playArea.LeftEdge; + else + ++Console.CursorLeft; break; } } @@ -57,23 +213,30 @@ { case ConsoleKey.UpArrow: case ConsoleKey.W: - _direction = Direction.Up; + if(_direction != Direction.Down) + _direction = Direction.Up; break; case ConsoleKey.DownArrow: case ConsoleKey.S: - _direction = Direction.Down; + if (_direction != Direction.Up) + _direction = Direction.Down; break; case ConsoleKey.LeftArrow: case ConsoleKey.A: - _direction = Direction.Left; + if (_direction != Direction.Right) + _direction = Direction.Left; break; case ConsoleKey.RightArrow: case ConsoleKey.D: - _direction = Direction.Right; + if (_direction != Direction.Left) + _direction = Direction.Right; break; case ConsoleKey.Escape: _running = false; break; + case ConsoleKey.G: + _growing = !_growing; + break; } } }