Completed
Push — master ( e88ec9...da59d3 )
by Rémi
02:58
created

PlayersCollection::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Hangman;
4
5
use Assert\Assertion;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Hangman\Entity\HangmanPlayer;
8
use MiniGame\Entity\PlayerId;
9
10
class PlayersCollection extends ArrayCollection
11
{
12
    /**
13
     * @var array
14
     */
15
    private $gameOrder;
16
17
    /**
18
     * @var HangmanPlayer
19
     */
20
    private $currentPlayer;
21
22
    /**
23
     * @inheritDoc
24
     */
25 111
    public function __construct(array $elements = array())
26
    {
27 111
        parent::__construct($elements);
28
29 111
        $this->gameOrder = [];
30 111
    }
31
32
    /**
33
     * @param mixed         $key
34
     * @param HangmanPlayer $value
35
     */
36 63
    public function set($key, $value)
37
    {
38 63
        Assertion::isInstanceOf($value, HangmanPlayer::class);
39 63
        Assertion::eq($key, (string) $value->getId());
40
41 63
        parent::set($key, $value);
42
43 63
        $this->gameOrder[] = $key;
44 63
    }
45
46
    /**
47
     * @param HangmanPlayer $value
48
     *
49
     * @return bool
50
     */
51 63
    public function add($value)
52
    {
53 63
        Assertion::isInstanceOf($value, HangmanPlayer::class);
54
55 63
        $this->set((string) $value->getId(), $value);
56
57 63
        return true;
58
    }
59
60
    /**
61
     * @return bool
62
     */
63 15
    public function thereIsAtLeastOneActivePlayer()
64
    {
65 15
        foreach ($this->gameOrder as $gameOrder) {
66
            /** @var HangmanPlayer $player */
67 15
            $player = $this->get($gameOrder);
68
69 15
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
70 13
                return true;
71
            }
72 10
        }
73
74 3
        return false;
75
    }
76
77
    /**
78
     * Returns the next player in line
79
     *
80
     * @return PlayerId
81
     */
82 18
    public function getNextPlayerId()
83
    {
84 18
        $nbPlayers = count($this->gameOrder);
85 18
        $currentPlayerId = (string) $this->currentPlayer->getId();
86 18
        $nextPlayerPosition = (array_search($currentPlayerId, $this->gameOrder) + 1) % $nbPlayers;
87
88 18
        $pos = $nextPlayerPosition;
89
        do {
90 18
            $player = $this->get($this->gameOrder[$pos]);
91
92 18
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
93 18
                return PlayerId::create($this->gameOrder[$pos]);
94
            }
95
96
            $pos = ($pos + 1) % $nbPlayers;
97
        } while ($pos !== $nextPlayerPosition);
98
99
        return null;
100
    }
101
102
    /**
103
     * @return HangmanPlayer
104
     */
105 27
    public function getCurrentPlayer()
106
    {
107 27
        return $this->currentPlayer;
108
    }
109
110
    /**
111
     * @param PlayerId $playerId
112
     */
113 48
    public function setCurrentPlayer(PlayerId $playerId = null)
114
    {
115 48
        $this->currentPlayer = ($playerId !== null) ? $this->get((string) $playerId) : null;
116 48
    }
117
118
    /**
119
     * @param PlayerId $playerId
120
     *
121
     * @return bool
122
     */
123 48
    public function isCurrentPlayer(PlayerId $playerId = null)
124
    {
125 48
        return $this->currentPlayer !== null && $this->currentPlayer->getId()->equals($playerId);
0 ignored issues
show
Bug introduced by
It seems like $playerId defined by parameter $playerId on line 123 can be null; however, MiniGame\Entity\PlayerId::equals() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
126
    }
127
128
    /**
129
     * @param PlayerId $playerId
130
     *
131
     * @return bool
132
     */
133 36
    public function canPlayerPlay(PlayerId $playerId)
134
    {
135 36
        return $this->isCurrentPlayer($playerId);
136
    }
137
138 51
    public function hasPlayers()
139
    {
140 51
        return $this->count() > 0;
141
    }
142
}
143