Completed
Push — master ( da59d3...1e9f84 )
by Rémi
02:48
created

PlayersCollection::canPlay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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 hasPlayers()
64
    {
65 15
        return $this->count() > 0;
66
    }
67 15
68
    /**
69 15
     * @return bool
70 13
     */
71
    public function hasAtLeastOneActivePlayer()
72 10
    {
73
        foreach ($this->gameOrder as $gameOrder) {
74 3
            /** @var HangmanPlayer $player */
75
            $player = $this->get($gameOrder);
76
77
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
78
                return true;
79
            }
80
        }
81
82 18
        return false;
83
    }
84 18
85 18
    /**
86 18
     * Returns the next player in line
87
     *
88 18
     * @return PlayerId
89
     */
90 18
    public function getNextPlayerId()
91
    {
92 18
        $nbPlayers = count($this->gameOrder);
93 18
        $currentPlayerId = (string) $this->currentPlayer->getId();
94
        $nextPlayerPosition = (array_search($currentPlayerId, $this->gameOrder) + 1) % $nbPlayers;
95
96
        $pos = $nextPlayerPosition;
97
        do {
98
            $player = $this->get($this->gameOrder[$pos]);
99
100
            if ($player->getState() === HangmanPlayer::STATE_IN_GAME) {
101
                return PlayerId::create($this->gameOrder[$pos]);
102
            }
103
104
            $pos = ($pos + 1) % $nbPlayers;
105 27
        } while ($pos !== $nextPlayerPosition);
106
107 27
        return null;
108
    }
109
110
    /**
111
     * @param PlayerId $playerId
112
     *
113 48
     * @return bool
114
     */
115 48
    public function canPlay(PlayerId $playerId)
116 48
    {
117
        return $this->isCurrentPlayer($playerId);
118
    }
119
120
    /**
121
     * @param PlayerId $playerId
122
     *
123 48
     * @return bool
124
     */
125 48
    public function isCurrentPlayer(PlayerId $playerId = null)
126
    {
127
        return $playerId !== null && $this->currentPlayer !== null && $this->currentPlayer->getId()->equals($playerId);
128
    }
129
130
    /**
131
     * @return HangmanPlayer
132
     */
133 36
    public function getCurrentPlayer()
134
    {
135 36
        return $this->currentPlayer;
136
    }
137
138 51
    /**
139
     * @param PlayerId $playerId
140 51
     */
141
    public function setCurrentPlayer(PlayerId $playerId = null)
142
    {
143
        $this->currentPlayer = ($playerId !== null) ? $this->get((string) $playerId) : null;
144
    }
145
}
146