public void DefaultByPowerPerformance()
        {
            tableGear     = new Dictionary <int, Dictionary <double, int> >();
            tableThrottle = new Dictionary <int, Dictionary <double, double> >();
            // Make sure there are 20 rpm steps, and 10 load steps
            for (int speed = 0; speed <= MaximumSpeed; speed += 1)
            {
                tableGear.Add(speed, new Dictionary <double, int>());
                tableThrottle.Add(speed, new Dictionary <double, double>());
                for (var load = 0.0; load <= 1.0; load += 0.1)
                {
                    tableThrottle[speed].Add(load, 1);
                    var gearSet = false;

                    var bestPower     = double.MinValue;
                    var bestPowerGear = 0;
                    var latestGearThatWasNotStalling = 1;

                    for (int gear = 0; gear < Drivetrain.Gears; gear++)
                    {
                        var calculatedRpm = Drivetrain.GearRatios[gear] * speed;
                        if (calculatedRpm < Drivetrain.StallRpm)
                        {
                            calculatedRpm = Drivetrain.StallRpm;
                        }
                        if (calculatedRpm < 1200)
                        {
                            continue;
                        }
                        var pwr = Drivetrain.CalculatePower(calculatedRpm + 200, load < 0.2 ? 0.2 : load);

                        latestGearThatWasNotStalling = gear;
                        if (calculatedRpm > Drivetrain.MaximumRpm)
                        {
                            continue;
                        }
                        if (gear == 0 && calculatedRpm > Drivetrain.MaximumRpm - 200)
                        {
                            continue;
                        }
                        if (pwr > bestPower)
                        {
                            bestPower     = pwr;
                            bestPowerGear = gear;
                            gearSet       = true;
                        }
                    }

                    //if (speed < 30 )
                    //    tableGear[speed].Add(load, latestGearThatWasNotStalling);
                    //else
                    if (!gearSet)
                    {
                        tableGear[speed].Add(load, (latestGearThatWasNotStalling == 1 ? 1 : latestGearThatWasNotStalling + 1));
                    }
                    else
                    {
                        tableGear[speed].Add(load, bestPowerGear + 1);
                    }
                }
            }
        }
        private void DefaultByPowerEfficiency2()
        {
            tableGear     = new Dictionary <int, Dictionary <double, int> >();
            tableThrottle = new Dictionary <int, Dictionary <double, double> >();

            if (Drivetrain.Gears == 0)
            {
                return;
            }
            // Make sure there are 20 rpm steps, and 10 load steps
            for (int speed = 0; speed <= MaximumSpeed; speed += 1)
            {
                tableGear.Add(speed, new Dictionary <double, int>());
                tableThrottle.Add(speed, new Dictionary <double, double>());

                Dictionary <int, float> pwrPerGear = new Dictionary <int, float>();

                // Populate:
                for (int gear = 0; gear < Drivetrain.Gears; gear++)
                {
                    var calculatedRpm = Drivetrain.GearRatios[gear] * speed;
                    var power         = (float)Drivetrain.CalculatePower(calculatedRpm, 1);
                    pwrPerGear.Add(gear, power);
                }

                var maxPwrAvailable = pwrPerGear.Values.Max() * 0.85;

                for (var load = 0.0; load <= 1.0; load += 0.1)
                {
                    Dictionary <int, float> efficiencyPerGear = new Dictionary <int, float>();
                    var highestGearBeforeStalling             = 0;

                    for (int gear = 0; gear < Drivetrain.Gears; gear++)
                    {
                        var calculatedRpm = Drivetrain.GearRatios[gear] * speed;
                        if (calculatedRpm > Drivetrain.StallRpm)
                        {
                            highestGearBeforeStalling = gear;
                        }
                        var power = (float)Drivetrain.CalculatePower(calculatedRpm, 1);
                        var fuel  = (float)Drivetrain.CalculateFuelConsumption(calculatedRpm, Math.Max(0.05, load));
                        efficiencyPerGear.Add(gear, fuel / power);
                    }
                    var bestGear  = highestGearBeforeStalling;
                    var bestGearV = 100.0f;
                    foreach (var kvp in efficiencyPerGear)
                    {
                        if (kvp.Value < bestGearV && kvp.Value > 0)
                        {
                            bestGearV = kvp.Value;
                            bestGear  = kvp.Key;
                        }
                    }
                    var actualRpm = Drivetrain.GearRatios[bestGear] * speed;

                    var reqThr   = Drivetrain.CalculateThrottleByPower(actualRpm, load * maxPwrAvailable);
                    var thrScale = reqThr / Math.Max(load, 0.1);
                    if (thrScale > 1.5)
                    {
                        thrScale = 1.5;
                    }
                    tableGear[speed].Add(load, bestGear + 1);
                    tableThrottle[speed].Add(load, thrScale);
                }
            }
        }
        public void DefaultByPowerEfficiency()
        {
            tableGear     = new Dictionary <int, Dictionary <double, int> >();
            tableThrottle = new Dictionary <int, Dictionary <double, double> >();
            // Make sure there are 20 rpm steps, and 10 load steps
            for (int speed = 0; speed <= MaximumSpeed; speed += 1)
            {
                tableGear.Add(speed, new Dictionary <double, int>());
                tableThrottle.Add(speed, new Dictionary <double, double>());
                for (var load = 0.0; load <= 1.0; load += 0.1)
                {
                    tableThrottle[speed].Add(load, 1);
                    var gearSet            = false;
                    var bestFuelEfficiency = double.MinValue;
                    var bestFuelGear       = 0;

                    for (int gear = 0; gear < Drivetrain.Gears; gear++)
                    {
                        var calculatedRpm = Drivetrain.GearRatios[gear] * speed;

                        if (calculatedRpm < Drivetrain.StallRpm * 1.5)
                        {
                            continue;
                        }
                        if (calculatedRpm > Drivetrain.MaximumRpm)
                        {
                            continue;
                        }

                        var thr = (load < 0.05) ? 0.05 : load;

                        var pwr        = Drivetrain.CalculatePower(calculatedRpm, thr);
                        var fuel       = Drivetrain.CalculateFuelConsumption(calculatedRpm, thr);
                        var efficiency = pwr / fuel;

                        if (efficiency > bestFuelEfficiency)
                        {
                            bestFuelEfficiency = efficiency;
                            bestFuelGear       = gear;
                            gearSet            = true;
                        }
                    }
                    if (!gearSet)
                    {
                        if (Drivetrain is Ets2Drivetrain && Drivetrain.Gears >= 10)
                        {
                            tableGear[speed].Add(load, 3);
                        }
                        else
                        {
                            tableGear[speed].Add(load, 1);
                        }
                    }
                    else
                    {
                        if (Drivetrain is Ets2Drivetrain && Drivetrain.Gears >= 10)
                        {
                            bestFuelGear = Math.Max(2, bestFuelGear);
                        }
                        tableGear[speed].Add(load, bestFuelGear + 1);
                    }
                }
            }
        }