Compare commits
3 Commits
feature/fu
...
fix/input-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06c51277b6 | ||
|
|
76b9faba1a | ||
|
|
f02e389580 |
@@ -3,6 +3,7 @@ namespace Snake.Core;
|
|||||||
public sealed class Snake
|
public sealed class Snake
|
||||||
{
|
{
|
||||||
private readonly LinkedList<Position> _segments = new();
|
private readonly LinkedList<Position> _segments = new();
|
||||||
|
private readonly Queue<Direction> _pendingDirections = new();
|
||||||
|
|
||||||
public Snake(Position start, int length, Direction direction)
|
public Snake(Position start, int length, Direction direction)
|
||||||
{
|
{
|
||||||
@@ -26,26 +27,37 @@ public sealed class Snake
|
|||||||
|
|
||||||
public IReadOnlyCollection<Position> Segments => _segments;
|
public IReadOnlyCollection<Position> Segments => _segments;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enqueues a direction change to be applied on a future tick.
|
||||||
|
/// </summary>
|
||||||
public void SetDirection(Direction direction)
|
public void SetDirection(Direction direction)
|
||||||
{
|
{
|
||||||
if (direction == Direction)
|
_pendingDirections.Enqueue(direction);
|
||||||
return;
|
|
||||||
|
|
||||||
if (AreOpposite(Direction, direction))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Direction = direction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the head position after the next move without changing state.
|
||||||
|
/// Invalid queued directions (same as current or opposite) are discarded.
|
||||||
|
/// </summary>
|
||||||
public Position PeekNextHead()
|
public Position PeekNextHead()
|
||||||
{
|
{
|
||||||
var offset = DirectionToOffset(Direction);
|
DiscardInvalidPendingDirections();
|
||||||
|
var direction = _pendingDirections.Count > 0 ? _pendingDirections.Peek() : Direction;
|
||||||
|
var offset = DirectionToOffset(direction);
|
||||||
return new Position(Head.X + offset.X, Head.Y + offset.Y);
|
return new Position(Head.X + offset.X, Head.Y + offset.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies at most one valid queued direction change, then moves the snake.
|
||||||
|
/// </summary>
|
||||||
public Position Move(bool grow = false)
|
public Position Move(bool grow = false)
|
||||||
{
|
{
|
||||||
var newHead = PeekNextHead();
|
DiscardInvalidPendingDirections();
|
||||||
|
if (_pendingDirections.Count > 0)
|
||||||
|
Direction = _pendingDirections.Dequeue();
|
||||||
|
|
||||||
|
var offset = DirectionToOffset(Direction);
|
||||||
|
var newHead = new Position(Head.X + offset.X, Head.Y + offset.Y);
|
||||||
|
|
||||||
_segments.AddFirst(newHead);
|
_segments.AddFirst(newHead);
|
||||||
|
|
||||||
@@ -63,6 +75,21 @@ public sealed class Snake
|
|||||||
return _segments.Contains(position);
|
return _segments.Contains(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes queued directions that would turn backwards or repeat the current direction.
|
||||||
|
/// </summary>
|
||||||
|
private void DiscardInvalidPendingDirections()
|
||||||
|
{
|
||||||
|
while (_pendingDirections.Count > 0)
|
||||||
|
{
|
||||||
|
var next = _pendingDirections.Peek();
|
||||||
|
if (next != Direction && !AreOpposite(Direction, next))
|
||||||
|
break;
|
||||||
|
|
||||||
|
_pendingDirections.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Position DirectionToOffset(Direction direction) =>
|
private static Position DirectionToOffset(Direction direction) =>
|
||||||
direction switch
|
direction switch
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user