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

BlackJackController   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 183
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 74
dl 0
loc 183
ccs 0
cts 77
cp 0
rs 10
c 1
b 0
f 0
wmc 17

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getBlackJackOrRedirect() 0 7 2
A blackJackInit() 0 35 4
A playBlackJack() 0 16 2
A newRound() 0 22 3
A handlePlayer() 0 29 3
A round() 0 14 3
1
<?php
2
3
namespace App\Controller;
4
5
use App\Card\BlackJack;
6
use App\Service\GameBlackJackService;
7
use App\Service\GameBlackJackValidateService;
8
use Symfony\Component\HttpFoundation\Session\SessionInterface;
9
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\Routing\Annotation\Route;
13
use Symfony\Component\Yaml\Exception\RuntimeException;
14
15
/**
16
 * BlackJack Controller.
17
 */
18
final class BlackJackController extends AbstractController
19
{
20
    /**
21
     * Init the BlackJack game after bet is submitted.
22
     *
23
     * @param SessionInterface $session The current session.
24
     * @param Request $request The HTTP request object.
25
     *
26
     * @return Response Redirects to the play route or back to bet on error.
27
     */
28
    #[Route('/proj/bet', name: 'enter_bet_post', methods: ['POST'])]
29
    public function blackJackInit(SessionInterface $session, Request $request, GameBlackJackService $gameService, GameBlackJackValidateService $gameValidate): Response
30
    {
31
        // Extract and validate input from POST using service
32
        $input = $gameValidate->validateInput($request->request->all());
33
        if (is_string($input)) {
34
            $this->addFlash('danger', $input);
35
            return $this->redirectToRoute('enter_bet');
36
        }
37
38
        $playerName = $input['playerName'];
39
        $betAmount = (int) $input['betAmount'];
40
        $numHands = (int) $input['numHands'];
41
42
        // Preserve existing balance or init to 1000
43
        $existingGame = $session->get('blackJack');
44
45
        if (!$existingGame instanceof \App\Card\BlackJack) {
46
            $existingGame = null;
47
        }
48
49
        // Validate bet against current balance and number of hands
50
        $error = $gameValidate->validateBet($existingGame, $betAmount, $numHands);
51
        if ($error) {
52
            $this->addFlash('danger', 'Your bet exceeds the available balance.');
53
            return $this->redirectToRoute('enter_bet');
54
        }
55
56
        $blackJack = $gameService->initOrCreate($existingGame, $playerName, $betAmount, $numHands);
57
58
        // Store game in session
59
        $session->set('playerName', $playerName);
60
        $session->set('blackJack', $blackJack);
61
62
        return $this->redirectToRoute('proj_play');
63
    }
64
65
    /**
66
     * Handle the display of the blackJack play page.
67
     *
68
     * @param SessionInterface $session Session to store blackJack state.
69
     *
70
     * @return Response Renders the blackJack play Twig template.
71
     */
72
    #[Route("/proj/play", name: "proj_play", methods: ["GET"])]
73
    public function playBlackJack(SessionInterface $session): Response
74
    {
75
        $blackJack = $this->getBlackJackOrRedirect($session);
76
        if (!$blackJack) {
77
            return $this->redirectToRoute('enter_bet');
78
        }
79
80
        return $this->render('proj/play.html.twig', [
81
            'blackJack' => $blackJack,
82
            'gameOver' => false,
83
            'results' => $blackJack->getResults(),
84
            'playerHands' => $blackJack->getPlayerHands(),
85
            'currentHand' => $blackJack->getCurrentHand(),
86
            'bankHand' => $blackJack->getBankHand(),
87
            'balance' => $blackJack->getBalance(),
88
        ]);
89
    }
90
91
    /**
92
     * Handle the blackJack play.
93
     *
94
     * @param SessionInterface $session Session to store blackJack state.
95
     *
96
     * @return Response Renders the blackJack play Twig template.
97
     * @throws RuntimeException if the stored session blackJack object is invalid.
98
     */
99
    #[Route("/proj/play", name: "proj_play_post", methods: ["POST"])]
100
    public function handlePlayer(SessionInterface $session, Request $request, GameBlackJackService $gameService): Response
101
    {
102
        $blackJack = $session->get('blackJack');
103
104
        if (!$blackJack instanceof BlackJack) {
105
            throw new RuntimeException("Invalid blackJack instance in session");
106
        }
107
108
        // Get the action by the player (draw or stay)
109
        $action = $request->get("action");
110
111
        if (!is_string($action)) {
112
            $action = '';
113
        }
114
115
        // Process player action
116
        $blackJack = $gameService->processAction($blackJack, $action);
117
118
        $session->set('blackJack', $blackJack);
119
120
        return $this->render('proj/play.html.twig', [
121
            'blackJack' => $blackJack,
122
            'gameOver' => $blackJack->isGameOver(),
123
            'results' => $blackJack->getResults(),
124
            'playerHands' => $blackJack->getPlayerHands(),
125
            'currentHand' => $blackJack->getCurrentHand(),
126
            'bankHand' => $blackJack->getBankHand(),
127
            'balance' => $blackJack->getBalance(),
128
        ]);
129
    }
130
131
    /**
132
     * Handle request to start a new game round with a new bet.
133
     *
134
     * @param SessionInterface $session Current session.
135
     * @param Request $request POST request containing the bet.
136
     * @param GameBlackJackService $gameService Logic handler for game creation.
137
     *
138
     * @return Response Redirect to play or round view depending on bet validity.
139
     */
140
    #[Route("/proj/newround", name: "proj_new_round", methods: ['POST'])]
141
    public function newRound(SessionInterface $session, Request $request, GameBlackJackService $gameService, GameBlackJackValidateService $gameValidate): Response
142
    {
143
        $blackJack = $this->getBlackJackOrRedirect($session);
144
        if (!$blackJack) {
145
            return $this->redirectToRoute('enter_bet');
146
        }
147
148
        $betAmount = (int) $request->request->get('betAmount');
149
        $numHands = (int) $request->request->get('numHands', 1);
150
151
        // Validate bet
152
        $error = $gameValidate->validateBet($blackJack, $betAmount, $numHands);
153
        if ($error) {
154
            $this->addFlash('danger', $error);
155
            return $this->redirectToRoute('proj_round');
156
        }
157
158
        $newGame = $gameService->newRound($blackJack, $betAmount, $numHands);
159
        $session->set('blackJack', $newGame);
160
161
        return $this->redirectToRoute('proj_play');
162
    }
163
164
    /**
165
     * Display the round start page where the player enters a new bet.
166
     *
167
     * @param SessionInterface $session Current session.
168
     *
169
     * @return Response Renders the round view or redirects if no balance.
170
     */
171
    #[Route("/proj/round", name: "proj_round", methods: ['GET'])]
172
    public function round(SessionInterface $session): Response
173
    {
174
        $blackJack = $this->getBlackJackOrRedirect($session);
175
        if (!$blackJack) {
176
            return $this->redirectToRoute('enter_bet');
177
        }
178
179
        if ($blackJack->getBalance() <= 0) {
180
            return $this->redirectToRoute('proj_game_over');
181
        }
182
183
        return $this->render('proj/round.html.twig', [
184
            'blackJack' => $blackJack,
185
        ]);
186
    }
187
188
    /**
189
     * Helper to get a valid BlackJack game from session or return null.
190
     *
191
     * @param SessionInterface $session Current session.
192
     * @return BlackJack|null The game instance if valid, otherwise null.
193
     */
194
    private function getBlackJackOrRedirect(SessionInterface $session): ?BlackJack
195
    {
196
        $blackJack = $session->get('blackJack');
197
        if (!$blackJack instanceof BlackJack) {
198
            return null;
199
        }
200
        return $blackJack;
201
    }
202
}
203