TwentyOneGameController   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Test Coverage

Coverage 23.21%

Importance

Changes 12
Bugs 0 Features 1
Metric Value
eloc 106
c 12
b 0
f 1
dl 0
loc 223
rs 10
ccs 26
cts 112
cp 0.2321
wmc 21

10 Methods

Rating   Name   Duplication   Size   Complexity  
A index() 0 4 1
A play() 0 22 2
A docs() 0 4 1
A init() 0 27 1
A setup() 0 55 4
A hit() 0 26 4
A reset() 0 13 1
A stay() 0 26 4
A bet() 0 18 2
A destroy() 0 7 1
1
<?php
2
3
namespace App\Controller;
4
5
use App\Game\GameManager;
6
use App\Game\BettingManager;
7
use App\Game\BankerInterface;
8
use App\Game\EasyBanker;
9
use App\Game\MediumBanker;
10
use App\Game\HardBanker;
11
use App\Game\Player;
12
use App\Card\DeckOfCards;
13
14
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\Routing\Annotation\Route;
18
use Symfony\Component\HttpFoundation\Session\SessionInterface;
19
20
class TwentyOneGameController extends AbstractController
21
{
22
    #[Route("/game", name: "game_index", methods: ['GET'])]
23
    public function index(): Response
24
    {
25
        return $this->render('game/index.html.twig');
26
    }
27
28
    #[Route("/game/docs", name: "game_docs", methods: ['GET'])]
29
    public function docs(): Response
30
    {
31
        return $this->render('game/docs.html.twig');
32
    }
33
34
    #[Route("/game/init", name: "game_init", methods: ['GET'])]
35
    public function init(): Response
36
    {
37
        /** @var mixed[] $bankers Data to display in difficulty level select form. */
38
        $bankers = [
39
            'easy' => [
40
                'name' => 'BetBot Buddy',
41
                'img' => 'easy_banker.png',
42
                'description' => 'This is your friendly casino banker who does not know anything about counting cards. They always play until they hit 17 or more.',
43
            ],
44
            'medium' => [
45
                'name' => 'Cashbot McMoneybags',
46
                'img' => 'medium_banker.png',
47
                'description' => 'This banker is a master card counter. They will hit until they are likely to burst.',
48
            ],
49
            'hard' => [
50
                'name' => 'Robo-Schemer Scrooge',
51
                'img' => 'hard_banker.png',
52
                'description' => 'This money grubbing fiend is definitely looking at your cards. They will hit as long as they are behind.',
53
            ],
54
        ];
55
56
        $data = [
57
            'bankers' => $bankers,
58
        ];
59
60
        return $this->render('game/init.html.twig', $data);
61
    }
62
63
    /** @SuppressWarnings(PHPMD.ElseExpression) */
64
    #[Route("/game/init", name: "game_init_post", methods: ['POST'])]
65
    public function setup(Request $request, SessionInterface $session): Response
66
    {
67
        // Start by checking and determining banker difficulty
68
        $level = $request->request->get('banker', null);
69
70
        /** @var BankerInterface|null $banker */
71
        $banker = null;
72
73
        if ($level === 'easy') {
74
            $banker = new EasyBanker();
75
        } elseif ($level === 'medium') {
76
            $banker = new MediumBanker();
77
        } elseif ($level === 'hard') {
78
            $banker = new HardBanker();
79
        } else {
80
            $this->addFlash(
81
                'warning',
82
                'No difficulty level selected.'
83
            );
84
            return $this->redirectToRoute('game_init');
85
        }
86
87
        /** @var GameManager $gameManager */
88
        $gameManager = new GameManager();
89
90
        $gameManager->setBanker($banker);
91
        $gameManager->setPlayer(new Player());
92
93
        /** @var DeckOfCards $deck */
94
        $deck = new DeckOfCards();
95
96
        $deck->shuffleCards();
97
        $gameManager->setDeck($deck);
98
99
        // Set assistance mode on or off
100
        $assistance = $request->request->get('assistance', false) !== false;
101
        $gameManager->setAssistanceMode($assistance);
102
103
        // First card is mandatory
104
        $gameManager->dealPlayer();
105
106
        // Save state
107
        $session->set('gameManager', $gameManager);
108
109
        /** @var BettingManager $bettingManager */
110
        $bettingManager = new BettingManager();
111
112
        // Set betting mode on or off
113
        $betting = $request->request->get('betting', false) !== false;
114
        $bettingManager->setBetting($betting);
115
116
        $session->set('bettingManager', $bettingManager);
117
118
        return $this->redirectToRoute('game_play');
119
    }
120
121
    #[Route("/game/play", name: "game_play")]
122
    public function play(SessionInterface $session): Response
123
    {
124
        /** @var GameManager|null $gameManager */
125
        $gameManager = $session->get('gameManager', null);
126
127
        // Start by checking if gameManager is set up properly
128
        if ($gameManager === null) {
129
            $this->addFlash(
130
                'warning',
131
                'No active game. Press "Play" to start a new one.'
132
            );
133
            return $this->redirectToRoute('game_index');
134
        }
135
136
        /** @var BettingManager $bettingManager */
137
        $bettingManager = $session->get('bettingManager');
138
139
        // Get state to display in view
140
        $data = array_merge($gameManager->getState(), $bettingManager->getState());
141
142
        return $this->render('game/play.html.twig', $data);
143
    }
144
145 2
    #[Route("/game/play/hit", name: "game_hit", methods: ['POST'])]
146
    public function hit(SessionInterface $session): Response
147
    {
148
        /** @var GameManager $gameManager */
149 2
        $gameManager = $session->get('gameManager');
150
151
        // Player hit for another card
152 2
        $gameManager->dealPlayer();
153 2
        $hasWon = $gameManager->checkPlayerWon();
154
155
        /** @var BettingManager $bettingManager */
156 2
        $bettingManager = $session->get('bettingManager');
157
158 2
        if ($bettingManager->isBetting() === true) {
159 2
            if ($hasWon === -1) {
160 1
                $bettingManager->bankerWinsStake();
161 1
            } elseif ($hasWon === 1) {
162 1
                $bettingManager->playerWinsStake();
163
            }
164
165 2
            $session->set('bettingManager', $bettingManager);
166
        }
167
168 2
        $session->set('gameManager', $gameManager);
169
170 2
        return $this->redirectToRoute('game_play');
171
    }
172
173 2
    #[Route("/game/play/stay", name: "game_stay", methods: ['POST'])]
174
    public function stay(SessionInterface $session): Response
175
    {
176
        /** @var GameManager $gameManager */
177 2
        $gameManager = $session->get('gameManager');
178
179
        // Player decide to stay, banker takes their turn
180 2
        $gameManager->dealBanker();
181 2
        $hasWon = $gameManager->checkBankerWon();
182
183
        /** @var BettingManager $bettingManager */
184 2
        $bettingManager = $session->get('bettingManager');
185
186 2
        if ($bettingManager->isBetting() === true) {
187 2
            if ($hasWon === -1) {
188 1
                $bettingManager->bankerWinsStake();
189 1
            } elseif ($hasWon === 1) {
190 1
                $bettingManager->playerWinsStake();
191
            }
192
193 2
            $session->set('bettingManager', $bettingManager);
194
        }
195
196 2
        $session->set('gameManager', $gameManager);
197
198 2
        return $this->redirectToRoute('game_play');
199
    }
200
201
    #[Route("/game/play/reset", name: "game_reset", methods: ['POST'])]
202
    public function reset(SessionInterface $session): Response
203
    {
204
        /** @var GameManager $gameManager */
205
        $gameManager = $session->get('gameManager');
206
207
        $gameManager->reset();
208
209
        $gameManager->dealPlayer();
210
211
        $session->set('gameManager', $gameManager);
212
213
        return $this->redirectToRoute('game_play');
214
    }
215
216
    #[Route("/game/play/bet", name: "game_bet", methods: ['POST'])]
217
    public function bet(Request $request, SessionInterface $session): Response
218
    {
219
        /** @var BettingManager $bettingManager */
220
        $bettingManager = $session->get('bettingManager');
221
222
        $bet = intval($request->request->get('bet'));
223
224
        if ($bettingManager->placeBet($bet) === false) {
225
            $this->addFlash(
226
                'warning',
227
                'Invalid betting amount!'
228
            );
229
        }
230
231
        $session->set('bettingManager', $bettingManager);
232
233
        return $this->redirectToRoute('game_play');
234
    }
235
236
    #[Route("/game/destroy", name: "game_destroy", methods: ['POST'])]
237
    public function destroy(SessionInterface $session): Response
238
    {
239
        $session->remove('gameManager');
240
        $session->remove('bettingManager');
241
242
        return $this->redirectToRoute('game_index');
243
    }
244
}
245