Cleaned up a bit, OOPified it as well, even though I meant to keep it as procedural as possible (for now)

master
morpha 2023-03-28 23:21:20 +02:00
parent 3da34fadb2
commit 854d1bfde1
1 changed files with 113 additions and 142 deletions

View File

@ -29,21 +29,28 @@ namespace ConsoleSnake
private struct Position2D private struct Position2D
{ {
public Position2D() : this(-1, -1) { }
public Position2D(Int32 x, Int32 y) { X = x; Y = y; } public Position2D(Int32 x, Int32 y) { X = x; Y = y; }
public Int32 X { get; set; } public Int32 X { get; set; }
public Int32 Y { get; set; } public Int32 Y { get; set; }
} }
private struct Snake
{
public Direction Direction { get; set; } = Direction.Down;
public Position2D HeadPosition { get; set; } = new Position2D();
public List<Position2D> Segments { get; set; } = new List<Position2D>();
public bool Growing { get; set; } = false;
public Snake()
{
}
}
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 bool _growingP1 = false; private static Snake _snakeP1 = new Snake();
private static bool _growingP2 = false; private static Snake _snakeP2 = new Snake();
private static Direction _directionP1 = Direction.Right;
private static Direction _directionP2 = Direction.Left;
private static Position2D _headP1 = new Position2D(-1, -1);
private static Position2D _headP2 = new Position2D(-1, -1);
private static List<Position2D> _snakeSegmentsP1 = new List<Position2D>();
private static List<Position2D> _snakeSegmentsP2 = new List<Position2D>();
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();
static void Main(string[] args) static void Main(string[] args)
@ -85,61 +92,51 @@ namespace ConsoleSnake
{ {
for (Int32 left = 0; left < _playArea.LeftEdge; ++left) for (Int32 left = 0; left < _playArea.LeftEdge; ++left)
Console.Write(' '); Console.Write(' ');
//Console.CursorLeft = _playArea.RightEdge+1;
for (Int32 left = Console.CursorLeft = _playArea.RightEdge + 1; left < Console.WindowWidth; ++left) for (Int32 left = Console.CursorLeft = _playArea.RightEdge + 1; left < Console.WindowWidth; ++left)
Console.Write(' '); Console.Write(' ');
/*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; Console.BackgroundColor = ConsoleColor.Black;
} }
private static void Reset() private static void Reset()
{ {
_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;
_growingP1 = false; _snakeP1.Growing = false;
_growingP2 = false; _snakeP2.Growing = false;
_directionP1 = Direction.Right; _snakeP1.Direction = Direction.Right;
_directionP2 = Direction.Left; _snakeP2.Direction = Direction.Left;
_snakeSegmentsP1.Clear(); _snakeP1.Segments.Clear();
_snakeSegmentsP2.Clear(); _snakeP2.Segments.Clear();
// Set up anew // Set up anew
_snakeSegmentsP1.Add(_headP1 = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2)); _snakeP1.Segments.Add(_snakeP1.HeadPosition = new Position2D(Console.BufferWidth / 2, Console.BufferHeight / 2));
_snakeSegmentsP2.Add(_headP2 = new Position2D(Console.BufferWidth / 2 - 1, Console.BufferHeight / 2)); _snakeP2.Segments.Add(_snakeP2.HeadPosition = new Position2D(Console.BufferWidth / 2 - 1, Console.BufferHeight / 2));
SpawnFood(); SpawnFood();
MoveCursor(_snakeSegmentsP1.Last());
} }
private static void SpawnFood() private static void SpawnFood()
{ {
Position2D oldCursorPos = new Position2D(Console.CursorLeft, Console.CursorTop); //Position2D oldCursorPos = new Position2D(Console.CursorLeft, Console.CursorTop);
do do
{ {
_food = new Position2D(rng.Next(_playArea.LeftEdge+1, _playArea.RightEdge), rng.Next(_playArea.TopEdge, _playArea.BottomEdge)); _food = new Position2D(rng.Next(_playArea.LeftEdge+1, _playArea.RightEdge), rng.Next(_playArea.TopEdge, _playArea.BottomEdge));
} while (_snakeSegmentsP1.Contains(_food) || _snakeSegmentsP2.Contains(_food)); } while (_snakeP1.Segments.Contains(_food) || _snakeP2.Segments.Contains(_food));
MoveCursor(_food); MoveCursor(_food);
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.Write('@'); Console.Write('@');
Console.ForegroundColor = ConsoleColor.Green; //MoveCursor(oldCursorPos);
MoveCursor(oldCursorPos);
} }
private static void JoinPlayer2() private static void WriteColAt(char text, ConsoleColor color, Position2D pos) => WriteColAt(text.ToString(), color, pos.X, pos.Y);
private static void WriteColAt(string text, ConsoleColor color, Position2D pos) => WriteColAt(text, color, pos.X, pos.Y);
private static void WriteColAt(char text, ConsoleColor color, Int32 x, Int32 y) => WriteColAt(text.ToString(), color, x, y);
private static void WriteColAt(string text, ConsoleColor color, Int32 x, Int32 y)
{ {
Console.SetCursorPosition(x, y);
Console.ForegroundColor = color;
Console.Write(text);
} }
private static void MoveCursor(Position2D pos) => MoveCursor(pos.X, pos.Y); private static void MoveCursor(Position2D pos) => MoveCursor(pos.X, pos.Y);
@ -150,30 +147,23 @@ namespace ConsoleSnake
} }
private static void GrowSnakes() private static void GrowSnakes()
{ {
if (_snakeSegmentsP1.Count > 0) if (_snakeP1.Segments.Count > 0)
{ {
_snakeSegmentsP1.Add(_headP1); _snakeP1.Segments.Add(_snakeP1.HeadPosition);
Console.SetCursorPosition(_headP1.X, _headP1.Y); WriteColAt('#', ConsoleColor.Green, _snakeP1.HeadPosition);
Console.ForegroundColor = ConsoleColor.Green;
Console.Write('#');
} }
if (_snakeSegmentsP2.Count > 0) if (_snakeP2.Segments.Count > 0)
{ {
_snakeSegmentsP2.Add(_headP2); _snakeP2.Segments.Add(_snakeP2.HeadPosition);
Console.SetCursorPosition(_headP2.X, _headP2.Y); WriteColAt('#', ConsoleColor.Cyan, _snakeP2.HeadPosition);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write('#');
} }
} }
private static void DeleteAt(Position2D pos) => DeleteAt(pos.X, pos.Y); private static void DeleteAt(Position2D pos) => DeleteAt(pos.X, pos.Y);
private static void DeleteAt(Int32 x, Int32 y) private static void DeleteAt(Int32 x, Int32 y)
{ {
Int32 curX = Console.CursorLeft;
Int32 curY = Console.CursorTop;
MoveCursor(x, y); MoveCursor(x, y);
Console.Write(' '); Console.Write(' ');
MoveCursor(curX, curY);
} }
private static bool Collision(Position2D pos1, Position2D pos2) private static bool Collision(Position2D pos1, Position2D pos2)
@ -186,136 +176,118 @@ namespace ConsoleSnake
ProcessMovement(); ProcessMovement();
if (_snakeSegmentsP1.Contains(_headP1) || _snakeSegmentsP2.Contains(_headP1)) // P1 pepsi?
if (_snakeP1.Segments.Contains(_snakeP1.HeadPosition) || _snakeP2.Segments.Contains(_snakeP1.HeadPosition))
{ {
foreach(Position2D segment in _snakeSegmentsP1) foreach(Position2D segment in _snakeP1.Segments)
DeleteAt(segment); DeleteAt(segment);
_snakeSegmentsP1.Clear(); _snakeP1.Segments.Clear();
return; return;
} }
if (_snakeSegmentsP1.Contains(_headP2) || _snakeSegmentsP2.Contains(_headP2)) // P2 pepsi?
if (_snakeP1.Segments.Contains(_snakeP2.HeadPosition) || _snakeP2.Segments.Contains(_snakeP2.HeadPosition))
{ {
foreach (Position2D segment in _snakeSegmentsP2) foreach (Position2D segment in _snakeP2.Segments)
DeleteAt(segment); DeleteAt(segment);
_snakeSegmentsP2.Clear(); _snakeP2.Segments.Clear();
return; return;
} }
if(_snakeSegmentsP1.Count == 0 && _snakeSegmentsP2.Count == 0) // everyone pepsi? game over?!
if(_snakeP1.Segments.Count == 0 && _snakeP2.Segments.Count == 0)
_running = false; _running = false;
GrowSnakes(); GrowSnakes();
if(_food.X == _headP1.X && _food.Y == _headP1.Y) if(Collision(_food, _snakeP1.HeadPosition))
{ {
_growingP1 = true; _snakeP1.Growing = true;
SpawnFood(); SpawnFood();
} else if (_food.X == _headP2.X && _food.Y == _headP2.Y) } else if (Collision(_food, _snakeP2.HeadPosition))
{ {
_growingP2 = true; _snakeP2.Growing = true;
SpawnFood(); SpawnFood();
} }
// growth P1 // growth P1
if (!_growingP1 && _snakeSegmentsP1.Count > 0) if (!_snakeP1.Growing && _snakeP1.Segments.Count > 0)
{ {
DeleteAt(_snakeSegmentsP1.First()); DeleteAt(_snakeP1.Segments.First());
_snakeSegmentsP1.Remove(_snakeSegmentsP1.First()); _snakeP1.Segments.Remove(_snakeP1.Segments.First());
} }
else else
_growingP1 = false; _snakeP1.Growing = false;
// growth P2 // growth P2
if (!_growingP2 && _snakeSegmentsP2.Count > 0) if (!_snakeP2.Growing && _snakeP2.Segments.Count > 0)
{ {
DeleteAt(_snakeSegmentsP2.First()); DeleteAt(_snakeP2.Segments.First());
_snakeSegmentsP2.Remove(_snakeSegmentsP2.First()); _snakeP2.Segments.Remove(_snakeP2.Segments.First());
} }
else else
_growingP2 = false;/**/ _snakeP2.Growing = false;
} }
private static void ProcessMovement() private static void ProcessMovement()
{ {
/*switch (_directionP1) Position2D posP1 = _snakeP1.HeadPosition;
Position2D posP2 = _snakeP2.HeadPosition;
switch (_snakeP1.Direction)
{ {
case Direction.Up: case Direction.Up:
if (Console.CursorTop - 1 < _playArea.TopEdge) if (posP1.Y - 1 < _playArea.TopEdge)
Console.CursorTop = _playArea.BottomEdge; posP1.Y = _playArea.BottomEdge;
else else
--Console.CursorTop; --posP1.Y;
break; break;
case Direction.Down: case Direction.Down:
if (Console.CursorTop + 1 > _playArea.BottomEdge) if (posP1.Y + 1 > _playArea.BottomEdge)
Console.CursorTop = _playArea.TopEdge; posP1.Y = _playArea.TopEdge;
else else
++Console.CursorTop; ++posP1.Y;
break; break;
case Direction.Left: case Direction.Left:
if (Console.CursorLeft - 1 < _playArea.LeftEdge) if (posP1.X - 1 < _playArea.LeftEdge)
Console.CursorLeft = _playArea.RightEdge; posP1.X = _playArea.RightEdge;
else else
--Console.CursorLeft; --posP1.X;
break; break;
case Direction.Right: case Direction.Right:
if (Console.CursorLeft + 1 > _playArea.RightEdge) if (posP1.X + 1 > _playArea.RightEdge)
Console.CursorLeft = _playArea.LeftEdge; posP1.X = _playArea.LeftEdge;
else else
++Console.CursorLeft; ++posP1.X;
break;
}/**/
switch (_directionP1)
{
case Direction.Up:
if (_headP1.Y - 1 < _playArea.TopEdge)
_headP1.Y = _playArea.BottomEdge;
else
--_headP1.Y;
break;
case Direction.Down:
if (_headP1.Y + 1 > _playArea.BottomEdge)
_headP1.Y = _playArea.TopEdge;
else
++_headP1.Y;
break;
case Direction.Left:
if (_headP1.X - 1 < _playArea.LeftEdge)
_headP1.X = _playArea.RightEdge;
else
--_headP1.X;
break;
case Direction.Right:
if (_headP1.X + 1 > _playArea.RightEdge)
_headP1.X = _playArea.LeftEdge;
else
++_headP1.X;
break; break;
} }
switch (_directionP2) switch (_snakeP2.Direction)
{ {
case Direction.Up: case Direction.Up:
if (_headP2.Y - 1 < _playArea.TopEdge) if (posP2.Y - 1 < _playArea.TopEdge)
_headP2.Y = _playArea.BottomEdge; posP2.Y = _playArea.BottomEdge;
else else
--_headP2.Y; --posP2.Y;
break; break;
case Direction.Down: case Direction.Down:
if (_headP2.Y + 1 > _playArea.BottomEdge) if (posP2.Y + 1 > _playArea.BottomEdge)
_headP2.Y = _playArea.TopEdge; posP2.Y = _playArea.TopEdge;
else else
++_headP2.Y; ++posP2.Y;
break; break;
case Direction.Left: case Direction.Left:
if (_headP2.X - 1 < _playArea.LeftEdge) if (posP2.X - 1 < _playArea.LeftEdge)
_headP2.X = _playArea.RightEdge; posP2.X = _playArea.RightEdge;
else else
--_headP2.X; --posP2.X;
break; break;
case Direction.Right: case Direction.Right:
if (_headP2.X + 1 > _playArea.RightEdge) if (posP2.X + 1 > _playArea.RightEdge)
_headP2.X = _playArea.LeftEdge; posP2.X = _playArea.LeftEdge;
else else
++_headP2.X; ++posP2.X;
break; break;
} }
_snakeP1.HeadPosition = posP1;
_snakeP2.HeadPosition = posP2;
} }
static void HandleInput() static void HandleInput()
@ -326,49 +298,48 @@ namespace ConsoleSnake
{ {
// Movement P1 // Movement P1
case ConsoleKey.UpArrow: case ConsoleKey.UpArrow:
if(_directionP1 != Direction.Down) if(_snakeP1.Direction != Direction.Down)
_directionP1 = Direction.Up; _snakeP1.Direction = Direction.Up;
break; break;
case ConsoleKey.DownArrow: case ConsoleKey.DownArrow:
if (_directionP1 != Direction.Up) if (_snakeP1.Direction != Direction.Up)
_directionP1 = Direction.Down; _snakeP1.Direction = Direction.Down;
break; break;
case ConsoleKey.LeftArrow: case ConsoleKey.LeftArrow:
if (_directionP1 != Direction.Right) if (_snakeP1.Direction != Direction.Right)
_directionP1 = Direction.Left; _snakeP1.Direction = Direction.Left;
break; break;
case ConsoleKey.RightArrow: case ConsoleKey.RightArrow:
if (_directionP1 != Direction.Left) if (_snakeP1.Direction != Direction.Left)
_directionP1 = Direction.Right; _snakeP1.Direction = Direction.Right;
break; break;
// Movement P2 // Movement P2
case ConsoleKey.W: case ConsoleKey.W:
if (_directionP2 != Direction.Down) if (_snakeP2.Direction != Direction.Down)
_directionP2 = Direction.Up; _snakeP2.Direction = Direction.Up;
break; break;
case ConsoleKey.S: case ConsoleKey.S:
if (_directionP2 != Direction.Up) if (_snakeP2.Direction != Direction.Up)
_directionP2 = Direction.Down; _snakeP2.Direction = Direction.Down;
break; break;
case ConsoleKey.A: case ConsoleKey.A:
if (_directionP2 != Direction.Right) if (_snakeP2.Direction != Direction.Right)
_directionP2 = Direction.Left; _snakeP2.Direction = Direction.Left;
break; break;
case ConsoleKey.D: case ConsoleKey.D:
if (_directionP2 != Direction.Left) if (_snakeP2.Direction != Direction.Left)
_directionP2 = Direction.Right; _snakeP2.Direction = Direction.Right;
break;
case ConsoleKey.D2:
JoinPlayer2();
break; break;
case ConsoleKey.Escape: case ConsoleKey.Escape:
_running = false; _running = false;
break; break;
case ConsoleKey.G: case ConsoleKey.G:
_growingP1 = !_growingP1; _snakeP1.Growing = !_snakeP1.Growing;
break;
case ConsoleKey.H:
_snakeP2.Growing = !_snakeP2.Growing;
break; break;
} }
} }