/** * Set participants and session type on a session instance * * @param Session $session * @param array $data */ protected function setParticipantsAndSessionType(Session $session, array $data) { // Init participants array $participants = array(); // Collect drivers in array $driver_data_array = array(); // No grid position by default $set_grid_position = false; foreach ($data as $key => $driver_data) { // Not a driver driver_data if (!preg_match('/slot([0-9]+)/i', $key, $matches)) { continue; } // No qualtime if (!array_key_exists('qualtime', $driver_data)) { // Create qualtime, we need it for easier closure usage $driver_data['qualtime'] = null; } else { $set_grid_position = true; } $driver_data_array[] = $driver_data; } // Set grid positions if ($set_grid_position) { // Sort drivers by qualify time to figure out grid positions usort($driver_data_array, function ($a, $b) { // Same time if ($a['qualtime'] === $b['qualtime']) { return 0; } // a has no time if (!$a['qualtime']) { // $b is faster return 1; } // b has no time if (!$b['qualtime']) { // $a is faster return -1; } return $a['qualtime'] < $b['qualtime'] ? -1 : 1; }); // Set grid positions foreach ($driver_data_array as $driver_key => &$driver_data_array_item) { $driver_data_array_item['grid_position'] = $driver_key + 1; } unset($driver_data_array_item); } // All participants are dnf by default $all_dnf = true; // Loop each driver foreach ($driver_data_array as $driver_data) { // Create driver $driver = new Driver(); $driver->setName($driver_data['driver']); // Create participant and add driver $participant = Participant::createInstance(); $participant->setDrivers(array($driver))->setTeam(Helper::arrayGet($driver_data, 'team')); // Finish position will be set later using an special // sort // We have laps and must set grid positions if (Helper::arrayGet($driver_data, 'laps_collection') and $set_grid_position) { $participant->setGridPosition($driver_data['grid_position']); } // Create vehicle and add to participant $vehicle = new Vehicle(); $vehicle->setName(Helper::arrayGet($driver_data, 'vehicle')); $participant->setVehicle($vehicle); // Has race time information if ($race_time = Helper::arrayGet($driver_data, 'racetime')) { // Not dnf by default if it's not 0:00:00.000 or dnf $set_dnf = ($race_time === '0:00:00.000' or $race_time === 'DNF'); // Try setting seconds if not dnf if (!$set_dnf) { try { // Get seconds $seconds = Helper::secondsFromFormattedTime($race_time); // Set total time $participant->setTotalTime($seconds); // Is finished $participant->setFinishStatus(Participant::FINISH_NORMAL); $all_dnf = false; } catch (\InvalidArgumentException $ex) { $set_dnf = true; } } // Should set this participant dnf if ($set_dnf) { $participant->setFinishStatus(Participant::FINISH_DNF); // Has reason if (null !== ($reason = Helper::arrayGet($driver_data, 'reason'))) { $participant->setFinishComment("DNF (reason {$reason})"); } } } // Laps count not found if (null === ($laps_count = Helper::arrayGet($driver_data, 'laps'))) { // Try racelaps key $laps_count = Helper::arrayGet($driver_data, 'racelaps'); } // Has run laps if ($laps_count !== null and $laps_count > 0) { // Get laps collection $laps_collection = Helper::arrayGet($driver_data, 'laps_collection'); // Loop laps by lap count due to missing laps in results // so we can fill up the gaps for ($lap_i = 1; $lap_i <= $laps_count; $lap_i++) { // Init new lap $lap = new Lap(); // Set participant $lap->setParticipant($participant); // Set first driver of participant as lap driver. Race07 does // not support swapping $lap->setDriver($participant->getDriver()); // Set lap number $lap->setNumber($lap_i); // Is first lap if ($lap->getNumber() === 1) { // Set grid position as lap position $lap->setPosition(Helper::arrayGet($driver_data, 'grid_position')); } // Lap data exists if (isset($laps_collection[$lap_i])) { // Get lap data $lap_data = $laps_collection[$lap_i]; // Set lap times $lap->setTime($lap_data['time'])->setElapsedSeconds($lap_data['elapsed_time']); $all_laps_missing = false; } // Add lap to participant $participant->addLap($lap); } // All laps missing but has best lap if (sizeof($laps_collection) === 0 and ($racebestlap = Helper::arrayGet($driver_data, 'racebestlap') or $racebestlap = Helper::arrayGet($driver_data, 'bestlap'))) { // Get first lap and change time $participant->getLap(1)->setTime(Helper::secondsFromFormattedTime($racebestlap)); } } // Add participant to collection $participants[] = $participant; } // All participants are dnf if ($all_dnf) { // Assume we're dealing with qualify session $session->setType(Session::TYPE_QUALIFY); $session->setName('Qualify or practice session'); } else { // Race session $session->setType(Session::TYPE_RACE); } // Sort participants $this->sortParticipantsAndFixPositions($participants, $session); // Set participants on session $session->setParticipants($participants); }
/** * Get a Session instance populated with test data. * * NOTE: Every time this method is ran, a different instance will be * returned! Keep this in mind when comparing things by reference * * @return Session */ protected function getSessionWithData() { // Create new session $session = new Session(); // Participants testdata array $participants_data = array(array('position' => 1, 'vehicle' => array('class' => 'class1'), 'laps' => array(array('time' => 130.7517, 'sectors' => array(53.2312, 32.299, 45.2215), 'position' => 1), array('time' => 125.2989, 'sectors' => array(47.4511, 32.063, 45.7848), 'position' => 1), array('time' => 123.3179, 'sectors' => array(46.6382, 32.0084, 44.6712), 'position' => 1))), array('position' => 2, 'vehicle' => array('class' => 'class3'), 'laps' => array(array('time' => 130.9077, 'sectors' => array(54.0223, 32.3176, 44.5677), 'position' => 2), array('time' => 125.6976, 'sectors' => array(47.5271, 32.4621, 45.7083), 'position' => 2), array('time' => 126.062, 'sectors' => array(47.7989, 32.7721, 45.491), 'position' => 2))), array('position' => 3, 'vehicle' => array('class' => 'class2'), 'laps' => array(array('time' => 134.8484, 'sectors' => array(56.0119, 32.4913, 46.3452), 'position' => 12), array('time' => 126.2454, 'sectors' => array(50.4389, 31.8827, 43.9237), 'position' => 3), array('time' => 122.0663, 'sectors' => array(46.2715, 31.8696, 43.9252), 'position' => 3))), array('position' => 4, 'vehicle' => array('class' => 'class1'), 'laps' => array(array('time' => 155.1491, 'sectors' => array(60.0119, 40.4913, 54.6459), 'position' => 4), array('time' => 156.1491, 'sectors' => array(60.0119, 40.4913, 55.6459), 'position' => 4))), array('position' => 5, 'vehicle' => array('class' => 'class2'), 'laps' => array()), array('position' => 6, 'vehicle' => array('class' => 'class3'), 'laps' => array(array('time' => null, 'sectors' => array(42.4389), 'position' => 6)))); // Loop each participant data foreach ($participants_data as $participant_data) { // Create the new participant and populate $participant = new Participant(); $participant->setPosition($participant_data['position']); $vehicle = new Vehicle(); $vehicle->setClass($participant_data['vehicle']['class']); $participant->setVehicle($vehicle); // Create each lap foreach ($participant_data['laps'] as $lap_key => $lap_data) { $lap = new Lap(); $lap->setTime($lap_data['time'])->setSectorTimes($lap_data['sectors'])->setNumber($lap_key + 1)->setPosition($lap_data['position'])->setParticipant($participant); // Add lap to participant $participant->addLap($lap); } // Add participant to session $session->addParticipant($participant); } // Return the session return $session; }
/** * Returns a populated participant with laps * * @return Participant */ protected function getParticipantWithLaps() { // Create new participant $participant = new Participant(); // Add some laps $lap = new Lap(); $participant->addLap($lap->setTime(128.211)->setSectorTimes(array(40.201, 33.5, 54.51))->setPosition(1)->setNumber(1)->setAids(array('PlayerControl' => null, 'TC' => 3))); $lap = new Lap(); $participant->addLap($lap->setTime(125.73)->setSectorTimes(array(39.601, 38.2, 47.929))->setPosition(2)->setNumber(2)->setAids(array('AutoShift' => 3))); $lap = new Lap(); $participant->addLap($lap->setTime(128.73)->setSectorTimes(array(40.601, 39.2, 48.929))->setPosition(2)->setNumber(2)->setAids(array('AutoShift' => 3))); $lap = new Lap(); $participant->addLap($lap->setTime(131.73)->setSectorTimes(array(41.601, 40.2, 49.929))->setPosition(2)->setNumber(2)->setAids(array('AutoShift' => 3))->setPitLap(true)); $lap = new Lap(); $participant->addLap($lap->setTime(155.73)->setSectorTimes(array(49.601, 48.2, 57.929))->setPosition(1)->setNumber(3)); // null lap as somtimes present in qualify sessions $lap = new Lap(); $participant->addLap($lap->setPosition(2)->setNumber(4)); return $participant; }
/** * Test calculating the pitstop times based on laps * * Pit time is calculated using 2 sectors that were part of the pitstop * (e.g. L1S3->L2S1) MINUS the averages of all non pitstop sectors. * * For inner understanding how these values are calculated, please see * the document `docs/RfactorReaderTest_testReadingPitTimes.ods` */ public function testCalculatingPitTimes() { // Init participant $participant = new Participant(); // Init new laps $laps = array(); // Normal lap $lap1 = new Lap(); $lap1->setSectorTimes(array(42.9237, 42.9237, 44.9237))->setParticipant($participant); $laps[] = $lap1; // Pit lap $lap2 = new Lap(); $lap2->setSectorTimes($lap2_sectors = array(41.9237, 42.9237, 53.9237))->setParticipant($participant)->setPitLap(true); $laps[] = $lap2; // Normal lap $lap3 = new Lap(); $lap3->setSectorTimes(array(51.9237, 42.9237, 56.9237))->setParticipant($participant); $laps[] = $lap3; // Set laps to participant $participant->setLaps($laps); //---- Validate pit times $this->assertSame(0, $lap1->getPitTime()); $this->assertSame(53.9237 - (44.9237 + 56.9237) / 2 + (51.9237 - (42.9237 + 41.9237) / 2), $lap2->getPitTime()); $this->assertSame(0, $lap3->getPitTime()); //---- Validate special cases // Invalidate participant cache $participant->invalidateAverageLapCache(); // Validate that when sector 3 is missing no calculation is done on that $lap2->setSectorTimes(array(41.9237, 42.9237, null)); $this->assertSame(51.9237 - (42.9237 + 41.9237) / 2, $lap2->getPitTime()); // Restore lap 2 sectors $lap2->setSectorTimes($lap2_sectors); //----- // Validate that when sector 1 of next lap is missing, any calculation // on that sector is ignored, thus pit time is only based on sector 3 // of this pit lap. This also validates ignoring multipe pit sectors // that should be ignored in the averages as we're now marking a // second lap as pit lap // Invalidate participant cache $participant->invalidateAverageLapCache(); // Set lap3 as pit lap $lap3->setPitLap(true); // Invalidate participant cache $participant->invalidateAverageLapCache(); // Check time $this->assertSame(56.9237 - 44.9237, $lap3->getPitTime()); //----- // Validate that calculation is done when hard pit time is available $lap2->setPitTime(21); $this->assertSame(21, $lap2->getPitTime()); }
public function testGettingVehicleWhenVehicleNotSetOnLap() { // Init participant $participant = Participant::createInstance(); // Set vehicle $participant->setVehicle($vehicle = new Vehicle()); // Normal lap without vehicle on lap itself $lap = new Lap(); $lap->setParticipant($participant); // Validate vehicle $this->assertSame($vehicle, $lap->getVehicle()); }
/** * Test sorting laps by sector */ public function testSortingLapsBySector() { // Init laps $laps = array(); $lap = new Lap(); $lap->setSectorTimes(array(100.2)); $laps[] = $lap; $lap = new Lap(); $lap->setSectorTimes(array(100.1)); $laps[] = $lap; $lap = new Lap(); $lap->setSectorTimes(array(103.5)); $laps[] = $lap; // Sort laps $laps = Helper::sortLapsBySector($laps, 1); // Get sector info $sectors1 = $laps[0]->getSectorTimes(); $sectors2 = $laps[1]->getSectorTimes(); $sectors3 = $laps[2]->getSectorTimes(); // Validate laps $this->assertSame(100.1, $sectors1[0]); $this->assertSame(100.2, $sectors2[0]); $this->assertSame(103.5, $sectors3[0]); }