Skip to content

Commit

Permalink
fix: 3% chance of black bass entering the tank.
Browse files Browse the repository at this point in the history
  • Loading branch information
Yukihiro Arisawa committed May 1, 2024
1 parent 8329767 commit b9f5853
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/Domain/Enum/BreedNameType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class BreedNameType
public const SHIRO = 'シロ';
public const YOZAKURA = '夜桜';

public const BIWAKO = '琵琶湖産'; // TODO: bug

/** @return string[] */
public static function getBreedNameForMedaka(): array
{
Expand Down
15 changes: 15 additions & 0 deletions src/Domain/Logic/Probability.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Iamyukihiro\Aquarium\Domain\Logic;

class Probability
{
public function calc(int $percentage): bool
{
$randomNumber = mt_rand(1, 100);

return $randomNumber <= $percentage;
}
}
33 changes: 33 additions & 0 deletions src/Domain/Logic/RandomLargeMouseBassGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Iamyukihiro\Aquarium\Domain\Logic;

use Iamyukihiro\Aquarium\Domain\Enum\BreedNameType;
use Iamyukihiro\Aquarium\Domain\Enum\ConditionLevelType;
use Iamyukihiro\Aquarium\Domain\Enum\FishType;
use Iamyukihiro\Aquarium\Domain\Enum\HungerLevelType;
use Iamyukihiro\Aquarium\Domain\Model\Fish\LargeMouseBass;
use Iamyukihiro\Aquarium\Domain\ValueObject\Breed;

use function Symfony\Component\Clock\now;

class RandomLargeMouseBassGenerator
{
public function __construct(
private NicknameGenerator $nicknameGenerator,
) {
}

public function generate(): LargeMouseBass
{
return new LargeMouseBass(
nickName: $this->nicknameGenerator->generate(),
breed: new Breed(FishType::LARGE_MOUSE_BASS, BreedNameType::BIWAKO),
conditionLevel: ConditionLevelType::FINE,
hungerLevel: HungerLevelType::STUFFED,
birthday: now()
);
}
}
4 changes: 1 addition & 3 deletions src/Domain/Model/Tank/Tank.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
namespace Iamyukihiro\Aquarium\Domain\Model\Tank;

use Iamyukihiro\Aquarium\Domain\Model\Fish\AbstractFish;
use Iamyukihiro\Aquarium\Domain\Model\Fish\LargeMouseBass;
use Iamyukihiro\Aquarium\Domain\Model\Fish\Medaka;

class Tank
{
Expand All @@ -22,7 +20,7 @@ public function addFish(AbstractFish $fish): void
* @param string|null $fishClassName
* @return AbstractFish[]
*/
public function getFishList(string $fishClassName = null): array
public function getFishList(?string $fishClassName = null): array
{
if ($fishClassName === null) {
return $this->fishList;
Expand Down
16 changes: 15 additions & 1 deletion src/UseCase/AddMedakaUseCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,35 @@

namespace Iamyukihiro\Aquarium\UseCase;

use Iamyukihiro\Aquarium\Domain\Logic\Probability;
use Iamyukihiro\Aquarium\Domain\Logic\RandomLargeMouseBassGenerator;
use Iamyukihiro\Aquarium\Domain\Logic\RandomMedakaGenerator;
use Iamyukihiro\Aquarium\Domain\Model\Fish\AbstractFish;
use Iamyukihiro\Aquarium\Domain\Model\Tank\TankManager;

class AddMedakaUseCase
{
public function __construct(
private TankManager $tankManager,
private RandomMedakaGenerator $randomMedakaGenerator,
private RandomLargeMouseBassGenerator $randomLargeMouseBassGenerator,
private Probability $probability,
) {
}

public function add(): void
{
$tank = $this->tankManager->load();
$tank->addFish($this->randomMedakaGenerator->generate());
$tank->addFish($this->gachaFish());
$this->tankManager->save($tank);
}

private function gachaFish(): AbstractFish
{
if ($this->probability->calc(3)) {
return $this->randomLargeMouseBassGenerator->generate();
}

return $this->randomMedakaGenerator->generate();
}
}
38 changes: 38 additions & 0 deletions tests/UseCase/AddMedakaUseCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use Iamyukihiro\Aquarium\Domain\Enum\ConditionLevelType;
use Iamyukihiro\Aquarium\Domain\Enum\FishType;
use Iamyukihiro\Aquarium\Domain\Enum\HungerLevelType;
use Iamyukihiro\Aquarium\Domain\Logic\Probability;
use Iamyukihiro\Aquarium\Domain\Logic\RandomLargeMouseBassGenerator;
use Iamyukihiro\Aquarium\Domain\Logic\RandomMedakaGenerator;
use Iamyukihiro\Aquarium\Domain\Model\Fish\LargeMouseBass;
use Iamyukihiro\Aquarium\Domain\Model\Fish\Medaka;
Expand All @@ -29,15 +31,20 @@ class AddMedakaUseCaseTest extends TestCase

private ObjectProphecy $tankManagerP;
private ObjectProphecy $randomMedakaGeneratorP;
private ObjectProphecy $randomLargeMouseBassGeneratorP;
private ObjectProphecy $probabilityP;

protected function setUp(): void
{
$this->tankManagerP = $this->prophesize(TankManager::class);
$this->randomMedakaGeneratorP = $this->prophesize(RandomMedakaGenerator::class);
$this->randomLargeMouseBassGeneratorP = $this->prophesize(RandomLargeMouseBassGenerator::class);
$this->probabilityP = $this->prophesize(Probability::class);
}

public function test(): void
{
$this->probabilityP->calc(3)->willReturn(false)->shouldBeCalled();
$medaka = new Medaka(
nickName: 'テストメダカ',
breed: new Breed(FishType::MEDAKA, BreedNameType::YOUKIHI),
Expand All @@ -64,11 +71,42 @@ function (Tank $tank) {
$SUT->add();
}

public function test_3%の確率でブラックバスが水槽に入ること(): void
{
$this->probabilityP->calc(3)->willReturn(true)->shouldBeCalled();
$largeMouseBass = new LargeMouseBass(
nickName: 'テストブラックバス',
breed: new Breed(FishType::LARGE_MOUSE_BASS, BreedNameType::BIWAKO),
conditionLevel: ConditionLevelType::FINE,
hungerLevel: HungerLevelType::STUFFED,
birthday: now()
);
$this->randomLargeMouseBassGeneratorP->generate()->willReturn($largeMouseBass)->shouldBeCalled();

$tank = new Tank();
$this->tankManagerP->load()->willReturn($tank)->shouldBeCalled();
$this->tankManagerP->save(
Argument::that(
function (Tank $tank) {
$this->assertCount(1, $tank->getFishList());
$this->assertSame('テストブラックバス', $tank->getFishList()[0]->getNickName());

return $tank;
}
)
)->shouldBeCalled();

$SUT = $this->getSUT();
$SUT->add();
}

public function getSUT(): AddMedakaUseCase
{
return new AddMedakaUseCase(
$this->tankManagerP->reveal(),
$this->randomMedakaGeneratorP->reveal(),
$this->randomLargeMouseBassGeneratorP->reveal(),
$this->probabilityP->reveal(),
);
}
}

0 comments on commit b9f5853

Please sign in to comment.