Completed
Push — master ( 144ff2...6ebbcb )
by Jesse
02:12
created

Player   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 43
c 2
b 0
f 1
dl 0
loc 105
rs 10
wmc 14

9 Methods

Rating   Name   Duplication   Size   Complexity  
A from() 0 3 1
A __construct() 0 10 1
A drawOpeningHand() 0 8 3
A attackers() 0 3 1
A attackWith() 0 7 1
A cardInPlay() 0 6 2
A counterTheAttackersOf() 0 14 2
A defendAgainst() 0 10 1
A playTheCard() 0 13 2
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\CardGame\Match;
4
5
use function count;
6
use Stratadox\CardGame\DomainEventRecorder;
7
use Stratadox\CardGame\DomainEventRecording;
8
use Throwable;
9
10
final class Player implements DomainEventRecorder
11
{
12
    use DomainEventRecording;
13
14
    private $playerNumber;
15
    private $cards;
16
    private $maxHandSize;
17
    private $mana;
18
19
    public function __construct(
20
        int $id,
21
        Cards $cards,
22
        int $maxHandSize,
23
        Mana $mana
24
    ) {
25
        $this->playerNumber = $id;
26
        $this->cards = $cards;
27
        $this->maxHandSize = $maxHandSize;
28
        $this->mana = $mana;
29
    }
30
31
    public static function from(int $playerId, Cards $cards): self
32
    {
33
        return new self($playerId, $cards, 7, new Mana(4));
34
    }
35
36
    /** @throws NoSuchCard */
37
    public function cardInPlay(int $number): Card
38
    {
39
        try {
40
            return $this->cards->inPlay()[$number];
41
        } catch (Throwable $notFound) {
42
            throw NoSuchCard::atPosition($number, $notFound);
43
        }
44
    }
45
46
    /** @throws NotEnoughMana */
47
    public function playTheCard(int $cardNumber, MatchId $match): void
48
    {
49
        $card = $this->cards->inHand()[$cardNumber];
50
51
        if ($this->mana->isLessThan($card->cost())) {
52
            throw NotEnoughMana::toPlayThatCard();
53
        }
54
55
        $this->mana = $this->mana->minus($card->cost());
56
        $card->play($match, count($this->cards->inPlay()), $this->playerNumber);
57
58
        $this->happened(...$card->domainEvents());
59
        $card->eraseEvents();
60
    }
61
62
    /** @throws NoSuchCard */
63
    public function attackWith(int $cardNumber, MatchId $match): void
64
    {
65
        $card = $this->cardInPlay($cardNumber);
66
        $card->sendToAttack($match, count($this->attackers()), $this->playerNumber);
67
68
        $this->happened(...$card->domainEvents());
69
        $card->eraseEvents();
70
    }
71
72
    /** @throws NoSuchCard */
73
    public function defendAgainst(
74
        int $attacker,
75
        int $defender,
76
        MatchId $match
77
    ): void {
78
        $card = $this->cardInPlay($defender);
79
        $card->sendToDefendAgainst($match, $attacker, $this->playerNumber);
80
81
        $this->happened(...$card->domainEvents());
82
        $card->eraseEvents();
83
    }
84
85
    public function attackers(): Cards
86
    {
87
        return $this->cards->thatAttack();
88
    }
89
90
    public function drawOpeningHand(MatchId $match): void
91
    {
92
        for ($i = 0; $i < $this->maxHandSize; $i++) {
93
            $this->cards->drawFromTopOfDeck($match, $this->playerNumber);
94
        }
95
        foreach ($this->cards->inHand() as $card) {
96
            $this->happened(...$card->domainEvents());
97
            $card->eraseEvents();
98
        }
99
    }
100
101
    public function counterTheAttackersOf(
102
        int $attackingPlayer,
103
        MatchId $match,
104
        Cards $attackers
105
    ): void {
106
        foreach ($this->cards->thatDefend() as $defender) {
107
            $defender->counterAttack(
108
                $match,
109
                $attackers->theOneThatAttacksTheAmbushOf($defender),
110
                $this->playerNumber,
111
                $attackingPlayer
112
            );
113
            $this->happened(...$defender->domainEvents());
114
            $defender->eraseEvents();
115
        }
116
    }
117
}
118