PlayersCollection::setCurrentPlayer()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 2
eloc 2
nc 2
nop 1
crap 2
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 141
    public function __construct(array $elements = array())
26
    {
27 141
        parent::__construct();
28
29 141
        $this->gameOrder = [];
30
31 141
        foreach ($elements as $element) {
32 27
            $this->add($element);
33 94
        }
34 141
    }
35
36
    /**
37
     * @param mixed         $key
38
     * @param HangmanPlayer $value
39
     */
40 90
    public function set($key, $value)
41
    {
42 90
        Assertion::isInstanceOf($value, HangmanPlayer::class);
43 90
        Assertion::eq($key, (string) $value->getId());
44
45 90
        parent::set($key, $value);
46
47 90
        if (! in_array($key, $this->gameOrder)) {
48 90
            $this->gameOrder[] = $key;
49 60
        }
50
51 90
        if ($this->currentPlayer === null) {
52 90
            $this->currentPlayer = $value;
53 60
        }
54 90
    }
55
56
    /**
57
     * @param HangmanPlayer $value
58
     *
59
     * @return bool
60
     */
61 90
    public function add($value)
62
    {
63 90
        Assertion::isInstanceOf($value, HangmanPlayer::class);
64
65 90
        $this->set((string) $value->getId(), $value);
66
67 90
        return true;
68
    }
69
70
    /**
71
     * @return bool
72
     */
73 60
    public function hasPlayers()
74
    {
75 60
        return $this->count() > 0;
76
    }
77
78
    /**
79
     * @return bool
80
     */
81 24
    public function hasAtLeastOneActivePlayer()
82
    {
83 24
        foreach ($this->gameOrder as $gameOrder) {
84
            /** @var HangmanPlayer $player */
85 21
            $player = $this->get($gameOrder);
86
87 21
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
88 17
                return true;
89
            }
90 14
        }
91
92 9
        return false;
93
    }
94
95
    /**
96
     * Returns the next player in line
97
     *
98
     * @return PlayerId
99
     */
100 27
    public function getNextPlayerId()
101
    {
102 27
        $nbPlayers = count($this->gameOrder);
103 27
        $currentPlayerId = (string) $this->currentPlayer->getId();
104 27
        $nextPlayerPosition = (array_search($currentPlayerId, $this->gameOrder) + 1) % $nbPlayers;
105
106 27
        $pos = $nextPlayerPosition;
107
        do {
108 27
            $player = $this->get($this->gameOrder[$pos]);
109
110 27
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
111 24
                return PlayerId::create($this->gameOrder[$pos]);
112
            }
113
114 6
            $pos = ($pos + 1) % $nbPlayers;
115 6
        } while ($pos !== $nextPlayerPosition);
116
117 3
        return null;
118
    }
119
120
    /**
121
     * @param PlayerId $playerId
122
     *
123
     * @return bool
124
     */
125 39
    public function canPlay(PlayerId $playerId)
126
    {
127 39
        return $this->isCurrentPlayer($playerId);
128
    }
129
130
    /**
131
     * @param PlayerId $playerId
132
     *
133
     * @return bool
134
     */
135 51
    public function isCurrentPlayer(PlayerId $playerId = null)
136
    {
137 51
        return $playerId !== null && $this->currentPlayer !== null && $this->currentPlayer->getId()->equals($playerId);
138
    }
139
140
    /**
141
     * @return HangmanPlayer
142
     */
143 30
    public function getCurrentPlayer()
144
    {
145 30
        return $this->currentPlayer;
146
    }
147
148
    /**
149
     * @param PlayerId $playerId
150
     */
151 33
    public function setCurrentPlayer(PlayerId $playerId = null)
152
    {
153 33
        $this->currentPlayer = ($playerId !== null) ? $this->get((string) $playerId) : null;
154 33
    }
155
}
156