From 362a910573d78eac6e6d9c730d164e31bb8ed90a Mon Sep 17 00:00:00 2001 From: bonchovylkov Date: Fri, 10 Jan 2020 20:51:21 +0200 Subject: [PATCH 1/3] Extract Directions, GameObjects and Positions into separate classes --- .gitignore | 2 ++ Snake/Direction.cs | 16 ++++++++++ Snake/GameObject.cs | 15 +++++++++ Snake/Position.cs | 20 ++++++++++++ Snake/Program.cs | 77 +++++++++++++++++++-------------------------- Snake/Snake.csproj | 3 ++ 6 files changed, 88 insertions(+), 45 deletions(-) create mode 100644 Snake/Direction.cs create mode 100644 Snake/GameObject.cs create mode 100644 Snake/Position.cs diff --git a/.gitignore b/.gitignore index bdc3535..0cc917b 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,8 @@ x64/ *.vssscc .builds +.vs/ + # Visual C++ cache files ipch/ *.aps diff --git a/Snake/Direction.cs b/Snake/Direction.cs new file mode 100644 index 0000000..bf07b3f --- /dev/null +++ b/Snake/Direction.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Snake +{ + public enum Direction + { + Right, + Left, + Down, + Up + } +} diff --git a/Snake/GameObject.cs b/Snake/GameObject.cs new file mode 100644 index 0000000..dd21a31 --- /dev/null +++ b/Snake/GameObject.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Snake +{ + public abstract class GameObject + { + public Position Position { get; set; } + + public char Symbol { get; set; } + } +} diff --git a/Snake/Position.cs b/Snake/Position.cs new file mode 100644 index 0000000..7e55c04 --- /dev/null +++ b/Snake/Position.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Snake +{ + public struct Position + { + public int x; + public int y; + + public Position(int x, int y) + { + this.x = x; + this.y = y; + } + } +} diff --git a/Snake/Program.cs b/Snake/Program.cs index 2849911..efbb852 100644 --- a/Snake/Program.cs +++ b/Snake/Program.cs @@ -7,25 +7,12 @@ namespace Snake { - struct Position - { - public int row; - public int col; - public Position(int row, int col) - { - this.row = row; - this.col = col; - } - } + class Program { static void Main(string[] args) { - byte right = 0; - byte left = 1; - byte down = 2; - byte up = 3; int lastFoodTime = 0; int foodDissapearTime = 8000; int negativePoints = 0; @@ -33,12 +20,12 @@ static void Main(string[] args) Position[] directions = new Position[] { new Position(0, 1), // right - new Position(0, -1), // left - new Position(1, 0), // down - new Position(-1, 0), // up + new Position(0, -1), // Left + new Position(1, 0), // Down + new Position(-1, 0), // Up }; double sleepTime = 100; - int direction = right; + Direction direction = Direction.Right; Random randomNumbersGenerator = new Random(); Console.BufferHeight = Console.WindowHeight; lastFoodTime = Environment.TickCount; @@ -54,7 +41,7 @@ static void Main(string[] args) foreach (Position obstacle in obstacles) { Console.ForegroundColor = ConsoleColor.Cyan; - Console.SetCursorPosition(obstacle.col, obstacle.row); + Console.SetCursorPosition(obstacle.y, obstacle.x); Console.Write("="); } @@ -71,13 +58,13 @@ static void Main(string[] args) randomNumbersGenerator.Next(0, Console.WindowWidth)); } while (snakeElements.Contains(food) || obstacles.Contains(food)); - Console.SetCursorPosition(food.col, food.row); + Console.SetCursorPosition(food.y, food.x); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write("@"); foreach (Position position in snakeElements) { - Console.SetCursorPosition(position.col, position.row); + Console.SetCursorPosition(position.y, position.x); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write("*"); } @@ -91,32 +78,32 @@ static void Main(string[] args) ConsoleKeyInfo userInput = Console.ReadKey(); if (userInput.Key == ConsoleKey.LeftArrow) { - if (direction != right) direction = left; + if (direction != Direction.Right) direction = Direction.Left; } if (userInput.Key == ConsoleKey.RightArrow) { - if (direction != left) direction = right; + if (direction != Direction.Left) direction = Direction.Right; } if (userInput.Key == ConsoleKey.UpArrow) { - if (direction != down) direction = up; + if (direction != Direction.Down) direction = Direction.Up; } if (userInput.Key == ConsoleKey.DownArrow) { - if (direction != up) direction = down; + if (direction != Direction.Up) direction = Direction.Down; } } Position snakeHead = snakeElements.Last(); - Position nextDirection = directions[direction]; + Position nextDirection = directions[(int)direction]; - Position snakeNewHead = new Position(snakeHead.row + nextDirection.row, - snakeHead.col + nextDirection.col); + Position snakeNewHead = new Position(snakeHead.x + nextDirection.x, + snakeHead.y + nextDirection.y); - if (snakeNewHead.col < 0) snakeNewHead.col = Console.WindowWidth - 1; - if (snakeNewHead.row < 0) snakeNewHead.row = Console.WindowHeight - 1; - if (snakeNewHead.row >= Console.WindowHeight) snakeNewHead.row = 0; - if (snakeNewHead.col >= Console.WindowWidth) snakeNewHead.col = 0; + if (snakeNewHead.y < 0) snakeNewHead.y = Console.WindowWidth - 1; + if (snakeNewHead.x < 0) snakeNewHead.x = Console.WindowHeight - 1; + if (snakeNewHead.x >= Console.WindowHeight) snakeNewHead.x = 0; + if (snakeNewHead.y >= Console.WindowWidth) snakeNewHead.y = 0; if (snakeElements.Contains(snakeNewHead) || obstacles.Contains(snakeNewHead)) { @@ -130,20 +117,20 @@ static void Main(string[] args) return; } - Console.SetCursorPosition(snakeHead.col, snakeHead.row); + Console.SetCursorPosition(snakeHead.y, snakeHead.x); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write("*"); snakeElements.Enqueue(snakeNewHead); - Console.SetCursorPosition(snakeNewHead.col, snakeNewHead.row); + Console.SetCursorPosition(snakeNewHead.y, snakeNewHead.x); Console.ForegroundColor = ConsoleColor.Gray; - if (direction == right) Console.Write(">"); - if (direction == left) Console.Write("<"); - if (direction == up) Console.Write("^"); - if (direction == down) Console.Write("v"); + if (direction == Direction.Right) Console.Write(">"); + if (direction == Direction.Left) Console.Write("<"); + if (direction == Direction.Up) Console.Write("^"); + if (direction == Direction.Down) Console.Write("v"); - if (snakeNewHead.col == food.col && snakeNewHead.row == food.row) + if (snakeNewHead.y == food.y && snakeNewHead.x == food.x) { // feeding the snake do @@ -153,7 +140,7 @@ static void Main(string[] args) } while (snakeElements.Contains(food) || obstacles.Contains(food)); lastFoodTime = Environment.TickCount; - Console.SetCursorPosition(food.col, food.row); + Console.SetCursorPosition(food.y, food.x); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write("@"); sleepTime--; @@ -166,9 +153,9 @@ static void Main(string[] args) } while (snakeElements.Contains(obstacle) || obstacles.Contains(obstacle) || - (food.row != obstacle.row && food.col != obstacle.row)); + (food.x != obstacle.x && food.y != obstacle.x)); obstacles.Add(obstacle); - Console.SetCursorPosition(obstacle.col, obstacle.row); + Console.SetCursorPosition(obstacle.y, obstacle.x); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("="); } @@ -176,14 +163,14 @@ static void Main(string[] args) { // moving... Position last = snakeElements.Dequeue(); - Console.SetCursorPosition(last.col, last.row); + Console.SetCursorPosition(last.y, last.x); Console.Write(" "); } if (Environment.TickCount - lastFoodTime >= foodDissapearTime) { negativePoints = negativePoints + 50; - Console.SetCursorPosition(food.col, food.row); + Console.SetCursorPosition(food.y, food.x); Console.Write(" "); do { @@ -194,7 +181,7 @@ static void Main(string[] args) lastFoodTime = Environment.TickCount; } - Console.SetCursorPosition(food.col, food.row); + Console.SetCursorPosition(food.y, food.x); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write("@"); diff --git a/Snake/Snake.csproj b/Snake/Snake.csproj index 4eb74d1..c331cb7 100644 --- a/Snake/Snake.csproj +++ b/Snake/Snake.csproj @@ -41,6 +41,9 @@ + + + From d1300749cf93f64a944bde019b9bd44bda8daf25 Mon Sep 17 00:00:00 2001 From: bonchovylkov Date: Fri, 10 Jan 2020 21:33:54 +0200 Subject: [PATCH 2/3] Extract common logic into functions --- Snake/GameObject.cs | 15 ------ Snake/Program.cs | 114 ++++++++++++++++++++++++++++---------------- Snake/Snake.csproj | 1 - 3 files changed, 74 insertions(+), 56 deletions(-) delete mode 100644 Snake/GameObject.cs diff --git a/Snake/GameObject.cs b/Snake/GameObject.cs deleted file mode 100644 index dd21a31..0000000 --- a/Snake/GameObject.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Snake -{ - public abstract class GameObject - { - public Position Position { get; set; } - - public char Symbol { get; set; } - } -} diff --git a/Snake/Program.cs b/Snake/Program.cs index efbb852..b20e6d8 100644 --- a/Snake/Program.cs +++ b/Snake/Program.cs @@ -11,25 +11,21 @@ namespace Snake class Program { - static void Main(string[] args) - { - int lastFoodTime = 0; - int foodDissapearTime = 8000; - int negativePoints = 0; + const int FOOD_DISAPPEAR_TIME = 8000; - Position[] directions = new Position[] + static ICollection CreatePositions() + { + return new Position[] { new Position(0, 1), // right new Position(0, -1), // Left new Position(1, 0), // Down new Position(-1, 0), // Up }; - double sleepTime = 100; - Direction direction = Direction.Right; - Random randomNumbersGenerator = new Random(); - Console.BufferHeight = Console.WindowHeight; - lastFoodTime = Environment.TickCount; + } + static ICollection CreateObstacles() + { List obstacles = new List() { new Position(12, 12), @@ -38,6 +34,7 @@ static void Main(string[] args) new Position(19, 19), new Position(6, 9), }; + foreach (Position obstacle in obstacles) { Console.ForegroundColor = ConsoleColor.Cyan; @@ -45,28 +42,74 @@ static void Main(string[] args) Console.Write("="); } + return obstacles; + } + + static Queue CreateSnake() + { Queue snakeElements = new Queue(); + for (int i = 0; i <= 5; i++) { snakeElements.Enqueue(new Position(0, i)); } + return snakeElements; + } + + static void AddGameObject(Position position, char symbol, ConsoleColor? color = null) + { + Console.SetCursorPosition(position.y, position.x); + + if (color.HasValue) + { + Console.ForegroundColor = color.Value; + } + + Console.Write(symbol); + } + + static Position CreateRandomPosition() + { + Random randomNumbersGenerator = new Random(); + + var x = randomNumbersGenerator.Next(0, Console.WindowHeight); + var y = randomNumbersGenerator.Next(0, Console.WindowWidth); + + return new Position(x,y); + } + + static void Main(string[] args) + { + int lastFoodTime = 0; + int negativePoints = 0; + + Position[] directions = CreatePositions().ToArray(); + + double sleepTime = 100; + Direction direction = Direction.Right; + + + Console.BufferHeight = Console.WindowHeight; + lastFoodTime = Environment.TickCount; + + List obstacles = CreateObstacles().ToList(); + + Queue snakeElements = CreateSnake(); + Position food; + do { - food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight), - randomNumbersGenerator.Next(0, Console.WindowWidth)); + food = CreateRandomPosition(); } while (snakeElements.Contains(food) || obstacles.Contains(food)); - Console.SetCursorPosition(food.y, food.x); - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write("@"); + + AddGameObject(food, '@', ConsoleColor.Yellow); foreach (Position position in snakeElements) { - Console.SetCursorPosition(position.y, position.x); - Console.ForegroundColor = ConsoleColor.DarkGray; - Console.Write("*"); + AddGameObject(position, '*', ConsoleColor.DarkGray); } while (true) @@ -135,55 +178,46 @@ static void Main(string[] args) // feeding the snake do { - food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight), - randomNumbersGenerator.Next(0, Console.WindowWidth)); + food = CreateRandomPosition(); } while (snakeElements.Contains(food) || obstacles.Contains(food)); lastFoodTime = Environment.TickCount; - Console.SetCursorPosition(food.y, food.x); - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write("@"); + AddGameObject(food, '@', ConsoleColor.Yellow); sleepTime--; Position obstacle = new Position(); do { - obstacle = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight), - randomNumbersGenerator.Next(0, Console.WindowWidth)); + obstacle = CreateRandomPosition(); } while (snakeElements.Contains(obstacle) || obstacles.Contains(obstacle) || (food.x != obstacle.x && food.y != obstacle.x)); obstacles.Add(obstacle); - Console.SetCursorPosition(obstacle.y, obstacle.x); - Console.ForegroundColor = ConsoleColor.Cyan; - Console.Write("="); + + AddGameObject(obstacle, '=', ConsoleColor.Cyan); } else { // moving... - Position last = snakeElements.Dequeue(); - Console.SetCursorPosition(last.y, last.x); - Console.Write(" "); + AddGameObject(snakeElements.Dequeue(), ' '); } - if (Environment.TickCount - lastFoodTime >= foodDissapearTime) + if (Environment.TickCount - lastFoodTime >= FOOD_DISAPPEAR_TIME) { negativePoints = negativePoints + 50; - Console.SetCursorPosition(food.y, food.x); - Console.Write(" "); + AddGameObject(food, ' '); + do { - food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight), - randomNumbersGenerator.Next(0, Console.WindowWidth)); + food = CreateRandomPosition(); } while (snakeElements.Contains(food) || obstacles.Contains(food)); + lastFoodTime = Environment.TickCount; } - Console.SetCursorPosition(food.y, food.x); - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write("@"); + AddGameObject(food, '@', ConsoleColor.Yellow); sleepTime -= 0.01; diff --git a/Snake/Snake.csproj b/Snake/Snake.csproj index c331cb7..f332351 100644 --- a/Snake/Snake.csproj +++ b/Snake/Snake.csproj @@ -42,7 +42,6 @@ - From 102fcbced64313a498a2a64eb116b7385dd73c45 Mon Sep 17 00:00:00 2001 From: bonchovylkov Date: Fri, 10 Jan 2020 21:57:48 +0200 Subject: [PATCH 3/3] Extract Direction setup and not coliding functions --- Snake/Program.cs | 102 ++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/Snake/Program.cs b/Snake/Program.cs index b20e6d8..6679bbc 100644 --- a/Snake/Program.cs +++ b/Snake/Program.cs @@ -79,6 +79,48 @@ static Position CreateRandomPosition() return new Position(x,y); } + static Position CreateNotColidingPosition(Queue snakeElements + , List obstacles) + { + Position gameObject; + + do + { + gameObject = CreateRandomPosition(); + } + while (snakeElements.Contains(gameObject) || obstacles.Contains(gameObject)); + + return gameObject; + } + + static Direction GetDirection(Direction oldDirection) + { + Direction direction = oldDirection; + + if (Console.KeyAvailable) + { + ConsoleKeyInfo userInput = Console.ReadKey(); + if (userInput.Key == ConsoleKey.LeftArrow) + { + if (oldDirection != Direction.Right) direction = Direction.Left; + } + if (userInput.Key == ConsoleKey.RightArrow) + { + if (oldDirection != Direction.Left) direction = Direction.Right; + } + if (userInput.Key == ConsoleKey.UpArrow) + { + if (oldDirection != Direction.Down) direction = Direction.Up; + } + if (userInput.Key == ConsoleKey.DownArrow) + { + if (oldDirection != Direction.Up) direction = Direction.Down; + } + } + + return direction; + } + static void Main(string[] args) { int lastFoodTime = 0; @@ -97,13 +139,7 @@ static void Main(string[] args) Queue snakeElements = CreateSnake(); - Position food; - - do - { - food = CreateRandomPosition(); - } - while (snakeElements.Contains(food) || obstacles.Contains(food)); + Position food = CreateNotColidingPosition(snakeElements, obstacles); AddGameObject(food, '@', ConsoleColor.Yellow); @@ -116,26 +152,7 @@ static void Main(string[] args) { negativePoints++; - if (Console.KeyAvailable) - { - ConsoleKeyInfo userInput = Console.ReadKey(); - if (userInput.Key == ConsoleKey.LeftArrow) - { - if (direction != Direction.Right) direction = Direction.Left; - } - if (userInput.Key == ConsoleKey.RightArrow) - { - if (direction != Direction.Left) direction = Direction.Right; - } - if (userInput.Key == ConsoleKey.UpArrow) - { - if (direction != Direction.Down) direction = Direction.Up; - } - if (userInput.Key == ConsoleKey.DownArrow) - { - if (direction != Direction.Up) direction = Direction.Down; - } - } + direction = GetDirection(direction); Position snakeHead = snakeElements.Last(); Position nextDirection = directions[(int)direction]; @@ -160,32 +177,28 @@ static void Main(string[] args) return; } - Console.SetCursorPosition(snakeHead.y, snakeHead.x); - Console.ForegroundColor = ConsoleColor.DarkGray; - Console.Write("*"); + AddGameObject(snakeHead, '*', ConsoleColor.DarkGray); snakeElements.Enqueue(snakeNewHead); - Console.SetCursorPosition(snakeNewHead.y, snakeNewHead.x); - Console.ForegroundColor = ConsoleColor.Gray; - if (direction == Direction.Right) Console.Write(">"); - if (direction == Direction.Left) Console.Write("<"); - if (direction == Direction.Up) Console.Write("^"); - if (direction == Direction.Down) Console.Write("v"); + char headSymbol = '>'; + if (direction == Direction.Left) headSymbol = '<'; + if (direction == Direction.Up) headSymbol = '^'; + if (direction == Direction.Down) headSymbol = 'v'; + AddGameObject(snakeNewHead, headSymbol, ConsoleColor.Gray); + if (snakeNewHead.y == food.y && snakeNewHead.x == food.x) { // feeding the snake - do - { - food = CreateRandomPosition(); - } - while (snakeElements.Contains(food) || obstacles.Contains(food)); + food = CreateNotColidingPosition(snakeElements, obstacles); + lastFoodTime = Environment.TickCount; AddGameObject(food, '@', ConsoleColor.Yellow); sleepTime--; Position obstacle = new Position(); + do { obstacle = CreateRandomPosition(); @@ -193,6 +206,7 @@ static void Main(string[] args) while (snakeElements.Contains(obstacle) || obstacles.Contains(obstacle) || (food.x != obstacle.x && food.y != obstacle.x)); + obstacles.Add(obstacle); AddGameObject(obstacle, '=', ConsoleColor.Cyan); @@ -208,11 +222,7 @@ static void Main(string[] args) negativePoints = negativePoints + 50; AddGameObject(food, ' '); - do - { - food = CreateRandomPosition(); - } - while (snakeElements.Contains(food) || obstacles.Contains(food)); + food = CreateNotColidingPosition(snakeElements, obstacles); lastFoodTime = Environment.TickCount; }