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);
    }