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