ES
games/sorcery / src / Data / Hall.php · commit 613f5fb
<?phpnamespace App\Data;/** The hall of fame: the table of today (in memory) and the all-time table (persisted). A port of modern/src/hall.cpp. */final class Hall{    public const NAME_MAX = 16;    private const LETTERS = '<>!ABCDEFGHIJKLMNOPQRSTUVWXYZ.';    public const NUM_LETTERS = 30;    /** @var array<int, array{0: string, 1: int}> */    private array $today = [];    /** @var array<int, array{0: string, 1: int}> */    private array $allTime = [];    public function __construct(private Assets $A, private \JumPHP\Save\Storage $storage)    {        $this->today = $A->hallToday;        $saved = $this->storage->readJson('sorcery-halloffame.json');        $this->allTime = is_array($saved) && $saved !== [] ? $saved : $A->hallAllTime;    }    /** @return array<int, array{0: string, 1: int}> */    public function today(): array    {        return $this->today;    }    /** @return array<int, array{0: string, 1: int}> */    public function allTime(): array    {        return $this->allTime;    }    /** The typed letters become the name: the '.' key is a space, forbidden words are replaced. */    public function clean(string $typed): string    {        $n = str_replace('.', '', $typed);        $i = 0;        foreach ($this->A->forbiddenNames as $w) {            if (strlen($n) >= strlen($w) && substr($n, 0, strlen($w)) === $w) {                return str_replace('.', ' ', $this->A->replacementNames[$i + 1] ?? $n);            }            $i++;        }        return $n === '' ? 'QUI EST LA?' : $n;    }    /** The place of a score in a table (0 = best), or -1. Equal scores: the older entry stays above. */    public function rank(int $score, bool $allTime): int    {        $t = $allTime ? $this->allTime : $this->today;        foreach ($t as $i => $e) {            if ($e[1] < $score) {                return $i;            }        }        return -1;    }    /** Inserts {name, score} into both tables (if it is good enough). */    public function insert(string $name, int $score): void    {        foreach ([false, true] as $all) {            $rank = $this->rank($score, $all);            if ($rank < 0) {                continue;            }            $t = $all ? $this->allTime : $this->today;            array_splice($t, $rank, 0, [[$name, $score]]);            array_splice($t, 7);            if ($all) {                $this->allTime = $t;                $this->storage->writeJson('sorcery-halloffame.json', $t);            } else {                $this->today = $t;            }        }    }}