Castle on the Grid

  • + 0 comments

    C#

    private sealed record PathPoint(int X, int Y, int Direction, int Moves);
    
    public static int MinimumMoves(List<string> grid, int startX, int startY, int goalX, int goalY)
    {
        var moveDistances = Enumerable.Range(0, grid.Count).Select(_ => Enumerable.Repeat(int.MaxValue, grid.Count).ToArray()).ToArray();
        var directions = new List<(int Dx, int Dy)> { (-1, 0), (0, -1), (0, 1), (1, 0) };
        var pathQueue = new Queue<PathPoint>();
        var results = new List<int>();
    
        moveDistances[startX][startY] = 0;
        pathQueue.Enqueue(new PathPoint(startX, startY, -1, 0));
    
        while (pathQueue.TryDequeue(out var path))
        {
            if (path.X == goalX && path.Y == goalY)
            {
                results.Add(path.Moves);
            }
    
            for (var i = 0; i < directions.Count; i++)
            {
                var (x, y) = (path.X + directions[i].Dx, path.Y + directions[i].Dy);
                if (x >= 0 && x < grid.Count && y >= 0 && y < grid.Count && grid[x][y] != 'X')
                {
                    var moves = path.Moves + (i == path.Direction ? 0 : 1);
                    if (moves < moveDistances[x][y])
                    {
                        moveDistances[x][y] = moves;
                        pathQueue.Enqueue(new PathPoint(x, y, i, moves));
                    }
                }
            }
        }
    
        return results.Min();
    }