From f02e389580e77cfbfca99f0a2483ff71f88746fd Mon Sep 17 00:00:00 2001 From: Heller Date: Wed, 17 Jun 2026 19:12:20 +0000 Subject: [PATCH] fix: prevent self-collision on rapid multi-key input using pending direction buffer --- Snake.Core/Snake.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Snake.Core/Snake.cs b/Snake.Core/Snake.cs index b554871..3be64ff 100644 --- a/Snake.Core/Snake.cs +++ b/Snake.Core/Snake.cs @@ -3,6 +3,7 @@ namespace Snake.Core; public sealed class Snake { private readonly LinkedList _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);