GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BlackjackCommand::printWhiskey()   B
last analyzed

Complexity

Conditions 5
Paths 16

Size

Total Lines 40
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 44
nc 16
nop 1
dl 0
loc 40
c 0
b 0
f 0
cc 5
rs 8.9048
1
<?php
2
3
declare(strict_types=1);
4
5
/* (c) Anton Medvedev <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Deployer\Command;
12
13
use Symfony\Component\Console\Command\Command;
14
use Symfony\Component\Console\Input\InputInterface as Input;
15
use Symfony\Component\Console\Output\OutputInterface as Output;
16
use Symfony\Component\Console\Question\ChoiceQuestion;
17
use Symfony\Component\Console\Style\SymfonyStyle;
18
19
use function Deployer\Support\array_flatten;
20
21
class BlackjackCommand extends Command
22
{
23
    use CommandCommon;
24
25
    /**
26
     * @var Input
27
     */
28
    private $input;
29
30
    /**
31
     * @var Output
32
     */
33
    private $output;
34
35
    public function __construct()
36
    {
37
        parent::__construct('blackjack');
38
        $this->setDescription('Play blackjack');
39
    }
40
41
    protected function execute(Input $input, Output $output): int
42
    {
43
        $this->input = $input;
44
        $this->output = $output;
45
        $this->telemetry();
46
        $io = new SymfonyStyle($this->input, $this->output);
47
48
        if (getenv('COLORTERM') === 'truecolor') {
49
            $this->print("\x1b[38;2;255;95;109m╭\x1b[39m\x1b[38;2;255;95;107m─\x1b[39m\x1b[38;2;255;96;106m─\x1b[39m\x1b[38;2;255;96;104m─\x1b[39m\x1b[38;2;255;96;103m─\x1b[39m\x1b[38;2;255;97;101m─\x1b[39m\x1b[38;2;255;97;100m─\x1b[39m\x1b[38;2;255;97;99m─\x1b[39m\x1b[38;2;255;98;97m─\x1b[39m\x1b[38;2;255;100;98m─\x1b[39m\x1b[38;2;255;102;98m─\x1b[39m\x1b[38;2;255;104;98m─\x1b[39m\x1b[38;2;255;106;99m─\x1b[39m\x1b[38;2;255;108;99m─\x1b[39m\x1b[38;2;255;110;99m─\x1b[39m\x1b[38;2;255;112;100m─\x1b[39m\x1b[38;2;255;114;100m─\x1b[39m\x1b[38;2;255;116;100m─\x1b[39m\x1b[38;2;255;118;100m─\x1b[39m\x1b[38;2;255;120;101m─\x1b[39m\x1b[38;2;255;122;101m─\x1b[39m\x1b[38;2;255;124;101m─\x1b[39m\x1b[38;2;255;126;102m╮\x1b[39m");
50
            $this->print("\x1b[38;2;255;128;102m│\x1b[39m                     \x1b[38;2;255;130;102m│\x1b[39m");
51
            $this->print("\x1b[38;2;255;132;103m│\x1b[39m      \x1b[38;2;255;134;103mW\x1b[39m\x1b[38;2;255;136;103me\x1b[39m\x1b[38;2;255;138;104ml\x1b[39m\x1b[38;2;255;140;104mc\x1b[39m\x1b[38;2;255;142;104mo\x1b[39m\x1b[38;2;255;144;104mm\x1b[39m\x1b[38;2;255;146;105me\x1b[39m\x1b[38;2;255;148;105m!\x1b[39m       \x1b[38;2;255;150;105m│\x1b[39m");
52
            $this->print("\x1b[38;2;255;152;106m│\x1b[39m                     \x1b[38;2;255;153;106m│\x1b[39m");
53
            $this->print("\x1b[38;2;255;155;106m╰\x1b[39m\x1b[38;2;255;157;107m─\x1b[39m\x1b[38;2;255;159;107m─\x1b[39m\x1b[38;2;255;161;107m─\x1b[39m\x1b[38;2;255;163;108m─\x1b[39m\x1b[38;2;255;165;108m─\x1b[39m\x1b[38;2;255;166;108m─\x1b[39m\x1b[38;2;255;168;108m─\x1b[39m\x1b[38;2;255;170;109m─\x1b[39m\x1b[38;2;255;172;109m─\x1b[39m\x1b[38;2;255;174;109m─\x1b[39m\x1b[38;2;255;176;110m─\x1b[39m\x1b[38;2;255;177;110m─\x1b[39m\x1b[38;2;255;179;110m─\x1b[39m\x1b[38;2;255;181;111m─\x1b[39m\x1b[38;2;255;183;111m─\x1b[39m\x1b[38;2;255;185;111m─\x1b[39m\x1b[38;2;255;186;111m─\x1b[39m\x1b[38;2;255;188;112m─\x1b[39m\x1b[38;2;255;190;112m─\x1b[39m\x1b[38;2;255;192;112m─\x1b[39m\x1b[38;2;255;193;113m─\x1b[39m\x1b[38;2;255;195;113m╯\x1b[0m");
54
        } else {
55
            $this->print("╭─────────────────────╮");
56
            $this->print("│                     │");
57
            $this->print("│      Welcome!       │");
58
            $this->print("│                     │");
59
            $this->print("╰─────────────────────╯");
60
        }
61
62
        $money = 100;
63
64
        if (md5(strval(getenv('MONEY'))) === '5a7c2f336d0cc43b68951e75cdffe333') {
65
            $money += 25;
66
            $this->print('<fg=cyan>You got an extra $25.</>');
67
        } elseif (md5(strval(getenv('MONEY'))) === '530029252abcbda4a2a2069036ccc7fc') {
68
            $money += 100;
69
            $this->print('<fg=cyan>You got an extra $100.</>');
70
        } elseif (md5(strval(getenv('MONEY'))) === '1aa827a06ecbfa5d6fa7c62ad245f3a3') {
71
            $money = 100000;
72
        }
73
74
        $hasWatch = true;
75
        $orderWhiskey = false;
76
        $whiskeyLevel = 0;
77
78
        $deck = $this->newDeck();
79
        $graveyard = [];
80
        $dealersHand = [];
81
        $playersHand = [];
82
        shuffle($deck);
83
        $deal = function () use (&$deck, &$graveyard) {
84
            if (count($deck) == 0) {
85
                shuffle($graveyard);
86
                $deck = $graveyard;
87
                $graveyard = [];
88
            }
89
            return array_pop($deck);
90
        };
91
92
        start:
93
        $this->print("You have <info>$</info><info>$money</info>.");
94
        if ($money > 0) {
95
            $bet = (int) $io->ask('Your bet', '5');
96
            if ($bet <= 0) {
97
                goto start;
98
            }
99
            if ($bet > $money) {
100
                goto start;
101
            }
102
        } elseif ($hasWatch) { // @phpstan-ignore-line
0 ignored issues
show
introduced by
The condition $hasWatch is always true.
Loading history...
103
            $answer = $io->askQuestion(new ChoiceQuestion('?', ['leave', '- Here, take my watch! [$25]'], 0));
104
            if ($answer == 'leave') {
105
                goto leave;
106
            } else {
107
                $hasWatch = false;
108
                $money = 25;
109
                $bet = 25;
110
            }
111
        } else {
112
            goto leave;
113
        }
114
115
        $graveyard = array_merge($graveyard, $dealersHand);
116
        $dealersHand = [];
117
        $dealersHand[] = $deal();
118
        $this->print("Dealers hand:");
119
        $this->printHand($dealersHand);
120
121
        $graveyard = array_merge($graveyard, $playersHand);
122
        $playersHand = [];
123
        $playersHand[] = $deal();
124
        $playersHand[] = $deal();
125
        $this->print("Your hand:");
126
        $this->printHand($playersHand, 2);
127
128
        while (true) {
129
            $question = new ChoiceQuestion('Your turn', ['hit', 'stand'], 0);
130
            $answer = $io->askQuestion($question);
131
132
            if ($answer === 'hit') {
133
                $playersHand[] = $deal();
134
                usleep(200000);
135
            }
136
137
            if ($answer === 'stand') {
138
                break;
139
            }
140
141
            $this->printHand($playersHand);
142
            $handValue = self::handValue($playersHand);
143
144
            if ($handValue > 21) {
145
                $this->print("You got <comment>$handValue</comment>.");
146
                $this->print("<fg=cyan>Bust!</>");
147
                $this->print("-<info>$</info><info>$bet</info>");
148
                $money -= $bet;
149
                goto nextRound;
150
            }
151
        }
152
153
        $this->printHand($dealersHand);
154
        $this->print("Dealer: " . self::handValue($dealersHand));
155
        sleep(1);
156
157
        while (self::handValue($dealersHand) <= 17) {
158
            $dealersHand[] = $deal();
159
            $this->printHand($dealersHand);
160
            $this->print("Dealer: " . self::handValue($dealersHand));
161
            sleep(1);
162
        }
163
164
        $d = self::handValue($dealersHand);
165
        $p = self::handValue($playersHand);
166
        $this->print("You got <comment>$p</comment> and dealer <comment>$d</comment>.");
167
168
        if ($d > 21 || $p > $d) {
169
            $this->print("<fg=cyan>You won!</>");
170
            $this->print("+<info>$</info><info>$bet</info>");
171
            $money += $bet;
172
        } elseif ($p < $d) {
173
            $this->print("<fg=cyan>You lose!</>");
174
            $this->print("-<info>$</info><info>$bet</info>");
175
            $money -= $bet;
176
        } else {
177
            $this->print("<fg=cyan>Push!</>");
178
        }
179
180
        nextRound:
181
        $choices = ['continue', 'leave'];
182
        if ($orderWhiskey) {
0 ignored issues
show
introduced by
The condition $orderWhiskey is always false.
Loading history...
183
            $orderWhiskey = false;
184
            $whiskeyLevel = 4;
185
            $this->print();
186
            $this->print('The waitress brought whiskey and says:');
187
            $this->print(' - Your whiskey, sir.');
188
            if ($money >= 5) {
189
                array_push($choices, 'tip the waitress [$5]');
190
            }
191
        } elseif ($money >= 5) {
192
            array_push($choices, 'order whiskey [$5]');
193
        }
194
195
        if ($whiskeyLevel > 0) {
196
            $this->printWhiskey($whiskeyLevel);
197
            $whiskeyLevel--;
198
        }
199
        $answer = $io->askQuestion(new ChoiceQuestion('?', $choices, 0));
200
201
        if ($answer == 'leave') {
202
            goto leave;
203
        } elseif ($money >= 5 && $answer == 'order whiskey [$5]') {
204
            $orderWhiskey = true;
205
            $this->print('You say:');
206
            $this->print(' - Whiskey, please.');
207
            $money -= 5;
208
        } elseif ($money >= 5 && $answer == 'tip the waitress [$5]') {
209
            $this->print('The waitress says:');
210
            $this->print(' - Thank you, sir!');
211
            $money -= 5;
212
        }
213
        $this->print();
214
        $this->print("=====> Next round <=====");
215
        goto start;
216
217
        leave:
218
        if ($money >= 5) {
219
            $answer = $io->ask('Leave a $5 tip to the dealer?', 'yes');
220
            if ($answer === 'yes') {
221
                $this->print("You can leave a tip here:");
222
                $this->print();
223
                $this->print("- https://github.com/sponsors/antonmedv");
224
                $this->print("- https://paypal.me/antonmedv");
225
                $this->print();
226
            }
227
        }
228
        $this->print('Thanks for playing, Come again!');
229
        return 0;
230
    }
231
232
    private function newDeck(): array
233
    {
234
        $deck = [];
235
        foreach (['♠', '♣', '♥', '♦'] as $suit) {
236
            for ($i = 2; $i <= 10; $i++) {
237
                $deck[] = [strval($i), $suit];
238
            }
239
            $deck[] = ['J', $suit];
240
            $deck[] = ['Q', $suit];
241
            $deck[] = ['K', $suit];
242
            $deck[] = ['A', $suit];
243
        }
244
        return $deck;
245
    }
246
247
    public static function handValue(array $hand): int
248
    {
249
        $aces = 0;
250
        $value = 0;
251
        foreach ($hand as [$rank]) {
252
            switch ($rank) {
253
                case '2':
254
                    $value += 2;
255
                    break;
256
                case '3':
257
                    $value += 3;
258
                    break;
259
                case '4':
260
                    $value += 4;
261
                    break;
262
                case '5':
263
                    $value += 5;
264
                    break;
265
                case '6':
266
                    $value += 6;
267
                    break;
268
                case '7':
269
                    $value += 7;
270
                    break;
271
                case '8':
272
                    $value += 8;
273
                    break;
274
                case '9':
275
                    $value += 9;
276
                    break;
277
                case '10':
278
                case 'J':
279
                case 'Q':
280
                case 'K':
281
                    $value += 10;
282
                    break;
283
                case 'A':
284
                    $aces++;
285
                    break;
286
            }
287
        }
288
        $variants = [$value];
289
        while ($aces-- > 0) {
290
            $variants = array_flatten(array_map(function ($v) {
291
                return [$v + 1, $v + 11];
292
            }, $variants));
293
        }
294
        $sum = $variants[0];
295
        for ($i = 1; $i < count($variants); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
296
            if ($variants[$i] <= 21) {
297
                $sum = $variants[$i];
298
            } else {
299
                break;
300
            }
301
        }
302
        return $sum;
303
    }
304
305
    private function print(string $text = "")
306
    {
307
        $this->output->writeln(" $text");
308
    }
309
310
    private function printHand(array $hand, int $offset = 1)
311
    {
312
        $cards = [];
313
        for ($i = 0; $i < count($hand) - $offset; $i++) {
314
            [$rank] = $hand[$i];
315
            $cards[] = [
316
                "┌───",
317
                "│" . str_pad($rank, 3),
318
                "│   ",
319
                "│   ",
320
                "│   ",
321
                "│   ",
322
                "└───",
323
            ];
324
        }
325
326
        for (; $i < count($hand); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
327
            [$rank, $suit] = $hand[$i];
328
            $cards[] = [
329
                "┌───────┐",
330
                "│" . str_pad($rank, 7) . "│",
331
                "│       │",
332
                "│   " . $suit . "   │",
333
                "│       │",
334
                "│" . str_pad($rank, 7, " ", STR_PAD_LEFT) . "│",
335
                "└───────┘",
336
            ];
337
        }
338
339
        for ($i = 0; $i < 7; $i++) {
340
            $this->output->write(" ");
341
            foreach ($cards as $lines) {
342
                $this->output->write($lines[$i]);
343
            }
344
            $this->output->write("\n");
345
        }
346
    }
347
348
    private function printWhiskey(int $whiskeyLevel)
349
    {
350
        if ($whiskeyLevel == 4) {
351
            echo <<<ASCII
352
353
                 |          |
354
                 |__________|
355
                 |          |
356
                 | /\ / /\ /|
357
                 |/_/__/__\_|
358
359
360
                ASCII;
361
        }
362
        if ($whiskeyLevel == 3) {
363
            echo <<<ASCII
364
365
                 |          |
366
                 |          |
367
                 |__________|
368
                 | /\ / /\ /|
369
                 |/_/__/__\_|
370
371
372
                ASCII;
373
        }
374
        if ($whiskeyLevel == 2) {
375
            echo <<<ASCII
376
377
                 |          |
378
                 |          |
379
                 |          |
380
                 |_/\_/_/\_/|
381
                 |/_/__/__\_|
382
383
384
                ASCII;
385
        }
386
        if ($whiskeyLevel == 1) {
387
            echo <<<ASCII
388
389
                 |          |
390
                 |          |
391
                 |          |
392
                 | /\ / /\ /|
393
                 |/_/__/__\_|
394
395
396
                ASCII;
397
        }
398
    }
399
}
400