Completed
Push — master ( 3a1491...416016 )
by Rémi
02:59
created

HangmanPlayer::badLetter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
365
    {
366 24
        $this->state = self::STATE_LOST;
367 24
    }
368
369
    /**
370
     * Apply the hangman player win event
371
     *
372
     * @param HangmanPlayerWinEvent $event
373
     */
374 9
    protected function applyHangmanPlayerWinEvent(HangmanPlayerWinEvent $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
375
    {
376 9
        $this->state = self::STATE_WON;
377 9
    }
378
379
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
380
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
381
    /////////////////////////////////////////   APPLY RESTRICTIONS   ///////////////////////////////////////////////
382
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
383
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
384
385
386
    /**
387
     * @param mixed $event
388
     */
389 105
    public function handleRecursively($event)
390
    {
391 105
        if (! $this->isSupportedEvent($event)) {
392 87
            return;
393
        }
394
395 93
        parent::handleRecursively($event);
396 93
    }
397
398
    /**
399
     * @param mixed $event
400
     *
401
     * @return bool
402
     */
403 105
    private function isSupportedEvent($event)
404
    {
405
        return (
406 105
            $event instanceof GameResult &&
407 105
            $this->id == $event->getPlayerId() &&
408 97
            $this->game->getId() == $event->getGameId()
409 70
        );
410
    }
411
}
412