Parcourir la source

Introduces game creation command

Adds a new command to create a game, including galaxy generation.
Refactors galaxy generation into a GameFactory.
Updates entity relationships to support game creation.
olinox14 il y a 2 mois
Parent
commit
5a8a141a77

+ 2 - 2
api/src/Commands/GalaxyGenerateCommand.php → api/src/Commands/MakeGalaxyCommand.php

@@ -13,10 +13,10 @@ use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 
 #[AsCommand(
-    name: 'astra:galaxy:generate',
+    name: 'astra:make:galaxy',
     description: 'Génère une nouvelle galaxie avec le nombre de secteurs spécifié'
 )]
-class GalaxyGenerateCommand extends Command
+class MakeGalaxyCommand extends Command
 {
     public function __construct(
         private readonly GalaxyFactory $galaxyFactory,

+ 120 - 0
api/src/Commands/MakeGameCommand.php

@@ -0,0 +1,120 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Commands;
+
+use App\Services\GalaxyFactory;
+use App\Services\GameFactory;
+use Doctrine\ORM\EntityManagerInterface;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+#[AsCommand(
+    name: 'astra:make:game',
+    description: 'Génère une nouvelle partie'
+)]
+class MakeGameCommand extends Command
+{
+    public function __construct(
+        private readonly GameFactory $gameFactory,
+        private readonly EntityManagerInterface $entityManager
+    ) {
+        parent::__construct();
+    }
+
+    protected function configure(): void
+    {
+        $this
+            ->addOption(
+                'sectors',
+                's',
+                InputOption::VALUE_OPTIONAL,
+                'Nombre de secteurs à générer pour la galaxie',
+                1000
+            )
+            ->addOption(
+                'name',
+                null,
+                InputOption::VALUE_OPTIONAL,
+                'Nom du jeu et de la galaxie à générer',
+                'New Game'
+            )
+            ->setHelp('Créé une nouvelle partie de Astra Corp');
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+
+        $sectors = (int) $input->getOption('sectors');
+        $name = $input->getOption('name');
+
+        if (!$name) {
+            $io->error('Le nom du jeu est requis. Utilisez l\'option --name');
+            return Command::FAILURE;
+        }
+
+        if ($sectors <= 0) {
+            $io->error('Le nombre de secteurs doit être supérieur à 0');
+            return Command::FAILURE;
+        }
+
+        // Vérifier si une galaxie avec ce nom existe déjà
+        $existingGalaxy = $this->entityManager->getRepository(\App\Entity\Galaxy::class)
+            ->findOneBy(['name' => $name]);
+
+        if ($existingGalaxy) {
+            $io->error(sprintf('Une galaxie avec le nom "%s" existe déjà', $name));
+            return Command::FAILURE;
+        }
+
+        $io->title('Génération de la galaxie');
+        $io->text(sprintf('Nom : %s', $name));
+        $io->text(sprintf('Nombre de secteurs : %d', $sectors));
+
+        // Créer la galaxie
+        $game = $this->gameFactory->createGame($name, $sectors);
+        $galaxy = $game->getGalaxy();
+
+        // Sauvegarder en base de données
+        $io->text('Sauvegarde en base de données...');
+
+        $this->entityManager->persist($galaxy);
+        $this->entityManager->flush();
+
+        $io->success(sprintf(
+            'Galaxie "%s" générée avec succès ! %d secteurs créés avec %d systèmes au total.',
+            $name,
+            $galaxy->getSectors()->count(),
+            $galaxy->getSectors()->count() * GalaxyFactory::SYSTEMS_PER_SECTOR
+        ));
+
+        // Statistiques détaillées
+        $totalSystems = 0;
+        $totalPlanets = 0;
+
+        foreach ($galaxy->getSectors() as $sector) {
+            $totalSystems += $sector->getSystems()->count();
+            foreach ($sector->getSystems() as $system) {
+                $totalPlanets += $system->getPlanets()->count();
+            }
+        }
+
+        $io->section('Statistiques de génération');
+        $io->table(
+            ['Élément', 'Quantité'],
+            [
+                ['Secteurs', $galaxy->getSectors()->count()],
+                ['Systèmes', $totalSystems],
+                ['Planètes', $totalPlanets],
+                ['ID de la galaxie', $galaxy->getId()],
+            ]
+        );
+
+        return Command::SUCCESS;
+    }
+}

+ 2 - 2
api/src/Entity/Galaxy.php

@@ -21,10 +21,10 @@ class Galaxy
     private string $name;
 
     /** @var Collection<int, Sector> */
-    #[ORM\OneToMany(targetEntity: Sector::class, mappedBy: 'galaxy', orphanRemoval: true, cascade: ['persist', 'remove'])]
+    #[ORM\OneToMany(targetEntity: Sector::class, mappedBy: 'galaxy', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $sectors;
 
-    #[ORM\OneToOne(inversedBy: 'galaxy', targetEntity: Game::class)]
+    #[ORM\OneToOne(targetEntity: Game::class, inversedBy: 'galaxy')]
     #[ORM\JoinColumn(nullable: true)]
     private ?Game $game = null;
 

+ 14 - 0
api/src/Entity/Game.php

@@ -34,6 +34,9 @@ class Game
     #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
     private ?\DateTimeImmutable $openedAt = null;
 
+    #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
+    private ?\DateTimeImmutable $closedAt = null;
+
     public function __construct()
     {
         $this->players = new ArrayCollection();
@@ -114,4 +117,15 @@ class Game
         $this->status = $status;
         return $this;
     }
+
+    public function getClosedAt(): ?\DateTimeImmutable
+    {
+        return $this->closedAt;
+    }
+
+    public function setClosedAt(?\DateTimeImmutable $closedAt): self
+    {
+        $this->closedAt = $closedAt;
+        return $this;
+    }
 }

+ 2 - 1
api/src/Entity/Sector.php

@@ -5,6 +5,7 @@ namespace App\Entity;
 
 use ApiPlatform\Metadata\ApiResource;
 use App\Enum\SectorStatusEnum;
+use App\Enum\StartingStateEnum;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -27,7 +28,7 @@ class Sector
     private string $name;
 
     /** @var Collection<int, System> */
-    #[ORM\OneToMany(targetEntity: System::class, mappedBy: 'sector', orphanRemoval: true, cascade: ['persist', 'remove'])]
+    #[ORM\OneToMany(targetEntity: System::class, mappedBy: 'sector', cascade: ['persist', 'remove'], orphanRemoval: true)]
     private Collection $systems;
 
     #[ORM\ManyToOne(targetEntity: Galaxy::class, inversedBy: 'sectors')]

+ 16 - 0
api/src/Services/CivilizationFactory.php

@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Services;
+
+use App\Entity\Galaxy;
+
+/**
+ * Génère une civilisation préalable dans une galaxie vierge
+ */
+class CivilizationFactory
+{
+    public function populate(Galaxy $galaxy) {
+
+    }
+}

+ 37 - 0
api/src/Services/GameFactory.php

@@ -0,0 +1,37 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Services;
+
+use App\Entity\Game;
+use App\Enum\GameStatusEnum;
+
+class GameFactory
+{
+    public function __construct(
+        private readonly GalaxyFactory $galaxyFactory
+    ) {}
+
+    public function createGame(string $name, int $nbSectors = 1000): Game {
+        $game = new Game();
+        $game->setName($name);
+
+        $galaxy = $this->galaxyFactory->createGalaxy($nbSectors, $name);
+
+        $game->setGalaxy($galaxy);
+        return $game;
+    }
+
+    public function openGame(Game $game): Game {
+        $game->setOpenedAt(new \DateTimeImmutable());
+        $game->setStatus(GameStatusEnum::OPEN);
+        return $game;
+    }
+
+    public function closeGame(Game $game): Game {
+        $game->setClosedAt(new \DateTimeImmutable());
+        $game->setStatus(GameStatusEnum::CLOSED);
+        return $game;
+    }
+
+}