feat: add GameGridGenerator service
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
100
src/Service/GameGridGenerator.php
Normal file
100
src/Service/GameGridGenerator.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Actor;
|
||||
use App\Entity\Game;
|
||||
use App\Entity\GameRow;
|
||||
use App\Entity\User;
|
||||
use App\Repository\ActorRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class GameGridGenerator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ActorRepository $actorRepository,
|
||||
private readonly EntityManagerInterface $em,
|
||||
) {}
|
||||
|
||||
public function generate(?User $user = null): Game
|
||||
{
|
||||
$mainActor = $this->actorRepository->findOneRandom(4);
|
||||
|
||||
$game = new Game();
|
||||
$game->setMainActor($mainActor);
|
||||
$game->setUser($user);
|
||||
|
||||
$usedActors = [$mainActor->getId()];
|
||||
$rowOrder = 0;
|
||||
|
||||
foreach (str_split(strtolower($mainActor->getName())) as $char) {
|
||||
if (!preg_match('/[a-z]/', $char)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tryFindActor = 0;
|
||||
do {
|
||||
$actor = $this->actorRepository->findOneRandom(4, $char);
|
||||
++$tryFindActor;
|
||||
} while (
|
||||
in_array($actor->getId(), $usedActors)
|
||||
|| $tryFindActor < 5
|
||||
);
|
||||
|
||||
$usedActors[] = $actor->getId();
|
||||
|
||||
$row = new GameRow();
|
||||
$row->setActor($actor);
|
||||
$row->setPosition(strpos(strtolower($actor->getName()), $char));
|
||||
$row->setRowOrder($rowOrder);
|
||||
|
||||
$game->addRow($row);
|
||||
++$rowOrder;
|
||||
}
|
||||
|
||||
$this->em->persist($game);
|
||||
$this->em->flush();
|
||||
|
||||
return $game;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute display data (grid, width, middle) from a Game entity for the React component.
|
||||
*
|
||||
* @return array{grid: list<array{actorName: string, actorId: int, pos: int}>, width: int, middle: int}
|
||||
*/
|
||||
public function computeGridData(Game $game): array
|
||||
{
|
||||
$leftSize = 0;
|
||||
$rightSize = 0;
|
||||
$grid = [];
|
||||
|
||||
foreach ($game->getRows() as $row) {
|
||||
$actor = $row->getActor();
|
||||
$pos = $row->getPosition();
|
||||
|
||||
if ($leftSize < $pos) {
|
||||
$leftSize = $pos;
|
||||
}
|
||||
|
||||
$rightSizeActor = strlen($actor->getName()) - $pos - 1;
|
||||
if ($rightSize < $rightSizeActor) {
|
||||
$rightSize = $rightSizeActor;
|
||||
}
|
||||
|
||||
$grid[] = [
|
||||
'actorName' => $actor->getName(),
|
||||
'actorId' => $actor->getId(),
|
||||
'pos' => $pos,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'grid' => $grid,
|
||||
'width' => $rightSize + $leftSize + 1,
|
||||
'middle' => $leftSize,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user