BlackJack::isPlayerBroke()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 10
ccs 4
cts 4
cp 1
crap 3
1
<?php
2
3
namespace App\Game;
4
5
use App\Cards\DeckOfCards;
6
use App\Game\BlackJack\Dealer;
7
use App\Game\BlackJack\GameLogic;
8
use App\Game\BlackJack\Player;
9
10
/**
11
 * BlackJack.
12
 */
13
class BlackJack
14
{
15
    public const MAX_PLAYERS = 7;
16
    public const MINIMUM_BET = 50;
17
18
    private GameLogic $gameLogic;
19
    private int $numOfPlayers;
20
    /**
21
     * @var array<Player> Is an array that contains BlackJackPlayer objects
22
     */
23
    private array $players;
24
    private Dealer $dealer;
25
    private DeckOfCards $deck;
26
27
    /**
28
     * __construct.
29
     *
30
     * Constructor of the class
31
     *
32
     * @return void
33
     */
34 22
    public function __construct(int $numOfPlayers = 1)
35
    {
36 22
        if ($numOfPlayers < 1) {
37 1
            throw new \RuntimeException("Can't have less then one player in Black Jack");
38
        }
39
40 21
        if ($numOfPlayers > self::MAX_PLAYERS) {
41 1
            throw new \RuntimeException('Maximum of '.self::MAX_PLAYERS.' players in Black Jack');
42
        }
43
44 20
        $this->numOfPlayers = $numOfPlayers;
45 20
        $this->deck = new DeckOfCards();
46 20
        $this->dealer = new Dealer();
47 20
        for ($i = 0; $i < $this->numOfPlayers; ++$i) {
48 20
            $this->players[$i] = new Player();
49
        }
50
51
        // Needs to be last or can create error if accessing any BlackJack properties before set
52 20
        $this->gameLogic = new GameLogic($this);
53
    }
54
55
    /**
56
     * drawUpdate.
57
     */
58 4
    private function drawUpdate(int $index): void
59
    {
60 4
        if ($this->players[$index]->isBust()) {
61 2
            $this->players[$index]->setGameState(Player::DEALER_WIN);
62 2
            $this->players[$index]->resetBet();
63 2
            $this->gameLogic->checkIfDealersTurn();
64
65 2
            return;
66
        }
67
68 4
        if (Player::DOUBLE_DOWN === $this->players[$index]->getGameState()) {
69 2
            $this->gameLogic->checkIfDealersTurn();
70
        }
71
    }
72
73
    /**
74
     * getNumOfPlayers.
75
     */
76 19
    public function getNumOfPlayers(): int
77
    {
78 19
        return $this->numOfPlayers;
79
    }
80
81
    /**
82
     * getPlayers.
83
     *
84
     * @return array<Player>
85
     */
86 19
    public function getPlayers(): array
87
    {
88 19
        return $this->players;
89
    }
90
91
    /**
92
     * getDealer.
93
     */
94 19
    public function getDealer(): Dealer
95
    {
96 19
        return $this->dealer;
97
    }
98
99
    /**
100
     * getDeck.
101
     */
102 19
    public function getDeck(): DeckOfCards
103
    {
104 19
        return $this->deck;
105
    }
106
107
    /**
108
     * setPlayers.
109
     *
110
     * @param array<Player> $players
111
     */
112 19
    public function setPlayers(array $players): void
113
    {
114
        // If not to many players
115 19
        if (self::MAX_PLAYERS >= count($players)) {
116 19
            $this->players = $players;
117 19
            $this->numOfPlayers = count($players);
118
        }
119
    }
120
121
    /**
122
     * setPlayer.
123
     */
124 11
    public function setPlayer(int $index, Player $player): void
125
    {
126
        // If index is out of bounds
127 11
        if ($index < 0 or $index >= $this->numOfPlayers) {
128 1
            return;
129
        }
130
131 11
        $this->players[$index] = $player;
132
    }
133
134
    /**
135
     * setDealer.
136
     */
137 19
    public function setDealer(Dealer $dealer): void
138
    {
139 19
        $this->dealer = $dealer;
140
    }
141
142
    /**
143
     * setDeck.
144
     */
145 19
    public function setDeck(DeckOfCards $deck): void
146
    {
147 19
        $this->deck = $deck;
148
    }
149
150
    /**
151
     * isPlayerBust.
152
     *
153
     * Returns if the player's hand value is over 21
154
     */
155 5
    public function isPlayerBust(int $index = 0): bool
156
    {
157
        // If index is out of bounds
158 5
        if ($index < 0 or $index >= $this->numOfPlayers) {
159 1
            return true;
160
        }
161
162 5
        return $this->players[$index]->isBust();
163
    }
164
165
    /**
166
     * isPlayerBroke.
167
     *
168
     * Returns if the player is broke
169
     */
170 2
    public function isPlayerBroke(int $index = 0): bool
171
    {
172
        // If index is out of bounds
173 2
        if ($index < 0 or $index >= $this->numOfPlayers) {
174 1
            return true;
175
        }
176
177 2
        return $this->players[$index]->isBroke();
178
    }
179
180
    /**
181
     * isDealerBust.
182
     *
183
     * Returns if the dealer's hand value is over 21
184
     */
185 2
    public function isDealerBust(): bool
186
    {
187 2
        return $this->dealer->isBust();
188
    }
189
190
    /**
191
     * newGame.
192
     *
193
     * Sets up a new game
194
     *
195
     * @param array<int, int> $bets
196
     */
197 11
    public function newGame(array $bets = []): void
198
    {
199 11
        $this->gameLogic->newGame($bets);
200
    }
201
202
    /**
203
     * stateOfGame.
204
     *
205
     * Returns the current game state.
206
     *
207
     * @return array
208
     *               Descriptive list of array contents:
209
     *               - numOfPlayers (int)
210
     *               - playersNames (array<string>)
211
     *               - playersCards (array<int, array<string>>)
212
     *               - playersHandValue (array<string>)
213
     *               - playersCredits (array<string>)
214
     *               - playersBets (array<string>)
215
     *               - dealerCards (array<string>)
216
     *               - dealerHandValue (string)
217
     *               - gameStates (array<string>)
218
     *
219
     * @phpstan-return array{
220
     *   numOfPlayers: int,
221
     *   playersNames: array<string>,
222
     *   playersCards: array<int, array<string>>,
223
     *   playersHandValue: array<string>,
224
     *   playersCredits: array<string>,
225
     *   playersBets: array<string>,
226
     *   dealerCards: array<string>,
227
     *   dealerHandValue: string,
228
     *   gameStates: array<string>
229
     * }
230
     */
231 5
    public function stateOfGame(): array
232
    {
233 5
        return $this->gameLogic->stateOfGame();
234
    }
235
236
    /**
237
     * stayPlayer.
238
     */
239 3
    public function stayPlayer(int $index = 0): void
240
    {
241
        // If index is out of bounds
242 3
        if ($index < 0 or $index >= $this->numOfPlayers) {
243 1
            return;
244
        }
245
246
        // If game not over
247 3
        if (Player::UNDECIDED === $this->players[$index]->getGameState()) {
248 3
            $this->players[$index]->setGameState(Player::STAYED);
249 3
            $this->gameLogic->checkIfDealersTurn();
250
        }
251
    }
252
253
    /**
254
     * hitPlayer.
255
     */
256 3
    public function hitPlayer(int $index = 0): void
257
    {
258
        // If index is out of bounds
259 3
        if ($index < 0 or $index >= $this->numOfPlayers) {
260 1
            return;
261
        }
262
263
        // Stops drawing new cards if game is over
264 3
        if (Player::UNDECIDED === $this->players[$index]->getGameState()) {
265 3
            $this->players[$index]->addCard($this->deck->drawCard());
266
267 3
            $this->drawUpdate($index);
268
        }
269
    }
270
271 2
    public function doubleDownPlayer(int $index = 0): void
272
    {
273
        // If index is out of bounds
274 2
        if ($index < 0 or $index >= $this->numOfPlayers) {
275 1
            return;
276
        }
277
278
        // Can't double down if game is over
279 2
        if (Player::UNDECIDED === $this->players[$index]->getGameState() and 2 === count($this->players[$index]->getString())) {
280
            // Double bet
281 2
            $currentBet = $this->players[$index]->getBet();
282 2
            $this->players[$index]->increaseBet($currentBet);
283
284 2
            $this->players[$index]->addCard($this->deck->drawCard());
285
286 2
            $this->players[$index]->setGameState(Player::DOUBLE_DOWN);
287
288 2
            $this->drawUpdate($index);
289
        }
290
    }
291
}
292