Exemplo n.º 1
0
bool SimpleStrategy::needPitstop(tCarElt* car, tSituation *s, Opponents *opp)
{
    // Do we need to refuel?
    int remainlaps = car->_remainingLaps;//-car->_lapsBehindLeader;
    //int this_pit_dammage = PitDamage;

    if (!car->_pit)
        return false;

    int forcepit = (int) GfParmGetNum( car->_carHandle, SECT_PRIVATE, PRV_FORCE_PIT, (char *)NULL, 0.0 );
    if (forcepit)
        return true;

#ifdef SPEED_DREAMS
    int repairWanted = 10000;

    if ((remainlaps > 0) && (remainlaps < 20))
    {
        repairWanted = MIN(8000, PitDamage + (20-remainlaps)*200);
    }

    if (car->_dammage < 9000 && (remainlaps <= 2 || strategy == STRATEGY_DESPERATE))
        repairWanted = 0;

    if (car->_dammage < MIN(3000, PitDamage/2))
        repairWanted = 0;

    float cmpfuel = (m_fuelperlap == 0.0) ? m_expectedfuelperlap : m_fuelperlap;

    float fuelPerM = cmpfuel / track->length;
    bool GotoPit = RtTeamNeedPitStop(teamIndex,fuelPerM,repairWanted);

    if (m_Driver->HasTYC)
    {
      double TdF = m_Driver->TyreTreadDepthFront(); // Check tyre condition
      double TdR = m_Driver->TyreTreadDepthRear();  // Pit stop needed if
      m_DegradationPerLap = (m_Laps * m_DegradationPerLap
        + MAX(m_TireLimitFront - TdF, m_TireLimitRear - TdR));
      m_DegradationPerLap /= ++m_Laps;

      if (MIN(TdF,TdR) < 1.5 * m_DegradationPerLap) // tyres become critical
      {
          /*LogUSR.warning("Tyre condition D: %.1f%% F: %.1f%% R: %.1f%%\n",
          m_DegradationPerLap, TdF, TdR);*/

        if ((TdF < 1.1 * m_DegradationPerLap)
          || (TdR < 1.1 * m_DegradationPerLap))
        {
          GotoPit = true;                           //   to stop in pit
        }
      }

      m_TireLimitFront = TdF;
      m_TireLimitRear = TdR;
    }

    if (GotoPit)
        is_pitting = 1;
    else
        is_pitting = 0;

    return GotoPit;
#else
    if (remainlaps > 0)
    {
        float cmpfuel = (m_fuelperlap == 0.0) ? m_expectedfuelperlap : m_fuelperlap;
        if (car->_fuel < 2.5*cmpfuel &&
                car->_fuel < remainlaps*cmpfuel)
        {
            is_pitting = 1;
            pit_reason = REASON_FUEL;
            return true;
        }
        else if (remainlaps < 20)
            this_pit_dammage = MIN(8000, PitDamage + (20-remainlaps)*200);
    }

    if (isPitFree(car))
    {
        // don't pit for damage if getting close to end
        if (car->_dammage < MAX(PitDamage/2, 9500 - remainlaps*1000))
        {
            is_pitting = 0;
            return false;
        }

        // Ok, otherwise do we need to repair?
        if (car->_dammage >= PitDamage)
        {
            is_pitting = 1;
            pit_reason = REASON_DAMAGE;
            return true;
        }

        // Can we safely repair a lesser amount of damage?
        int canrepair_damage;
        pit_reason = REASON_NONE;

        if ((canrepair_damage = calcRepair(car, s, opp, 0)) >= PitDamage/2)
        {
            if (car->_pos < 6)
            {
                // if there's a chance of overtaking an opponent that's
                // not far in front, avoid going in to fix optional damage.
                for (int i = 0; i < opp->getNOpponents(); i++)
                {
                    Opponent *o = opp->getOpponentPtr() + i;
                    tCarElt *ocar = o->getCarPtr();
                    if (ocar->_pos >= car->_pos) continue;
                    if (o->getTeam() == TEAM_FRIEND) continue;

                    if (o->getDistance() < 200.0 && car->_dammage < ocar->_dammage + 1500 && car->_dammage < PitDamage)
                    {
                        // close behind opponent, so lets not pit for damage purposes
                        return false;
                    }
                }
            }

            if (is_pitting)
                pit_damage = MIN(car->_dammage, MAX(pit_damage, canrepair_damage));
            else
                pit_damage = MIN(car->_dammage, MIN(pit_damage, canrepair_damage));
            is_pitting = 1;
            pit_reason = REASON_DAMAGE;
            return true;
        }
    }

    is_pitting = 0;
    return false;
#endif
}
Exemplo n.º 2
0
bool SimpleStrategy::needPitstop(tCarElt* car, tSituation *s)
{
    int m_maxDamage = PIT_DAMMAGE;
    float attvalue = 0.0f;
    // load defined value in xml file of Max Dammage before pitstops for this track
    //attvalue = GfParmGetNum(car->_carHandle, BT_SECT_PRIV, BT_ATT_MAXDAMMAGE, (char*) NULL, PIT_DAMMAGE);
    m_maxDamage = (int)attvalue;
    // Estimated average fuel per lap
    //m_Fuel = GfParmGetNum(car->_carHandle, BT_SECT_PRIV, BT_ATT_FUELPERLAP, (char*) NULL, m_expectedfuelperlap);

    double minFuelFactor;
    minFuelFactor = 1.8;
    if (shortTrack)
    {
        minFuelFactor = 2.15;
    }
    if (qualifRace)
    {
        minFuelFactor = 0.99;
    }

    /* Question makes only sense if there is a pit. */
    if(car->_pit != NULL)
    {
        /* Ideally we shouldn't pit on the last lap...
          just get to the finish line somehow. */
        int lapsToEnd = car->_remainingLaps - car->_lapsBehindLeader;
        if(lapsToEnd > 0)
        {
            // Do we need to refuel?
            double cmpfuel = (fuelPerLap == 0.0f) ? m_expectedfuelperlap : fuelPerLap;
            double reqfuel = lapsToEnd * cmpfuel;

            if(car->_fuel < fuelPerLap * minFuelFactor && car->_fuel < lapsToEnd * fuelPerLap)
            {
                if (!m_checkFuel)
                {
                    GfOut("%s Go to Pit the next lap to refuel: reqFuel=%.2f, carFuel=%.2f, remLap=%d\n",
                          car->_name, reqfuel, car->_fuel, car->_remainingLaps);
                    m_checkFuel = true;
                }
                return true;
            }

            // Do we need to repair and is the pit free?
            needRepair = false;
            if (car->_dammage > m_maxDamage && isPitFree(car))
            {
                needRepair = true;
                if(laps_to_go(car) > 5)
                {
                    if (!m_checkDamage)
                    {
                        GfOut("%s >> Max_damage: %d Car_damage: %d Laps_toGo: %d\n",
                              car->_name, m_maxDamage, car->_dammage, laps_to_go(car));
                        m_checkDamage = true;
                    }
                    return true;
                } else if(laps_to_go(car) <= 5)
                {
                    if(car->_dammage > MAX_DAMAGE)
                    {
                        quickPitstop = true;
                        return true;
                    } else
                    {
                        if (!m_checkDamage)
                        {
                            GfOut("%s Dont Stop At Pit!> Laps_toGo:%d  Car_damage: %d Max_damage: %d\n",
                                  car->_name, laps_to_go(car), car->_dammage, m_maxDamage);
                            m_checkDamage = true;
                            needRepair = false;
                        }
                    }
                }

            }
        }
    }

    return false;
}