Completed
Push — master ( c8047b...ec489f )
by Dan
02:22
created

Table::removePlayer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

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 2
eloc 11
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Cysha\Casino\Holdem\Game;
4
5
use Cysha\Casino\Game\Client;
6
use Cysha\Casino\Game\Contracts\Dealer as DealerContract;
7
use Cysha\Casino\Game\Contracts\Player;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Cysha\Casino\Holdem\Game\Player.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use Cysha\Casino\Game\Contracts\Player as PlayerContract;
9
use Cysha\Casino\Game\PlayerCollection;
10
use Cysha\Casino\Game\Table as BaseTable;
11
use Cysha\Casino\Holdem\Exceptions\TableException;
12
use Ramsey\Uuid\Uuid;
13
14
class Table extends BaseTable
15
{
16
    /**
17
     * @var Uuid
18
     */
19
    private $id;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
20
21
    /**
22
     * @var Dealer
23
     */
24
    private $dealer;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
25
26
    /**
27
     * @var PlayerCollection
28
     */
29
    private $players;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
30
31
    /**
32
     * @var PlayerCollection
33
     */
34
    private $playersSatOut;
35
36
    /**
37
     * @var int
38
     */
39
    private $button = 0;
40
41
    /**
42 66
     * Table constructor.
43
     *
44 66
     * @param Uuid $id
45 66
     * @param DealerContract $dealer
46 66
     * @param PlayerCollection $players
47 66
     */
48
    private function __construct(Uuid $id, DealerContract $dealer, PlayerCollection $players)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
49
    {
50
        $this->id = $id;
51
        $this->players = $players;
52
        $this->playersSatOut = PlayerCollection::make();
53
        $this->dealer = $dealer;
0 ignored issues
show
Documentation Bug introduced by
$dealer is of type object<Cysha\Casino\Game\Contracts\Dealer>, but the property $dealer was declared to be of type object<Cysha\Casino\Holdem\Game\Dealer>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
54
    }
55 66
56
    /**
57 66
     * @param Uuid $id
58
     * @param DealerContract $dealer
59
     * @param PlayerCollection $players
60
     *
61
     * @return Table
62
     */
63 64
    public static function setUp(Uuid $id, DealerContract $dealer, PlayerCollection $players)
64
    {
65 64
        return new self($id, $dealer, $players);
66
    }
67
68
    /**
69
     * @return Uuid
70
     */
71 52
    public function id(): Uuid
72
    {
73 52
        return $this->id;
74
    }
75
76
    /**
77
     * @return PlayerCollection
78
     */
79 46
    public function players(): PlayerCollection
80
    {
81 46
        return $this->players;
82
    }
83
84
    /**
85
     * @return DealerContract
86
     */
87 12
    public function dealer(): DealerContract
88
    {
89 12
        return $this->dealer;
90
    }
91
92
    /**
93
     * @return int
94
     */
95 9
    public function button(): int
96
    {
97 9
        return $this->button;
98 9
    }
99
100
    /**
101
     * @return PlayerContract
102
     */
103 61
    public function locatePlayerWithButton(): PlayerContract
104
    {
105 61
        return $this->playersSatDown()->get($this->button);
106
    }
107
108
    /**
109
     * @param PlayerContract $player
110
     */
111
    public function sitPlayerOut(PlayerContract $player)
112
    {
113 3
        $this->playersSatOut = $this->playersSatOut->push($player);
114
    }
115 3
116 3
    /**
117 3
     * @return PlayerCollection
118 3
     */
119 3
    public function playersSatDown(): PlayerCollection
120
    {
121 3
        return $this->players()->diff($this->playersSatOut)->values();
122 1
    }
123
124
    /**
125 2
     * @param PlayerContract $player
126 2
     *
127
     * @throws TableException
128
     */
129
    public function giveButtonToPlayer(PlayerContract $player)
130
    {
131 15
        $playerIndex = $this->playersSatDown()
132
            ->filter
133 15
            ->equals($player)
134
            ->keys()
135 15
            ->first();
136 2
137
        if ($playerIndex === null) {
138 15
            throw TableException::invalidButtonPosition();
139
        }
140
141
        $this->button = $playerIndex;
142
    }
143 22
144
    /**
145 22
     * Moves the button along the table seats.
146
     */
147
    public function moveButton()
148 22
    {
149 22
        ++$this->button;
150
151 22
        if ($this->button >= $this->playersSatDown()->count()) {
152 22
            $this->button = 0;
153
        }
154 22
    }
155
156
    /**
157 22
     * @param PlayerContract $findPlayer
158 22
     *
159
     * @return int
160
     */
161 22
    public function findSeat(PlayerContract $findPlayer): int
162 22
    {
163 22
        return $this->players()
164
            ->filter(function (PlayerContract $player) use ($findPlayer) {
165 22
                return $player->equals($findPlayer);
166
            })
167
            ->keys()
168
            ->first();
169
    }
170
171
    /**
172
     * @param string $playerName
173 16
     *
174
     * @return Player
175 16
     */
176
    public function findPlayerByName($playerName): PlayerContract
177 16
    {
178 16
        return $this->players()
179 16
            ->filter(function (PlayerContract $player) use ($playerName) {
180 16
                return $player->name() === $playerName;
181
            })
182
            ->first();
183
    }
184
185
    public function removePlayer(Client $client)
186
    {
187
        $player = $this->players()
188 1
            ->filter(function (Player $player) use ($client) {
189
                return $player->name() === $client->name();
190 1
            })
191 1
            ->first()
192 1
        ;
193 1
194 1
        if ($player === null) {
195
            throw TableException::notRegistered($client, $this);
196
        }
197
198
        $this->players = $this->players()
199
            ->reject(function (Player $player) use ($client) {
200
                return $player->name() === $client->name();
201
            })
202
            ->values();
203
    }
204
}
205