class Guard : IUpdate { private readonly Map _map; private readonly HashSet<(Vector2I, char)> _path = []; public char Direction { get; set; } public Vector2I Position { get; set; } public Guard(Map map) { _map = map; map.RegisterOnUpdate(this); } public bool? Step() { if (!_path.Add((Position, Direction))) { return null; } var test = NextPosition(); if (!_map.IsValid(test)) { return false; } else if (_map.IsOccupied(test)) { Direction = Turn(); } else { Position = test; } return true; } public void Update() { var tmpPosition = Position; if (Step() is not true) { _map.UnregisterOnUpdate(this); } else { _map.Move(tmpPosition, Position); } } private Vector2I NextPosition() { return Position + Program.ToVector(Direction); } private char Turn() { return Direction switch { '^' => '>', '>' => 'v', 'v' => '<', '<' => '^', _ => throw new InvalidOperationException() }; } }