fix: prevent self-collision on rapid multi-key input using pending direction buffer
This commit is contained in:
@@ -3,6 +3,7 @@ namespace Snake.Core;
|
||||
public sealed class Snake
|
||||
{
|
||||
private readonly LinkedList<Position> _segments = new();
|
||||
private Direction _pendingDirection;
|
||||
|
||||
public Snake(Position start, int length, Direction direction)
|
||||
{
|
||||
@@ -10,6 +11,7 @@ public sealed class Snake
|
||||
throw new ArgumentOutOfRangeException(nameof(length), "Length must be at least 1.");
|
||||
|
||||
Direction = direction;
|
||||
_pendingDirection = direction;
|
||||
|
||||
var offset = DirectionToOffset(direction);
|
||||
for (var i = 0; i < length; i++)
|
||||
@@ -28,23 +30,27 @@ public sealed class Snake
|
||||
|
||||
public void SetDirection(Direction direction)
|
||||
{
|
||||
if (direction == Direction)
|
||||
if (direction == _pendingDirection)
|
||||
return;
|
||||
|
||||
if (AreOpposite(Direction, direction))
|
||||
return;
|
||||
|
||||
Direction = direction;
|
||||
if (_pendingDirection != Direction && AreOpposite(_pendingDirection, direction))
|
||||
return;
|
||||
|
||||
_pendingDirection = direction;
|
||||
}
|
||||
|
||||
public Position PeekNextHead()
|
||||
{
|
||||
var offset = DirectionToOffset(Direction);
|
||||
var offset = DirectionToOffset(_pendingDirection);
|
||||
return new Position(Head.X + offset.X, Head.Y + offset.Y);
|
||||
}
|
||||
|
||||
public Position Move(bool grow = false)
|
||||
{
|
||||
Direction = _pendingDirection;
|
||||
var newHead = PeekNextHead();
|
||||
|
||||
_segments.AddFirst(newHead);
|
||||
|
||||
Reference in New Issue
Block a user