1<?php ...
2
3namespace Thunk\Verbs\Examples\Monopoly\Events\Gameplay;
4
5use Thunk\Verbs\Attributes\Autodiscovery\AppliesToState;
6use Thunk\Verbs\Event;
7use Thunk\Verbs\Examples\Monopoly\Game\Phase;
8use Thunk\Verbs\Examples\Monopoly\Game\Spaces\Property;
9use Thunk\Verbs\Examples\Monopoly\States\GameState;
10use Thunk\Verbs\Examples\Monopoly\States\PlayerState;
11
12#[AppliesToState(GameState::class)]
13#[AppliesToState(PlayerState::class)]
14class PurchasedProperty extends Event
15{
16 use PlayerAction;
17
18 public function __construct(
19 public int $game_id,
20 public int $player_id,
21 public Property $property,
22 ) {}
23
24 public function validatePlayer(PlayerState $player)
25 {
26 $this->assert($player->location === $this->property, 'You must land on a property to buy it.');
27 $this->assert($player->money->isGreaterThanOrEqualTo($this->property->price()), "You do not have enough money to buy {$this->property->name()}.");
28 }
29
30 public function validateGame(GameState $game)
31 {
32 $this->assert($game->bank->hasDeed($this->property), "{$this->property->name()} is not for sale.");
33 $this->assert($game->phase_complete, 'You must finish what you’re doing before purchasing a property.');
34 $this->assert($game->phase->canTransitionTo(Phase::Purchase), 'You are not allowed to purchase properties right now.');
35 }
36
37 public function applyToGame(GameState $game)
38 {
39 $game->phase = Phase::Purchase;
40 $game->phase_complete = true;
41 $game->bank->purchaseDeed($this->property);
42 }
43
44 public function applyToPlayer(PlayerState $player)
45 {
46 $player->deeds->push($this->property);
47 $player->money = $player->money->minus($this->property->price());
48 $this->property->setOwner($player);
49 }
50}