fix: generate hints about the row actor, not the main actor

Hints should help identify the row actor (to find the highlighted letter),
not reveal the main actor directly. Simplified hint generation: no shared
exclusion pools needed since each row has a different actor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thibaud-leclere
2026-03-30 22:51:22 +02:00
parent 8d413b5c57
commit 273ea49ed0

View File

@@ -33,9 +33,6 @@ class GameGridGenerator
$usedActors = [$mainActor->getId()];
$rowOrder = 0;
$usedMovieRoleIds = [];
$usedHintKeys = [];
$cachedAwards = null;
foreach (str_split(strtolower($mainActor->getName())) as $char) {
if (!preg_match('/[a-z]/', $char)) {
@@ -58,7 +55,7 @@ class GameGridGenerator
$row->setPosition(strpos(strtolower($actor->getName()), $char));
$row->setRowOrder($rowOrder);
$hint = $this->generateHint($mainActor, $usedMovieRoleIds, $usedHintKeys, $cachedAwards);
$hint = $this->generateHint($actor);
if ($hint !== null) {
$row->setHintType($hint['type']);
$row->setHintData($hint['data']);
@@ -135,17 +132,17 @@ class GameGridGenerator
}
/**
* @param list<int> $usedMovieRoleIds MovieRole IDs already used (for DB exclusion)
* @param list<string> $usedHintKeys Semantic keys like "film:42" to avoid duplicate hints
* Generate a single hint for a row actor.
*
* @return array{type: string, data: string}|null
*/
private function generateHint(Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys, ?array &$cachedAwards): ?array
private function generateHint(Actor $rowActor): ?array
{
$types = ['film', 'character', 'award'];
shuffle($types);
foreach ($types as $type) {
$hint = $this->resolveHint($type, $mainActor, $usedMovieRoleIds, $usedHintKeys, $cachedAwards);
$hint = $this->resolveHint($type, $rowActor);
if ($hint !== null) {
return $hint;
}
@@ -155,63 +152,34 @@ class GameGridGenerator
}
/**
* @param list<int> $usedMovieRoleIds
* @param list<string> $usedHintKeys
* @return array{type: string, data: string}|null
*/
private function resolveHint(string $type, Actor $mainActor, array &$usedMovieRoleIds, array &$usedHintKeys, ?array &$cachedAwards): ?array
private function resolveHint(string $type, Actor $rowActor): ?array
{
switch ($type) {
case 'film':
$role = $this->movieRoleRepository->findOneRandomByActor(
$mainActor->getId(),
$usedMovieRoleIds,
);
$role = $this->movieRoleRepository->findOneRandomByActor($rowActor->getId());
if ($role === null) {
return null;
}
$movieId = (string) $role->getMovie()->getId();
$key = 'film:' . $movieId;
if (in_array($key, $usedHintKeys)) {
return null;
}
$usedMovieRoleIds[] = $role->getId();
$usedHintKeys[] = $key;
return ['type' => 'film', 'data' => $movieId];
return ['type' => 'film', 'data' => (string) $role->getMovie()->getId()];
case 'character':
$role = $this->movieRoleRepository->findOneRandomByActor(
$mainActor->getId(),
$usedMovieRoleIds,
);
$role = $this->movieRoleRepository->findOneRandomByActor($rowActor->getId());
if ($role === null) {
return null;
}
$roleId = (string) $role->getId();
$key = 'character:' . $roleId;
if (in_array($key, $usedHintKeys)) {
return null;
}
$usedMovieRoleIds[] = $role->getId();
$usedHintKeys[] = $key;
return ['type' => 'character', 'data' => $roleId];
return ['type' => 'character', 'data' => (string) $role->getId()];
case 'award':
if ($cachedAwards === null) {
try {
$cachedAwards = $this->wikidataAwardGateway->getAwards($mainActor);
$awards = $this->wikidataAwardGateway->getAwards($rowActor);
} catch (\Throwable) {
$cachedAwards = [];
return null;
}
}
foreach ($cachedAwards as $award) {
$text = $award['name'] . ' (' . $award['year'] . ')';
$key = 'award:' . $text;
if (!in_array($key, $usedHintKeys)) {
$usedHintKeys[] = $key;
return ['type' => 'award', 'data' => $text];
}
if (!empty($awards)) {
$award = $awards[array_rand($awards)];
return ['type' => 'award', 'data' => $award['name'] . ' (' . $award['year'] . ')'];
}
return null;
}