Completed
Push — master ( c42dc8...74e801 )
by Rémi
02:43
created

HangmanPlayer::isSupportedEvent()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Hangman\Entity;
4
5
use Broadway\EventSourcing\EventSourcedEntity;
6
use Hangman\Event\HangmanBadLetterProposedEvent;
7
use Hangman\Event\HangmanGoodLetterProposedEvent;
8
use Hangman\Event\HangmanPlayerLostEvent;
9
use Hangman\Event\HangmanPlayerWinEvent;
10
use MiniGame\Entity\MiniGame;
11
use MiniGame\Entity\Player;
12
use MiniGame\Entity\PlayerId;
13
use MiniGame\GameResult;
14
use Rhumsaa\Uuid\Uuid;
15
16
class HangmanPlayer extends EventSourcedEntity implements Player
17
{
18
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20
    //////////////////////////////////////////////   CONSTANTS   ///////////////////////////////////////////////////
21
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23
24
    const STATE_IN_GAME = 'in-game';
25
    const STATE_LOST = 'lost';
26
    const STATE_WON = 'won';
27
28
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30
    /////////////////////////////////////////////   PROPERTIES   ///////////////////////////////////////////////////
31
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
33
34
    /**
35
     * @var PlayerId
36
     */
37
    private $id;
38
39
    /**
40
     * @var string
41
     */
42
    private $name;
43
44
    /**
45
     * @var int
46
     */
47
    private $lives;
48
49
    /**
50
     * @var string[]
51
     */
52
    private $playedLetters;
53
54
    /**
55
     * @var Hangman
56
     */
57
    private $game;
58
59
    /**
60
     * @var string
61
     */
62
    private $state;
63
64
    /**
65
     * @var string
66
     */
67
    private $externalReference;
68
69
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
71
    //////////////////////////////////////////   PUBLIC CONSTRUCTOR   //////////////////////////////////////////////
72
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
73
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
74
75
    /**
76
     * Constructor
77
     *
78
     * @param PlayerId $id
79
     * @param string   $name
80
     * @param int      $lives
81
     * @param Hangman  $game
82
     * @param string   $externalReference
83
     */
84 96
    public function __construct(
85
        PlayerId $id = null,
86
        $name = null,
87
        $lives = 6,
88
        Hangman $game = null,
89
        $externalReference = null
90
    ) {
91 96
        $this->id = ($id !== null) ? $id : PlayerId::create(Uuid::uuid4()->toString());
92 96
        $this->name = $name;
93 96
        $this->lives = $lives;
94 96
        $this->playedLetters = [];
95 96
        $this->game = $game;
96 96
        $this->externalReference = $externalReference;
97 96
        $this->state = self::STATE_IN_GAME;
98 96
    }
99
100
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102
    //////////////////////////////////////////////   ACCESSORS   ///////////////////////////////////////////////////
103
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
105
106
    /**
107
     * Returns the id of the player
108
     *
109
     * @return PlayerId
110
     */
111 84
    public function getId()
112
    {
113 84
        return $this->id;
114
    }
115
116
    /**
117
     * Returns the name of the player
118
     *
119
     * @return string
120
     */
121 6
    public function getName()
122
    {
123 6
        return $this->name;
124
    }
125
126
    /**
127
     * Gets the game
128
     *
129
     * @return MiniGame
130
     */
131 6
    public function getGame()
132
    {
133 6
        return $this->game;
134
    }
135
136
    /**
137
     * Gets the number of lives remaining
138
     *
139
     * @return int
140
     */
141 42
    public function getRemainingLives()
142
    {
143 42
        return $this->lives;
144
    }
145
146
    /**
147
     * Gets the played letters
148
     *
149
     * @return string[]
150
     */
151 30
    public function getPlayedLetters()
152
    {
153 30
        return $this->playedLetters;
154
    }
155
156
    /**
157
     * Gets the external reference
158
     *
159
     * @return string
160
     */
161 3
    public function getExternalReference()
162
    {
163 3
        return $this->externalReference;
164
    }
165
166
    /**
167
     * Gets the state
168
     *
169
     * @return string
170
     */
171 24
    public function getState()
172
    {
173 24
        return $this->state;
174
    }
175
176
    /**
177
     * @return bool
178
     */
179 12
    public function hasLost()
180
    {
181 12
        return $this->state === self::STATE_LOST;
182
    }
183
184
    /**
185
     * @return bool
186
     */
187 6
    public function hasWon()
188
    {
189 6
        return $this->state === self::STATE_WON;
190
    }
191
192
    /**
193
     * @param  Player $player
194
     * @return bool
195
     */
196 18
    public function equals(Player $player)
197
    {
198 18
        return $player instanceof HangmanPlayer && $this->id->equals($player->id);
199
    }
200
201
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
202
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
203
    ///////////////////////////////////////////   DOMAIN METHODS   /////////////////////////////////////////////////
204
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
205
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
206
207
    /**
208
     * Player loses a life
209
     *
210
     * @param int $nbLives
211
     */
212 15
    public function loseLife($nbLives = 1)
213
    {
214 15
        $this->lives -= $nbLives;
215 15
    }
216
217
    /**
218
     * Players played a letter
219
     *
220
     * @param string $letter
221
     */
222 21
    public function playLetter($letter)
223
    {
224 21
        $this->playedLetters[strtoupper($letter)] = strtoupper($letter);
225 21
    }
226
227
    /**
228
     * @return void
229
     */
230 9
    public function win()
231
    {
232 9
        $this->state = self::STATE_WON;
233 9
    }
234
235
    /**
236
     * @return void
237
     */
238 24
    public function lose()
239
    {
240 24
        $this->state = self::STATE_LOST;
241 24
    }
242
243
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
244
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
245
    ////////////////////////////////////////////   APPLY EVENTS   //////////////////////////////////////////////////
246
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
247
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
248
249
    /**
250
     * Apply the bad letter played event
251
     *
252
     * @param  HangmanBadLetterProposedEvent $event
253
     * @return void
254
     */
255 12
    protected function applyHangmanBadLetterProposedEvent(HangmanBadLetterProposedEvent $event)
256
    {
257 12
        if ((string)$event->getPlayerId() === (string)$this->getId()) {
258 12
            $this->loseLife($event->getLivesLost());
259 12
            $this->playLetter($event->getLetter());
260 8
        }
261 12
    }
262
263
    /**
264
     * Apply the bad letter played event
265
     *
266
     * @param  HangmanGoodLetterProposedEvent $event
267
     * @return void
268
     */
269 6
    protected function applyHangmanGoodLetterProposedEvent(HangmanGoodLetterProposedEvent $event)
270
    {
271 6
        if ((string)$event->getPlayerId() === (string)$this->getId()) {
272 6
            $this->playLetter($event->getLetter());
273 4
        }
274 6
    }
275
276
    /**
277
     * Apply the hangman player lost event
278
     *
279
     * @param HangmanPlayerLostEvent $event
280
     */
281 21
    protected function applyHangmanPlayerLostEvent(HangmanPlayerLostEvent $event)
282
    {
283 21
        if ((string)$event->getPlayerId() === (string)$this->getId()) {
284 21
            $this->lose();
285 14
        }
286 21
    }
287
288
    /**
289
     * Apply the hangman player win event
290
     *
291
     * @param HangmanPlayerWinEvent $event
292
     */
293 6
    protected function applyHangmanPlayerWinEvent(HangmanPlayerWinEvent $event)
294
    {
295 6
        if ((string)$event->getPlayerId() === (string)$this->getId()) {
296 6
            $this->win();
297 4
        }
298 6
    }
299
300
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
301
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302
    /////////////////////////////////////////   APPLY RESTRICTIONS   ///////////////////////////////////////////////
303
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
304
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
305
306
307
    /**
308
     * @param mixed $event
309
     */
310 81
    public function handleRecursively($event)
311
    {
312 81
        if (! $this->isSupportedEvent($event)) {
313 78
            return;
314
        }
315
316 78
        parent::handleRecursively($event);
317 78
    }
318
319
    /**
320
     * @param mixed $event
321
     *
322
     * @return bool
323
     */
324 81
    private function isSupportedEvent($event)
325
    {
326
        return (
327 81
            $event instanceof GameResult &&
328 81
            $this->id == $event->getPlayerId() &&
329 79
            $this->game->getId() == $event->getGameId()
330 54
        );
331
    }
332
}
333