Skip to content

Commit

Permalink
Generate planet stats during colonization process
Browse files Browse the repository at this point in the history
  • Loading branch information
senghe committed Dec 11, 2023
1 parent eab4216 commit 0c2fc17
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 2 deletions.
7 changes: 7 additions & 0 deletions src/Application/Component/Galaxy/Domain/Entity/Planet.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace TheGame\Application\Component\Galaxy\Domain\Entity;

use TheGame\Application\Component\Galaxy\Domain\PlanetStats;
use TheGame\Application\SharedKernel\Domain\EntityId\PlanetIdInterface;
use TheGame\Application\SharedKernel\Domain\EntityId\PlayerIdInterface;

Expand All @@ -12,6 +13,7 @@ class Planet
public function __construct(
protected readonly PlanetIdInterface $planetId,
protected readonly PlayerIdInterface $playerId,
protected readonly PlanetStats $planetStats,
protected readonly int $position,
) {

Expand All @@ -36,4 +38,9 @@ public function getPosition(): int
{
return $this->position;
}

public function getStats(): PlanetStats
{
return $this->planetStats;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace TheGame\Application\Component\Galaxy\Domain\Factory;

use TheGame\Application\Component\Galaxy\Domain\Entity\Planet;
use TheGame\Application\Component\Galaxy\Domain\PlanetStatsRandomizer;
use TheGame\Application\Component\Galaxy\Domain\PlanetStatsRandomizerInterface;
use TheGame\Application\SharedKernel\Domain\EntityId\PlayerIdInterface;
use TheGame\Application\SharedKernel\Domain\GalaxyPointInterface;
use TheGame\Application\SharedKernel\UuidGeneratorInterface;
Expand All @@ -13,18 +15,23 @@ final class PlanetFactory implements PlanetFactoryInterface
{
public function __construct(
private readonly UuidGeneratorInterface $uuidGenerator,
private readonly PlanetStatsRandomizerInterface $planetStatsRandomizer,
) {

}

public function create(
PlayerIdInterface $playerId,
GalaxyPointInterface $galaxyPoint,
int $maxPlanetPosition,
): Planet {
$planetPosition = $galaxyPoint->getPlanet();

return new Planet(
$this->uuidGenerator->generateNewPlanetId(),
$playerId,
$galaxyPoint->getPlanet(),
$this->planetStatsRandomizer->randomize($planetPosition, $maxPlanetPosition),
$planetPosition,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ interface PlanetFactoryInterface
public function create(
PlayerIdInterface $playerId,
GalaxyPointInterface $galaxyPoint,
int $maxPlanetPosition,
): Planet;
}
18 changes: 18 additions & 0 deletions src/Application/Component/Galaxy/Domain/PlanetBiome.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace TheGame\Application\Component\Galaxy\Domain;

enum PlanetBiome: string
{
case Desert = 'desert';

case Jungle = 'jungle';

case Lava = 'lava';

case Magnetic = 'magnetic';

case Watery = 'watery';
}
36 changes: 36 additions & 0 deletions src/Application/Component/Galaxy/Domain/PlanetStats.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace TheGame\Application\Component\Galaxy\Domain;

class PlanetStats
{
public function __construct(
private readonly PlanetBiome $biome,
private readonly int $size,
private readonly int $minTemperature,
private readonly int $maxTemperature,
) {
}

public function getBiome(): PlanetBiome
{
return $this->biome;
}

public function getSize(): int
{
return $this->size;
}

public function getMinTemperature(): int
{
return $this->minTemperature;
}

public function getMaxTemperature(): int
{
return $this->maxTemperature;
}
}
71 changes: 71 additions & 0 deletions src/Application/Component/Galaxy/Domain/PlanetStatsRandomizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace TheGame\Application\Component\Galaxy\Domain;

final class PlanetStatsRandomizer implements PlanetStatsRandomizerInterface
{
public function randomize(int $planetPosition, int $maxPosition): PlanetStats
{
$biomes = PlanetBiome::cases();
$biome = $biomes[rand(0, count($biomes)-1)];
$fieldsNumber = $this->randomizeFieldsNumber($planetPosition, $maxPosition);
[$minTemperature, $maxTemperature] = $this->randomizeTemperature($planetPosition, $maxPosition);

return new PlanetStats(
$biome, $fieldsNumber, $minTemperature, $maxTemperature
);
}

private function randomizeFieldsNumber(int $planetPosition, int $maxPosition): int
{
$pivot = $planetPosition / $maxPosition;
$statsMetadata = [
[0.15, 45, 95],
[0.3, 45, 120],
[0.4, 120, 165],
[0.6, 120, 185],
[0.8, 150, 185],
[0.9, 185, 265],
[1.0, 235, 265],
];

$minFieldsNumber = $maxFieldsNumber = 0;
foreach ($statsMetadata as $metadata) {
$pivotBound = $metadata[0];
$minFieldsNumberBound = $metadata[1];
$maxFieldsNumberBound = $metadata[2];

if ($pivot < $pivotBound) {
$minFieldsNumber = $minFieldsNumberBound;
$maxFieldsNumber = $maxFieldsNumberBound;
break;
}
}

return rand($minFieldsNumber, $maxFieldsNumber);
}

/** @return int[] */
private function randomizeTemperature(int $planetPosition, int $maxPosition): array
{
$minPivot = ($planetPosition / $maxPosition) * 100;
$maxPivot = 100;

$lowerBounds = [-45, 145];
$higherBounds = [-5, 275];

$randPivot = rand($minPivot, $maxPivot) / 100;
$lowerTemperature = $lowerBounds[0] + $randPivot * $lowerBounds[1]-$lowerBounds[0];

$randPivot = rand($minPivot, $maxPivot) / 100;
$higherTemperature = $higherBounds[0] + $randPivot * $higherBounds[1]-$higherBounds[0];

if ($lowerTemperature > $higherTemperature) {
return [$higherTemperature, $lowerTemperature];
}

return [$lowerTemperature, $higherTemperature];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace TheGame\Application\Component\Galaxy\Domain;

interface PlanetStatsRandomizerInterface
{
public function randomize(int $planetPosition, int $maxPosition): PlanetStats;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace TheGame\Application\Component\Galaxy\EventListener;

use TheGame\Application\Component\Balance\Bridge\GalaxyContextInterface;
use TheGame\Application\Component\FleetJourney\Domain\Event\FleetHasReachedJourneyTargetPointEvent;
use TheGame\Application\Component\Galaxy\Domain\Event\PlanetHasBeenColonizedEvent;
use TheGame\Application\Component\Galaxy\Domain\Exception\PlanetAlreadyColonizedException;
Expand All @@ -21,6 +22,7 @@ public function __construct(
private readonly SolarSystemRepositoryInterface $solarSystemRepository,
private readonly SolarSystemFactoryInterface $solarSystemFactory,
private readonly PlanetFactoryInterface $planetFactory,
private readonly GalaxyContextInterface $galaxyContext,
private readonly PlayerContextInterface $playerContext,
private readonly EventBusInterface $eventBus,
) {
Expand Down Expand Up @@ -48,7 +50,8 @@ public function __invoke(FleetHasReachedJourneyTargetPointEvent $event): void
throw new PlanetAlreadyColonizedException($targetPoint, $playerId);
}

$planet = $this->planetFactory->create($playerId, $targetPoint);
$maxPlanetPosition = $this->galaxyContext->getMaxPlanetPosition();
$planet = $this->planetFactory->create($playerId, $targetPoint, $maxPlanetPosition);
$solarSystem->colonize($planet);

$this->eventBus->dispatch(
Expand Down

0 comments on commit 0c2fc17

Please sign in to comment.