Verbs

Paid Rent

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 PaidRent 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 pay rent on it.');
27 $this->assert($player->money->isGreaterThanOrEqualTo($this->property->rent()), "You do not have enough money to pay rent at {$this->property->name()}.");
28 $this->assert($player !== $this->property->owner(), 'You cannot pay rent on a property that you do own.');
29 }
30 
31 public function validateGame(GameState $game)
32 {
33 $this->assert(! $game->bank->hasDeed($this->property), "{$this->property->name()} is still for sale—you cannot pay rent on it.");
34 $this->assert($game->phase_complete, 'You must finish what you’re doing before purchasing a property.');
35 $this->assert($game->phase->canTransitionTo(Phase::PayRent), 'You are not allowed to pay rent right now.');
36 }
37 
38 public function applyToGame(GameState $game)
39 {
40 $game->phase = Phase::PayRent;
41 $game->phase_complete = true;
42 }
43 
44 public function applyToPlayer(PlayerState $player)
45 {
46 $owner = $this->property->owner();
47 
48 $owner->money = $owner->money->plus($this->property->rent());
49 $player->money = $player->money->minus($this->property->rent());
50 }
51}