Passed
Push — main ( a57e19...f52e71 )
by Vedrana
28:10
created

BlackJack::stay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace App\Card;
4
5
use App\Card\PayoutBlackJack;
6
7
/**
8
 * Class BlackJack is game logic handler.
9
 */
10
class BlackJack
11
{
12
    /** @var Deck */
13
    private Deck $deck;
14
15
    /** @var CardHand[] */
16
    private array $playerHands = [];
17
18
    /** @var int Index for the active hand */
19
    private int $currentHandIndex = 0;
20
21
    /** @var CardHand */
22
    private CardHand $bankHand;
23
24
    private BlackJackRules $rules;
25
26
    private PayoutBlackJack $payout;
27
28
    /** @var bool Flag for whether the game is over. */
29
    private bool $gameOver = false;
30
31
    /** @var string[] The result message. */
32
    private array $results = [];
33
34
    private string $playerName = '';
35
    private int $bet = 0;
36
    private int $balance = 0;
37
38
    /**
39
     * Black Jack constructor.
40
     *
41
     * Init the game by creating a new deck and empty hands for the player and the bank.
42
     */
43 13
    public function __construct(Deck $deck, BlackJackRules $rules, PayoutBlackJack $payout)
44
    {
45 13
        $this->deck = $deck;
46 13
        $this->rules = $rules;
47 13
        $this->payout = $payout;
48
    }
49
50
    /**
51
     * Draw a card for current player hand.
52
     */
53 3
    public function drawForPlayer(): void
54
    {
55 3
        $hand = $this->getCurrentHand();
56
57 3
        if ($hand === null) {
58 1
            return;
59
        }
60
61 2
        $this->dealCardTo($hand);
62
63 2
        if ($hand->getTotalBlackJack() > 21) {
64 1
            $this->nextHand();
65
        }
66
    }
67
68 3
    public function getCurrentHand(): ?CardHand
69
    {
70 3
        return $this->playerHands[$this->currentHandIndex] ?? null;
71
    }
72
73
    /**
74
     * Go to next player hand, or bank at the end.
75
     */
76 3
    public function nextHand(): void
77
    {
78 3
        $this->currentHandIndex++;
79
80 3
        if ($this->currentHandIndex >= count($this->playerHands)) {
81 2
            $this->drawForBank();
82 2
            $this->compareResults();
83
        }
84
    }
85
86 3
    public function getCurrentHandIndex(): int
87
    {
88 3
        return $this->currentHandIndex;
89
    }
90
91
    /**
92
     * Player chooses to "stay" on this hand → move to the next one.
93
     */
94 2
    public function stay(): void
95
    {
96 2
        $this->nextHand();
97
    }
98
99
    /**
100
     * Public wrapper for drawing bank cards via BlackJackRUles class.
101
     */
102 3
    public function drawForBank(): void
103
    {
104 3
        $this->rules->drawForBank($this->bankHand, $this->deck);
105
    }
106
107
    /**
108
     * Compare each player hand against the bank
109
     * and determine the game result.
110
     */
111 4
    public function compareResults(): void
112
    {
113 4
        foreach ($this->playerHands as $index => $hand) {
114 4
            $outcome = $this->rules->determineResult($hand, $this->bankHand, $index);
115
116 4
            $this->payout->applyPayout($outcome['result'], $this->bet, $this->balance);
117
118 4
            $this->results[] = $outcome['message'];
119
        }
120
121 4
        $this->gameOver = true;
122
    }
123
124
    /**
125
     * Start a new round by creating player hands and dealing cards.
126
     *
127
     * @param int $numHands Number of hands the player wants (1-3)
128
     */
129 11
    public function startGame(int $numHands = 1): void
130
    {
131 11
        if ($numHands < 1 || $numHands > 3) {
132 1
            $numHands = 1;
133
        }
134
135 11
        $this->playerHands = [];
136 11
        $this->results = [];
137 11
        $this->currentHandIndex = 0;
138 11
        $this->gameOver = false;
139
140
        // Create players hands
141 11
        for ($i = 0; $i < $numHands; $i++) {
142 11
            $hand = new CardHand();
143 11
            $this->dealCardTo($hand);
144 11
            $this->dealCardTo($hand);
145 11
            $this->playerHands[] = $hand;
146
        }
147
148
        // Crate banks hand
149 11
        $this->bankHand = new CardHand();
150 11
        $this->dealCardTo($this->bankHand);
151 11
        $this->dealCardTo($this->bankHand);
152
153
        // Draw bet from balance
154 11
        $this->balance -= $this->bet * $numHands;
155
    }
156
157
    /**
158
     * Deal one card from the deck.
159
     */
160 11
    public function dealCardTo(CardHand $hand): void
161
    {
162 11
        $card = $this->deck->drawCard();
163 11
        if ($card !== null) {
164 11
            $hand->addCard($card);
165
        }
166
    }
167
168
    /**
169
     * @return CardHand[]
170
     */
171 4
    public function getPlayerHands(): array
172
    {
173 4
        return $this->playerHands;
174
    }
175
176
    /**
177
    * @return string[]
178
     */
179 2
    public function getResults(): array
180
    {
181 2
        return $this->results;
182
    }
183
184 3
    public function getBankHand(): CardHand
185
    {
186 3
        return $this->bankHand;
187
    }
188
189 2
    public function isGameOver(): bool
190
    {
191 2
        return $this->gameOver;
192
    }
193
194 3
    public function setPlayerName(string $name): void
195
    {
196 3
        $this->playerName = $name;
197
    }
198
199 11
    public function setBet(int $bet): void
200
    {
201 11
        $this->bet = $bet;
202
    }
203
204 3
    public function getPlayerName(): string
205
    {
206 3
        return $this->playerName;
207
    }
208
209 3
    public function getBet(): int
210
    {
211 3
        return $this->bet;
212
    }
213
214 5
    public function getBalance(): int
215
    {
216 5
        return $this->balance;
217
    }
218
219 11
    public function setBalance(int $amount): void
220
    {
221 11
        $this->balance = $amount;
222
    }
223
}
224