ldc-legaulois/app/Enums/Games/GamePointLevel.php
2024-09-13 16:56:09 +02:00

128 lines
3 KiB
PHP

<?php
namespace App\Enums\Games;
use App\Traits\Enums\BaseEnum;
use Illuminate\Support\Facades\Vite;
enum GamePointLevel: int
{
use BaseEnum;
case egg = 1;
case hatchedEgg = 2;
case chick = 3;
case hen = 4;
case chicken = 5;
/**
* Optionnal labels definition.
*
* @phpstan-ignore-next-line
*/
private const LABELS = [
self::egg->name => 'oeuf',
self::hatchedEgg->name => 'oeuf éclos',
self::chick->name => 'poussin',
self::hen->name => 'poule',
self::chicken->name => 'poulet',
];
/**
* Point levels definition.
*/
private const LEVELS = [
self::egg->name => 0,
self::hatchedEgg->name => 50,
self::chick->name => 130,
self::hen->name => 230,
self::chicken->name => 1000,
];
/**
* Get Level
*
* @return integer
*/
public function level(): int
{
return self::LEVELS[$this->name];
}
/**
* Get picture
*
* @return string
*/
public function picture(): string
{
return Vite::asset("resources/assets/images/club/game-points/{$this->name()}.png");
}
/**
* Get enum Levels
*
* @return array<integer>
*/
public static function toLevels(): array
{
return self::LEVELS;
}
/**
* Get Level from point value
*
* @param integer $points
* @return \App\Enums\Games\GamePointLevel
*/
public static function fromPoints(int $points): self
{
$levels = array_reverse(self::all());
foreach ($levels as $level) {
if ($points >= $level->level()) {
return $level;
}
}
// * This should not happen while egg level is 0
return self::egg;
}
/**
* Next Level
*
* @param integer $points
* @return \App\Enums\Games\GamePointLevel|null
*/
public static function fromPointsNextLevel(int $points): self|null
{
$currentLevel = self::fromPoints($points);
return collect(self::all())
->filter(fn ($level) => $level->level() > $currentLevel->level())
->first();
}
/**
* Percent from points
*
* @param integer $points
* @return float
*/
public static function percentFromPoints(int $points): float
{
$levels = collect(self::toValues());
$level = self::fromPoints($points);
$nextLevel = self::fromPointsNextLevel($points);
if (!$nextLevel) {
return 100;
}
// * Bars between 2 levels
$ratio = 4;
$percentBetween2Levels = 100 / ($levels->count() - 1);
$adjustment = $percentBetween2Levels *
($nextLevel->level() - $points) / ($nextLevel->level() - $level->level());
return round((($level->value() * 100) / $levels->last()) + $percentBetween2Levels - $adjustment);
}
}