HangmanPlayer::win()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

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