Somewhat major refactor
Snake is now a class, this marks the start of OOPing this thing Snakes are now an array, making for much sleeker code Optimized AllSnakeThings, at the cost of debug features like grow-on-key-stroke
This commit is contained in:
parent
0f752bdb1c
commit
f5f846d995
@ -35,13 +35,13 @@ namespace ConsoleSnake
|
|||||||
public Int32 Y { get; set; }
|
public Int32 Y { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct Snake
|
private class Snake
|
||||||
{
|
{
|
||||||
public bool Alive = true;
|
public bool Alive = true;
|
||||||
public Direction Direction { get; set; } = Direction.Down;
|
public Direction Direction { get; set; } = Direction.Down;
|
||||||
|
public ConsoleColor Color { get; set; } = ConsoleColor.Green;
|
||||||
public Position2D HeadPosition { get; set; } = new Position2D();
|
public Position2D HeadPosition { get; set; } = new Position2D();
|
||||||
public List<Position2D> Segments { get; set; } = new List<Position2D>();
|
public List<Position2D> Segments { get; set; } = new List<Position2D>();
|
||||||
public bool Growing { get; set; } = false;
|
|
||||||
|
|
||||||
public Snake()
|
public Snake()
|
||||||
{
|
{
|
||||||
@ -50,8 +50,10 @@ namespace ConsoleSnake
|
|||||||
|
|
||||||
private static PlayArea _playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
|
private static PlayArea _playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
|
||||||
private static bool _running = true;
|
private static bool _running = true;
|
||||||
private static Snake _snakeP1 = new Snake();
|
private static Snake[] _snakes = {
|
||||||
private static Snake _snakeP2 = new Snake();
|
new Snake(),
|
||||||
|
new Snake()
|
||||||
|
};
|
||||||
private static Position2D _food = new Position2D(-1,-1);
|
private static Position2D _food = new Position2D(-1,-1);
|
||||||
private static Random rng = new Random();
|
private static Random rng = new Random();
|
||||||
private static Int32 _desiredFrameTime = 75;
|
private static Int32 _desiredFrameTime = 75;
|
||||||
@ -59,8 +61,6 @@ namespace ConsoleSnake
|
|||||||
private static DateTime _frameTiming = DateTime.Now;
|
private static DateTime _frameTiming = DateTime.Now;
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
String blub = null;
|
|
||||||
WriteColAt(blub, ConsoleColor.DarkBlue, 0, 0);
|
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
|
|
||||||
Console.SetBufferSize(Console.WindowWidth, Console.WindowHeight);
|
Console.SetBufferSize(Console.WindowWidth, Console.WindowHeight);
|
||||||
@ -115,22 +115,23 @@ namespace ConsoleSnake
|
|||||||
{
|
{
|
||||||
_playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
|
_playArea = new PlayArea(1, 4, Console.WindowWidth - 2, Console.WindowHeight - 2);
|
||||||
_running = true;
|
_running = true;
|
||||||
_snakeP1.Growing = false;
|
|
||||||
_snakeP2.Growing = false;
|
_snakes[0].Direction = Direction.Right;
|
||||||
_snakeP1.Direction = Direction.Right;
|
_snakes[1].Direction = Direction.Left;
|
||||||
_snakeP2.Direction = Direction.Left;
|
_snakes[0].Color = ConsoleColor.Green;
|
||||||
_snakeP1.Segments.Clear();
|
_snakes[1].Color = ConsoleColor.Cyan;
|
||||||
_snakeP2.Segments.Clear();
|
_snakes[0].Segments.Clear();
|
||||||
|
_snakes[1].Segments.Clear();
|
||||||
|
|
||||||
// Set up anew
|
// Set up anew
|
||||||
_snakeP1.Segments.Add(_snakeP1.HeadPosition = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2));
|
_snakes[0].Segments.Add(_snakes[0].HeadPosition = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2));
|
||||||
_snakeP2.Segments.Add(_snakeP2.HeadPosition = new Position2D(Console.BufferWidth / 2 - 1, Console.BufferHeight / 2));
|
_snakes[1].Segments.Add(_snakes[1].HeadPosition = new Position2D(Console.BufferWidth / 2 - 1, Console.BufferHeight / 2));
|
||||||
SpawnFood();
|
SpawnFood();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool SnakeCollision(Position2D position)
|
private static bool SnakeCollision(Position2D position)
|
||||||
{
|
{
|
||||||
return _snakeP1.Segments.Contains(position) || _snakeP2.Segments.Contains(position);
|
return _snakes[0].Segments.Contains(position) || _snakes[1].Segments.Contains(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SpawnFood()
|
private static void SpawnFood()
|
||||||
@ -159,18 +160,10 @@ namespace ConsoleSnake
|
|||||||
Console.SetCursorPosition(left, top);
|
Console.SetCursorPosition(left, top);
|
||||||
Console.CursorVisible = false;
|
Console.CursorVisible = false;
|
||||||
}
|
}
|
||||||
private static void GrowSnakes()
|
private static void GrowSnake(Snake snake)
|
||||||
{
|
{
|
||||||
if (_snakeP1.Alive)
|
snake.Segments.Add(snake.HeadPosition);
|
||||||
{
|
WriteColAt('#', snake.Color, snake.HeadPosition);
|
||||||
_snakeP1.Segments.Add(_snakeP1.HeadPosition);
|
|
||||||
WriteColAt('#', ConsoleColor.Green, _snakeP1.HeadPosition);
|
|
||||||
}
|
|
||||||
if (_snakeP2.Alive)
|
|
||||||
{
|
|
||||||
_snakeP2.Segments.Add(_snakeP2.HeadPosition);
|
|
||||||
WriteColAt('#', ConsoleColor.Cyan, _snakeP2.HeadPosition);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DeleteAt(Position2D pos) => DeleteAt(pos.X, pos.Y);
|
private static void DeleteAt(Position2D pos) => DeleteAt(pos.X, pos.Y);
|
||||||
@ -185,125 +178,87 @@ namespace ConsoleSnake
|
|||||||
return (pos1.X == pos2.X && pos1.Y == pos2.Y);
|
return (pos1.X == pos2.X && pos1.Y == pos2.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void KillSnake(Snake snake)
|
||||||
|
{
|
||||||
|
foreach (Position2D segment in snake.Segments)
|
||||||
|
DeleteAt(segment);
|
||||||
|
snake.Segments.Clear();
|
||||||
|
snake.HeadPosition = new Position2D(-1, -1);
|
||||||
|
snake.Alive = false;
|
||||||
|
}
|
||||||
|
|
||||||
private static void AllSnakeThings()
|
private static void AllSnakeThings()
|
||||||
{
|
{
|
||||||
|
|
||||||
ProcessMovement();
|
ProcessMovement();
|
||||||
|
|
||||||
// P1 pepsi?
|
foreach (Snake snake in _snakes)
|
||||||
if (_snakeP1.Segments.Contains(_snakeP1.HeadPosition) || _snakeP2.Segments.Contains(_snakeP1.HeadPosition))
|
|
||||||
{
|
{
|
||||||
foreach(Position2D segment in _snakeP1.Segments)
|
if (snake.Alive)
|
||||||
DeleteAt(segment);
|
|
||||||
_snakeP1.Segments.Clear();
|
|
||||||
_snakeP1.Alive = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// P2 pepsi?
|
|
||||||
if (_snakeP1.Segments.Contains(_snakeP2.HeadPosition) || _snakeP2.Segments.Contains(_snakeP2.HeadPosition))
|
|
||||||
{
|
{
|
||||||
foreach (Position2D segment in _snakeP2.Segments)
|
// is this snake running into the other snake or itself?
|
||||||
DeleteAt(segment);
|
if (SnakeCollision(snake.HeadPosition))
|
||||||
_snakeP2.Segments.Clear();
|
{
|
||||||
_snakeP2.Alive = false;
|
KillSnake(snake);
|
||||||
return;
|
|
||||||
}
|
|
||||||
// everyone pepsi? game over?!
|
// everyone pepsi? game over?!
|
||||||
if(!_snakeP1.Alive && !_snakeP2.Alive)
|
if (!_snakes[0].Alive && !_snakes[1].Alive)
|
||||||
_running = false;
|
_running = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(Collision(_food, _snakeP1.HeadPosition))
|
// is this snake picking up food?
|
||||||
|
if (Collision(_food, snake.HeadPosition))
|
||||||
{
|
{
|
||||||
_snakeP1.Growing = true;
|
|
||||||
SpawnFood();
|
|
||||||
} else if (Collision(_food, _snakeP2.HeadPosition))
|
|
||||||
{
|
|
||||||
_snakeP2.Growing = true;
|
|
||||||
SpawnFood();
|
SpawnFood();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete P1 tail if not growing
|
|
||||||
if (!_snakeP1.Growing && _snakeP1.Segments.Count > 0)
|
|
||||||
{
|
|
||||||
DeleteAt(_snakeP1.Segments.First());
|
|
||||||
_snakeP1.Segments.Remove(_snakeP1.Segments.First());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
_snakeP1.Growing = false;
|
|
||||||
// Delete P2 tail if not growing
|
|
||||||
if (!_snakeP2.Growing && _snakeP2.Segments.Count > 0)
|
|
||||||
{
|
{
|
||||||
DeleteAt(_snakeP2.Segments.First());
|
DeleteAt(snake.Segments.First());
|
||||||
_snakeP2.Segments.Remove(_snakeP2.Segments.First());
|
snake.Segments.Remove(snake.Segments.First());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_snakeP2.Growing = false;
|
|
||||||
|
|
||||||
GrowSnakes();
|
GrowSnake(snake);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessMovement()
|
private static void ProcessMovement()
|
||||||
{
|
{
|
||||||
Position2D posP1 = _snakeP1.HeadPosition;
|
foreach(Snake snake in _snakes)
|
||||||
Position2D posP2 = _snakeP2.HeadPosition;
|
{
|
||||||
|
Position2D position = snake.HeadPosition;
|
||||||
|
|
||||||
switch (_snakeP1.Direction)
|
switch (snake.Direction)
|
||||||
{
|
{
|
||||||
case Direction.Up:
|
case Direction.Up:
|
||||||
if (posP1.Y - 1 < _playArea.TopEdge)
|
if (position.Y - 1 < _playArea.TopEdge)
|
||||||
posP1.Y = _playArea.BottomEdge;
|
position.Y = _playArea.BottomEdge;
|
||||||
else
|
else
|
||||||
--posP1.Y;
|
--position.Y;
|
||||||
break;
|
break;
|
||||||
case Direction.Down:
|
case Direction.Down:
|
||||||
if (posP1.Y + 1 > _playArea.BottomEdge)
|
if (position.Y + 1 > _playArea.BottomEdge)
|
||||||
posP1.Y = _playArea.TopEdge;
|
position.Y = _playArea.TopEdge;
|
||||||
else
|
else
|
||||||
++posP1.Y;
|
++position.Y;
|
||||||
break;
|
break;
|
||||||
case Direction.Left:
|
case Direction.Left:
|
||||||
if (posP1.X - 1 < _playArea.LeftEdge)
|
if (position.X - 1 < _playArea.LeftEdge)
|
||||||
posP1.X = _playArea.RightEdge;
|
position.X = _playArea.RightEdge;
|
||||||
else
|
else
|
||||||
--posP1.X;
|
--position.X;
|
||||||
break;
|
break;
|
||||||
case Direction.Right:
|
case Direction.Right:
|
||||||
if (posP1.X + 1 > _playArea.RightEdge)
|
if (position.X + 1 > _playArea.RightEdge)
|
||||||
posP1.X = _playArea.LeftEdge;
|
position.X = _playArea.LeftEdge;
|
||||||
else
|
else
|
||||||
++posP1.X;
|
++position.X;
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (_snakeP2.Direction)
|
|
||||||
{
|
|
||||||
case Direction.Up:
|
|
||||||
if (posP2.Y - 1 < _playArea.TopEdge)
|
|
||||||
posP2.Y = _playArea.BottomEdge;
|
|
||||||
else
|
|
||||||
--posP2.Y;
|
|
||||||
break;
|
|
||||||
case Direction.Down:
|
|
||||||
if (posP2.Y + 1 > _playArea.BottomEdge)
|
|
||||||
posP2.Y = _playArea.TopEdge;
|
|
||||||
else
|
|
||||||
++posP2.Y;
|
|
||||||
break;
|
|
||||||
case Direction.Left:
|
|
||||||
if (posP2.X - 1 < _playArea.LeftEdge)
|
|
||||||
posP2.X = _playArea.RightEdge;
|
|
||||||
else
|
|
||||||
--posP2.X;
|
|
||||||
break;
|
|
||||||
case Direction.Right:
|
|
||||||
if (posP2.X + 1 > _playArea.RightEdge)
|
|
||||||
posP2.X = _playArea.LeftEdge;
|
|
||||||
else
|
|
||||||
++posP2.X;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_snakeP1.HeadPosition = posP1;
|
snake.HeadPosition = position;
|
||||||
_snakeP2.HeadPosition = posP2;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleInput()
|
static void HandleInput()
|
||||||
@ -314,49 +269,43 @@ namespace ConsoleSnake
|
|||||||
{
|
{
|
||||||
// Movement P1
|
// Movement P1
|
||||||
case ConsoleKey.UpArrow:
|
case ConsoleKey.UpArrow:
|
||||||
if(_snakeP1.Direction != Direction.Down)
|
if(_snakes[0].Direction != Direction.Down)
|
||||||
_snakeP1.Direction = Direction.Up;
|
_snakes[0].Direction = Direction.Up;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.DownArrow:
|
case ConsoleKey.DownArrow:
|
||||||
if (_snakeP1.Direction != Direction.Up)
|
if (_snakes[0].Direction != Direction.Up)
|
||||||
_snakeP1.Direction = Direction.Down;
|
_snakes[0].Direction = Direction.Down;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.LeftArrow:
|
case ConsoleKey.LeftArrow:
|
||||||
if (_snakeP1.Direction != Direction.Right)
|
if (_snakes[0].Direction != Direction.Right)
|
||||||
_snakeP1.Direction = Direction.Left;
|
_snakes[0].Direction = Direction.Left;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.RightArrow:
|
case ConsoleKey.RightArrow:
|
||||||
if (_snakeP1.Direction != Direction.Left)
|
if (_snakes[0].Direction != Direction.Left)
|
||||||
_snakeP1.Direction = Direction.Right;
|
_snakes[0].Direction = Direction.Right;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Movement P2
|
// Movement P2
|
||||||
case ConsoleKey.W:
|
case ConsoleKey.W:
|
||||||
if (_snakeP2.Direction != Direction.Down)
|
if (_snakes[1].Direction != Direction.Down)
|
||||||
_snakeP2.Direction = Direction.Up;
|
_snakes[1].Direction = Direction.Up;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.S:
|
case ConsoleKey.S:
|
||||||
if (_snakeP2.Direction != Direction.Up)
|
if (_snakes[1].Direction != Direction.Up)
|
||||||
_snakeP2.Direction = Direction.Down;
|
_snakes[1].Direction = Direction.Down;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.A:
|
case ConsoleKey.A:
|
||||||
if (_snakeP2.Direction != Direction.Right)
|
if (_snakes[1].Direction != Direction.Right)
|
||||||
_snakeP2.Direction = Direction.Left;
|
_snakes[1].Direction = Direction.Left;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.D:
|
case ConsoleKey.D:
|
||||||
if (_snakeP2.Direction != Direction.Left)
|
if (_snakes[1].Direction != Direction.Left)
|
||||||
_snakeP2.Direction = Direction.Right;
|
_snakes[1].Direction = Direction.Right;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ConsoleKey.Escape:
|
case ConsoleKey.Escape:
|
||||||
_running = false;
|
_running = false;
|
||||||
break;
|
break;
|
||||||
case ConsoleKey.G:
|
|
||||||
_snakeP1.Growing = !_snakeP1.Growing;
|
|
||||||
break;
|
|
||||||
case ConsoleKey.H:
|
|
||||||
_snakeP2.Growing = !_snakeP2.Growing;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user