1<?php ...
 2 
 3namespace Thunk\Verbs\Examples\Monopoly\Events\Setup;
 4 
 5use Brick\Money\Money;
 6use Thunk\Verbs\Attributes\Autodiscovery\AppliesToState;
 7use Thunk\Verbs\Event;
 8use Thunk\Verbs\Examples\Monopoly\Game\DeedCollection;
 9use Thunk\Verbs\Examples\Monopoly\Game\Spaces\Go;
10use Thunk\Verbs\Examples\Monopoly\Game\Token;
11use Thunk\Verbs\Examples\Monopoly\States\GameState;
12use Thunk\Verbs\Examples\Monopoly\States\PlayerState; 
13 
14#[AppliesToState(GameState::class)]
15#[AppliesToState(PlayerState::class)]
16class PlayerJoinedGame extends Event
17{
18    public function __construct(
19        public int $game_id,
20        public int $player_id,
21        public Token $token,
22    ) {}
23 
24    public function validateGame(GameState $game)
25    {
26        $this->assert($game->started, 'Game must be started before a player can join.');
27 
28        $this->assert(
29            assertion: $game->players()->doesntContain(fn (PlayerState $player) => $player->token === $this->token),
30            message: 'This token has already been picked by another player'
31        );
32    }
33 
34    public function validatePlayer(PlayerState $player)
35    {
36        $this->assert(! $player->setup, 'Player has already joined game.');
37    }
38 
39    public function applyToGame(GameState $game)
40    {
41        $game->player_ids[] = $this->player_id;
42    }
43 
44    public function applyToPlayers(PlayerState $player)
45    {
46        $player->token = $this->token;
47        $player->deeds = DeedCollection::make([]);
48        $player->money = Money::of(1500, 'USD');
49        $player->location = Go::instance();
50        $player->setup = true;
51    }
52}