Last active
September 1, 2022 16:05
-
-
Save marhei/c264e204105ffe15bb211b561f15dce4 to your computer and use it in GitHub Desktop.
Ermittlung der besten Bewerbung für eine Ausschreibung
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* TrainCompany - Criteria.enum.php | |
* | |
* @author Marcel Heisinger | |
*/ | |
namespace Game\Task\Application; | |
use Game\Task\{Application, Schedule}; | |
enum Criteria { | |
case Time; // Fahrzeiten (unrealistische Fahrzeiten werden nicht berücksichtigt) | |
case Capacity; // Kapazität | |
case Drive; // Antrieb | |
case Kilometers; // Kilometer des Users | |
case Service; // Das Service-Level des Auftrags und der Fahrzeuge | |
/** | |
* Zieht den Wert für das jeweilige Kriterium aus der Ausschreibung | |
* | |
* @param Application $application description | |
* | |
* @return int description | |
*/ | |
public function getValue(Application $app): ?int { | |
return match($this) { | |
static::Time => max($app->schedule->getFullTime()->toInt(), Schedule::fromApplication($app)->getFullTime()->toInt()), | |
static::Capacity => $app->trainUnit->getFullCapacity(array_keys($app->task->neededCapacity)), | |
static::Drive => $app->trainUnit->getDrive()->getFactor($app->pathUnit->electrified), | |
static::Kilometers => $app->user->getKilometers(), | |
static::Service => $app->task->service->preferMatchingTrain() ? $app->trainUnit->getService()?->value : NULL, | |
}; | |
} | |
/** | |
* Gibt die Gewichtung der verschiedenen Kriterien zurück | |
* | |
* @return int | |
*/ | |
public function getWeighting(): int { | |
return match($this) { | |
static::Capacity => 3, | |
static::Service, | |
static::Time => 2, | |
default => 1 | |
}; | |
} | |
/** | |
* Sortiert die Arrays in der richtigen Reihenfolge | |
* | |
* @param array $array | |
* | |
* @return void | |
*/ | |
public function sort(array &$array): void { | |
match($this) { | |
static::Time, | |
static::Service, | |
static::Kilometers => asort($array), | |
static::Capacity, | |
static::Drive => arsort($array) | |
}; | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* TrainCompany - Drive.enum.php | |
* Antrieb des Fahrzeuges | |
* | |
* @author Marcel Heisinger | |
*/ | |
namespace Game\Train; | |
use Game\Path\Unit; | |
enum Drive: int { | |
use \Core\Enum; | |
case Without = 0; | |
case Electro = 1; | |
case Diesel = 2; | |
case Battery = 3; | |
case DualMode = 4; | |
case Hydrogen = 5; | |
case LastMile = 6; | |
case Steam = 7; | |
/** -- verkürzt -- **/ | |
/** | |
* Gibt den Faktor bei der Bewerbungsauswahl zurück | |
* | |
* @param bool $electrified | |
* | |
* @return float | |
*/ | |
public function getFactor(bool $electrified): int { | |
return match($this) { | |
static::Electro => 10, | |
static::Battery => $electrified ? 9 : 10, | |
static::LastMile, | |
static::DualMode => $electrified ? 8 : 10, | |
static::Diesel => $electrified ? 7 : 8, | |
static::Hydrogen => $electrified ? 8 : 10, | |
static::Steam => 5, | |
default => 0, | |
}; | |
} | |
/** -- verkürzt -- **/ | |
} | |
?> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* TrainCompany - Service.enum.php | |
* Servicelevel einer Ausschreibung | |
* | |
* @author Marcel Heisinger | |
*/ | |
namespace Game\Task; | |
enum Service: int { | |
case Highspeed = 0; | |
case Intercity = 1; | |
case Regional = 2; | |
case ShortRegional = 3; | |
case Special = 4; | |
case FreightImportant = 10; | |
case Freight = 11; | |
/** | |
* Gibt den Namen des Service zurück | |
* | |
* @return string | |
*/ | |
public function getName(): string { | |
return match($this) { | |
static::Highspeed => 'HGV', | |
static::Intercity => 'IC', | |
static::Regional => 'RE/RB', | |
static::ShortRegional => 'S-Bahn', | |
static::Special => 'Sonderzug', | |
static::FreightImportant=> 'hochwertiger GV', | |
static::Freight => 'GV', | |
}; | |
} | |
/** | |
* Gibt den Faktor zur Preiserstellung zurück | |
* | |
* @return float | |
*/ | |
public function getFactor(): float { | |
return match($this) { | |
static::FreightImportant => 1.3, | |
static::Highspeed, static::Freight => 1.2, | |
static::Intercity, static::Special => 1.1, | |
static::Regional, static::ShortRegional => 1.5, | |
}; | |
} | |
/** | |
* Gibt an wie lange eine DV angeboten wird | |
* | |
* @return int | |
*/ | |
public function getEndTime(): int { | |
return match($this) { | |
static::FreightImportant, static::Freight => 3600, | |
default => 1200 | |
}; | |
} | |
/** | |
* Gibt an ob für diesen Service passende Fahrzeuge bevorzugt werden sollen. | |
* | |
* @return bool | |
*/ | |
public function preferMatchingTrain(): bool { | |
return match($this) { | |
static::Highspeed, | |
static::Intercity => true, | |
default => false | |
}; | |
} | |
} | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* TrainCompany - Task.class.php | |
* | |
* @author Marcel Heisinger | |
*/ | |
namespace Game; | |
use Game\{Train\Drive, Path\Unit, Train\Unit\Weight}; | |
use Game\Task\{Journey, Difficulty, Type, Service, Application, | |
Application\Manager as ApplicationManager, | |
Journey\Manager as JourneyManager | |
}; | |
use Core\{Format, Time\Duration}; | |
class Task implements \Core\Access\Accessable, \Core\Manager\Managable { | |
use Station\Tools, \Core\Access; | |
/** -- verkürzt -- **/ | |
/** | |
* Gibt die beste Bewerbung für diese Ausschreibung zurück | |
* | |
* @return ?Application | |
*/ | |
public function getBestApplication(): ?Application { | |
// Bei Direktvergaben gibt es keine beste Ausschreibung | |
if($this->type->isDirect()) return NULL; | |
// Nur abgeschlossene Bewerbungen berücksichtigen | |
$applications = array_filter(ApplicationManager::iFor($this->id)->toArray(true), fn(Application $a): bool => $a->finished); | |
// Keine abgeschlossene Bewerbungen? | |
if(!count($applications)) return NULL; | |
// Array zufällig sortieren um frühere Bewerbungen nicht zu bevorteilen | |
shuffle($applications); | |
// Bewerbungen sortieren | |
usort($applications, function(Application $a, Application $b): int { | |
// Kriterien durchgehen | |
$values = []; | |
foreach(Application\Criteria::cases() as $criteria) { | |
[$av, $bv] = $value = array_map(fn(Application $a): ?int => $criteria->getValue($a), [$a, $b]); | |
// Wenn gleiches Value, dann Kriterium ignorieren | |
if($av == $bv) continue; | |
// Null rauslöschen | |
$value = array_filter($value, fn($v): bool => !is_null($v)); | |
// Sortieren und Gewinner hinzufügen | |
$criteria->sort($value); | |
for($i=0;$i<$criteria->getWeighting();$i++) $values[] = array_key_first($value); | |
} | |
// Wer hat den ersten Platz? | |
$keys = array_count_values($values); | |
return ($keys[1] ?? 0) <=> ($keys[0] ?? 0); | |
}); | |
// Platz 1 zurückgeben | |
return $applications[array_key_first($applications)]; | |
} | |
/** -- verkürzt -- **/ | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment