public ElevatorReturn ElevatorsByDirection(int clonePos, Direction direction)
    {
        var elevatorsReturn = new ElevatorReturn();
        var lookup          = Elevators.ToLookup(p => p > clonePos ? Direction.Right : Direction.Left, x => new ClosestElevator(x, clonePos, direction));

        if (lookup.Contains(Direction.Right))
        {
            elevatorsReturn.ClosestRight = lookup[Direction.Right].Where(p => p.Position > clonePos).OrderBy(p => p.Distance).FirstOrDefault();
        }
        if (lookup.Contains(Direction.Left))
        {
            elevatorsReturn.ClosestLeft = lookup[Direction.Left].Where(p => p.Position < clonePos).OrderBy(p => p.Distance).FirstOrDefault();
        }

        return(elevatorsReturn);
    }
    private MapReturn HandleLastFloor(SimulationParameters simulationParameters, ElevatorReturn elevators)
    {
        if (simulationParameters.ClonePos == _exitPosition)
        {
            return(new MapReturn(1, simulationParameters.Direction));
        }

        var returnDirection = _exitPosition > simulationParameters.ClonePos ? Direction.Right : Direction.Left;

        if (returnDirection == Direction.Right)
        {
            return(LastFloorReturnRight(simulationParameters, returnDirection, elevators.ClosestRight));
        }

        return(LastFloorReturnLeft(simulationParameters, returnDirection, elevators.ClosestLeft));
    }
    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);
        }
    }
    public List <MapReturn> GetMasterElevators(SimulationParameters simulationParameters, ElevatorReturn elevators)
    {
        var results = new List <MapReturn>();

        if (simulationParameters.ElevatorsToBuild > 0)
        {
            AddRight(simulationParameters, elevators, results);
            AddLeft(simulationParameters, elevators, results);
        }

        return(results);
    }