public MapReturn ScanBuildingElevator(SimulationParameters parameters)
    {
        if (parameters.ElevatorsToBuild <= 0)
        {
            return(MapReturn.Invalid);
        }

        var elevator = new MapReturn(ElevatorTotalTravel(parameters), parameters.Direction, true);

        return(elevator);
    }
    public MapReturn ShortPath(SimulationParameters simulationParameters, bool root = false)
    {
        var key = simulationParameters.CacheKey();

        if (_pathCaching.ContainsKey(key))
        {
            return(_pathCaching[key]);
        }

        if (simulationParameters.NbTotalClones < 0 || simulationParameters.CloneFloor > _exitFloor)
        {
            return(new MapReturn(int.MaxValue, simulationParameters.Direction));
        }

        var floor     = _floors[simulationParameters.CloneFloor];
        var elevators = floor.ElevatorsByDirection(simulationParameters.ClonePos, simulationParameters.Direction);

        if (floor.Elevators.Any(p => p == simulationParameters.ClonePos))
        {
            return(WaitForElevator(simulationParameters));
        }

        if (simulationParameters.CloneFloor == _exitFloor)
        {
            return(HandleLastFloor(simulationParameters, elevators));
        }

        var left  = new MapReturn(CalculateFor(simulationParameters, elevators.ClosestLeft, Direction.Left), Direction.Left);
        var right = new MapReturn(CalculateFor(simulationParameters, elevators.ClosestRight, Direction.Right), Direction.Right);


        var buildElevator = _elevatorStrategy.ScanBuildingElevator(simulationParameters.CloneAt(simulationParameters.ClonePos));

        var shortPath = MinOf(left, right, buildElevator);

        if (shortPath.TotalTravel == int.MaxValue)
        {
            var elevatorReturns = _elevatorStrategy.GetMasterElevators(simulationParameters, elevators);
            shortPath = MinOf(elevatorReturns.ToArray());
        }

        if (root)
        {
            //Console.Error.WriteLine($"Health Total Clones = {_nbTotalClones}; TotalElevators = {_elevatorsToBuild}");
            //Console.Error.WriteLine($"left = {left.Format()}");
            //Console.Error.WriteLine($"right = {right.Format()}");
            //Console.Error.WriteLine($"elevator! = {buildElevator.Format()}");
            //Console.Error.WriteLine($"Returned! = {shortPath.Format()}");
        }
        _pathCaching.Add(key, shortPath);
        return(shortPath);
    }
    private void AddRight(SimulationParameters simulationParameters, ElevatorReturn elevators, List <MapReturn> results)
    {
        int maxRight = _game._maxWidth;

        if (elevators.ClosestRight != null)
        {
            maxRight = elevators.ClosestRight.Position - 1;
        }

        var newParams = simulationParameters.WrongDirectionHandle(simulationParameters.Direction == Direction.Right);

        for (int i = simulationParameters.ClonePos + 1; i <= maxRight; i++)
        {
            var distance     = Floor.GetDistance(simulationParameters.ClonePos, i, simulationParameters.Direction);
            var cloneAt      = newParams.CloneAt(i);
            var pathDistance = ElevatorTotalTravel(cloneAt) + distance;
            var x            = new MapReturn(pathDistance, simulationParameters.Direction);
            results.Add(x);
        }
    }
    private void AddLeft(SimulationParameters simulationParameters, ElevatorReturn elevators, List <MapReturn> results)
    {
        int maxRight = 0;

        if (elevators.ClosestLeft != null)
        {
            maxRight = elevators.ClosestLeft.Position + 1;
        }

        var newParams = simulationParameters.WrongDirectionHandle(simulationParameters.Direction == Direction.Left);

        for (int i = simulationParameters.ClonePos - 1; i >= maxRight; i--)
        {
            var cloneAt             = newParams.CloneAt(i);
            var distance            = Floor.GetDistance(simulationParameters.ClonePos, i, simulationParameters.Direction);
            var elevatorTotalTravel = distance + ElevatorTotalTravel(cloneAt);

            var x = new MapReturn(elevatorTotalTravel, Direction.Left);
            results.Add(x);
        }
    }