@arcanahq/cardgames 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +722 -0
  2. package/as-test.config.js +36 -0
  3. package/asconfig.json +22 -0
  4. package/assembly/__tests__/blackjack/actions/common.spec.ts +180 -0
  5. package/assembly/__tests__/blackjack/actions/dealer_scenarios.spec.ts +452 -0
  6. package/assembly/__tests__/blackjack/actions/double.spec.ts +128 -0
  7. package/assembly/__tests__/blackjack/actions/edge_cases.spec.ts +1041 -0
  8. package/assembly/__tests__/blackjack/actions/insurance.spec.ts +39 -0
  9. package/assembly/__tests__/blackjack/actions/split.spec.ts +96 -0
  10. package/assembly/__tests__/blackjack/actions/stand.spec.ts +103 -0
  11. package/assembly/__tests__/blackjack/actions/surrender.spec.ts +89 -0
  12. package/assembly/__tests__/blackjack/actions/test.ts +18 -0
  13. package/assembly/__tests__/blackjack/rules.spec.ts +231 -0
  14. package/assembly/__tests__/deck/deck.spec.ts +551 -0
  15. package/assembly/__tests__/deck/shoe.spec.ts +410 -0
  16. package/assembly/__tests__/poker/betting_round.spec.ts +103 -0
  17. package/assembly/__tests__/poker/omaha.spec.ts +171 -0
  18. package/assembly/__tests__/poker/pots.spec.ts +255 -0
  19. package/assembly/__tests__/poker/showdown.spec.ts +324 -0
  20. package/assembly/__tests__/poker/six_plus.spec.ts +152 -0
  21. package/assembly/__tests__/poker/stakes.spec.ts +384 -0
  22. package/assembly/__tests__/poker/stud.spec.ts +190 -0
  23. package/assembly/__tests__/poker/test.ts +13 -0
  24. package/assembly/__tests__/test.ts +11 -0
  25. package/assembly/blackjack/actions.ts +191 -0
  26. package/assembly/blackjack/blackjack.ts +571 -0
  27. package/assembly/blackjack/rules.ts +11 -0
  28. package/assembly/cardgames.ts +314 -0
  29. package/assembly/cards.ts +314 -0
  30. package/assembly/cashgames/cash_game_types.ts +142 -0
  31. package/assembly/cashgames/cash_game_utils.ts +223 -0
  32. package/assembly/cashgames/index.ts +10 -0
  33. package/assembly/deck/deck.ts +744 -0
  34. package/assembly/deck/index.ts +9 -0
  35. package/assembly/index.ts +28 -0
  36. package/assembly/poker/index.ts +17 -0
  37. package/assembly/poker/omaha_evaluator.ts +121 -0
  38. package/assembly/poker/poker_game_types.ts +233 -0
  39. package/assembly/poker/poker_game_utils.ts +671 -0
  40. package/assembly/poker/showdown.ts +106 -0
  41. package/assembly/poker/showdown_evaluator.ts +225 -0
  42. package/assembly/poker/six_plus_showdown.ts +96 -0
  43. package/assembly/poker/stud_evaluator.ts +60 -0
  44. package/assembly/poker/variant_utils.ts +51 -0
  45. package/assembly/poker/variants.ts +182 -0
  46. package/assembly/poker.ts +307 -0
  47. package/package.json +51 -0
  48. package/tsconfig.json +16 -0
@@ -0,0 +1,571 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Blackjack Card Game Utilities
4
+ *
5
+ * Provides utilities for blackjack-specific card game operations:
6
+ * - Blackjack card value calculations
7
+ * - Hand value calculations with ace handling
8
+ * - Blackjack-specific game rules
9
+ */
10
+
11
+ import { Card, Rank, Suit } from "../cards";
12
+
13
+ /**
14
+ * Extended Card class for blackjack with hidden card support
15
+ */
16
+ export class BlackjackCard extends Card {
17
+ isHidden: bool;
18
+
19
+ constructor(suit: string = "", rank: string = "", isHidden: bool = false) {
20
+ super(suit, rank);
21
+ this.isHidden = isHidden;
22
+ }
23
+
24
+ static fromCard(card: Card, isHidden: bool = false): BlackjackCard {
25
+ return new BlackjackCard(card.suit, card.rank, isHidden);
26
+ }
27
+
28
+ clone(): BlackjackCard {
29
+ return new BlackjackCard(this.suit, this.rank, this.isHidden);
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Gets the numeric value of a card rank for blackjack
35
+ * Aces return 11 (will be adjusted in hand calculation)
36
+ * Face cards (J, Q, K) return 10
37
+ * Number cards return their face value
38
+ */
39
+ export function getBlackjackCardValue(card: Card): i32 {
40
+ if (card.rank === Rank.ACE) {
41
+ return 11; // Default to 11, will be adjusted in hand calculation
42
+ } else if (card.rank === Rank.JACK || card.rank === Rank.QUEEN || card.rank === Rank.KING) {
43
+ return 10;
44
+ } else if (card.rank === "?") {
45
+ return 0; // Unknown card
46
+ } else {
47
+ // Parse number cards (2-10)
48
+ const num = parseInt(card.rank);
49
+ if (isNaN(num) || num < 2 || num > 10) {
50
+ return 0;
51
+ }
52
+ return <i32>num;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Calculates the optimal value of a hand in blackjack
58
+ * Aces are counted as 11 when beneficial, otherwise as 1
59
+ */
60
+ export function calculateBlackjackHandValue(cards: Card[]): i32 {
61
+ if (cards.length === 0) {
62
+ return 0;
63
+ }
64
+
65
+ let total: i32 = 0;
66
+ let aces: i32 = 0;
67
+
68
+ // First pass: count all cards, treating aces as 11
69
+ for (let i = 0; i < cards.length; i++) {
70
+ const card = cards[i];
71
+ if (!card) {
72
+ continue; // Skip null cards
73
+ }
74
+
75
+ // Skip hidden cards (for blackjack, we check isHidden property)
76
+ // Check if card is a BlackjackCard by checking if it has isHidden property
77
+ // We use a type guard: if the card is a BlackjackCard, it will have isHidden
78
+ const bjCard = changetype<BlackjackCard>(card);
79
+ if (bjCard !== null && bjCard.isHidden === true) {
80
+ continue;
81
+ }
82
+ // Also check for suit === "hidden" for backward compatibility
83
+ if (card.suit === "hidden") {
84
+ continue;
85
+ }
86
+
87
+ if (card.rank === Rank.ACE) {
88
+ aces++;
89
+ total += 11;
90
+ } else {
91
+ total += getBlackjackCardValue(card);
92
+ }
93
+ }
94
+
95
+ // Adjust aces down from 11 to 1 if needed to avoid busting
96
+ while (total > 21 && aces > 0) {
97
+ total -= 10; // Convert one ace from 11 to 1
98
+ aces--;
99
+ }
100
+
101
+ return total;
102
+ }
103
+
104
+ /**
105
+ * Checks if a hand is a blackjack (21 with exactly 2 cards)
106
+ */
107
+ export function isBlackjack(cards: Card[]): bool {
108
+ return cards.length === 2 && calculateBlackjackHandValue(cards) === 21;
109
+ }
110
+
111
+ /**
112
+ * Checks if a hand is busted (over 21)
113
+ */
114
+ export function isBusted(cards: Card[]): bool {
115
+ return calculateBlackjackHandValue(cards) > 21;
116
+ }
117
+
118
+ /**
119
+ * Checks if two cards can be split (same rank)
120
+ */
121
+ export function canSplitCards(cards: Card[]): bool {
122
+ if (cards.length !== 2) {
123
+ return false;
124
+ }
125
+
126
+ const rank1 = cards[0].rank;
127
+ const rank2 = cards[1].rank;
128
+
129
+ // Special case: face cards (J, Q, K) can split with each other
130
+ if ((rank1 === Rank.JACK || rank1 === Rank.QUEEN || rank1 === Rank.KING) &&
131
+ (rank2 === Rank.JACK || rank2 === Rank.QUEEN || rank2 === Rank.KING)) {
132
+ return true;
133
+ }
134
+
135
+ // Otherwise, ranks must match exactly
136
+ return rank1 === rank2;
137
+ }
138
+
139
+
140
+ /**
141
+ * Configurable Blackjack Rules
142
+ * Supports different blackjack variants (standard, Spanish 21, etc.)
143
+ */
144
+ export class BlackjackRules {
145
+ // Dealer rules
146
+ dealerStandValue: i32 = 17; // Dealer stands on this value or higher
147
+ hitOnSoft17: bool = false; // Dealer hits on soft 17 (A-6) if true, stands if false
148
+
149
+ // Game mechanics
150
+ maxSplitHands: i32 = 4; // Maximum number of hands from splitting
151
+ doubleAfterSplit: bool = false; // Allow double after split (standard is false)
152
+ surrenderAllowed: bool = true; // Allow surrender
153
+ lateSurrender: bool = false; // Late surrender (after dealer checks for blackjack)
154
+ insuranceOffered: bool = true; // Offer insurance when dealer shows ace
155
+
156
+ // Deck configuration
157
+ isSpanish21: bool = false; // Spanish 21 uses 48-card deck (no 10s)
158
+ deckSize: i32 = 52; // Standard deck size (48 for Spanish 21)
159
+
160
+ // Hand values
161
+ blackjackValue: i32 = 21;
162
+ bustValue: i32 = 22;
163
+
164
+ // Payout rates (as multipliers)
165
+ payoutBlackjack: f64 = 1.5; // 3:2
166
+ payoutWin: f64 = 1.0; // 1:1
167
+ payoutPush: f64 = 1.0; // 1:1 (return bet)
168
+ payoutLose: f64 = 0.0; // 0:1
169
+ payoutSurrender: f64 = 0.5; // 0.5:1 (half bet returned)
170
+ payoutInsurance: f64 = 2.0; // 2:1
171
+
172
+ constructor(
173
+ dealerStandValue: i32 = 17,
174
+ hitOnSoft17: bool = false,
175
+ maxSplitHands: i32 = 4,
176
+ doubleAfterSplit: bool = false,
177
+ surrenderAllowed: bool = true,
178
+ lateSurrender: bool = false,
179
+ insuranceOffered: bool = true,
180
+ isSpanish21: bool = false,
181
+ payoutBlackjack: f64 = 1.5,
182
+ payoutWin: f64 = 1.0,
183
+ payoutPush: f64 = 1.0,
184
+ payoutLose: f64 = 0.0,
185
+ payoutSurrender: f64 = 0.5,
186
+ payoutInsurance: f64 = 2.0
187
+ ) {
188
+ this.dealerStandValue = dealerStandValue;
189
+ this.hitOnSoft17 = hitOnSoft17;
190
+ this.maxSplitHands = maxSplitHands;
191
+ this.doubleAfterSplit = doubleAfterSplit;
192
+ this.surrenderAllowed = surrenderAllowed;
193
+ this.lateSurrender = lateSurrender;
194
+ this.insuranceOffered = insuranceOffered;
195
+ this.isSpanish21 = isSpanish21;
196
+ this.deckSize = isSpanish21 ? 48 : 52;
197
+ this.payoutBlackjack = payoutBlackjack;
198
+ this.payoutWin = payoutWin;
199
+ this.payoutPush = payoutPush;
200
+ this.payoutLose = payoutLose;
201
+ this.payoutSurrender = payoutSurrender;
202
+ this.payoutInsurance = payoutInsurance;
203
+ }
204
+
205
+ /**
206
+ * Create standard blackjack rules (most common casino rules)
207
+ */
208
+ static standard(): BlackjackRules {
209
+ return new BlackjackRules(
210
+ 17, // dealerStandValue
211
+ false, // hitOnSoft17 (most casinos stand on soft 17)
212
+ 4, // maxSplitHands
213
+ false, // doubleAfterSplit (standard rule: no double after split)
214
+ true, // surrenderAllowed
215
+ false, // lateSurrender
216
+ true, // insuranceOffered
217
+ false // isSpanish21
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Create Spanish 21 rules (48-card deck, no 10s)
223
+ */
224
+ static spanish21(): BlackjackRules {
225
+ return new BlackjackRules(
226
+ 17, // dealerStandValue
227
+ true, // hitOnSoft17 (Spanish 21 typically hits on soft 17)
228
+ 4, // maxSplitHands
229
+ true, // doubleAfterSplit (Spanish 21 allows double after split)
230
+ true, // surrenderAllowed
231
+ false, // lateSurrender
232
+ false, // insuranceOffered (Spanish 21 doesn't offer insurance)
233
+ true // isSpanish21
234
+ );
235
+ }
236
+
237
+ /**
238
+ * Create rules with dealer hitting on soft 17
239
+ */
240
+ static dealerHitsSoft17(): BlackjackRules {
241
+ const rules = BlackjackRules.standard();
242
+ rules.hitOnSoft17 = true;
243
+ return rules;
244
+ }
245
+
246
+ /**
247
+ * Create rules allowing double after split
248
+ */
249
+ static allowDoubleAfterSplit(): BlackjackRules {
250
+ const rules = BlackjackRules.standard();
251
+ rules.doubleAfterSplit = true;
252
+ return rules;
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Legacy static constants for backward compatibility
258
+ */
259
+ export class BlackjackPayouts {
260
+ static readonly BLACKJACK: f64 = 1.5; // 3:2
261
+ static readonly WIN: f64 = 1.0; // 1:1
262
+ static readonly PUSH: f64 = 1.0; // 1:1 (return bet)
263
+ static readonly LOSE: f64 = 0.0; // 0:1
264
+ static readonly SURRENDER: f64 = 0.5; // 0.5:1 (half bet returned)
265
+ static readonly INSURANCE: f64 = 2.0; // 2:1
266
+ }
267
+
268
+ /**
269
+ * Checks if a hand is a soft hand (contains an ace counted as 11)
270
+ * A soft hand is one where an ace is counted as 11 and the hand value could be reduced by 10
271
+ * This is used to determine dealer behavior on soft 17
272
+ */
273
+ export function isSoftHand(cards: Card[]): bool {
274
+ if (cards.length === 0) {
275
+ return false;
276
+ }
277
+
278
+ let hasAce = false;
279
+ let nonAceValue: i32 = 0;
280
+
281
+ for (let i = 0; i < cards.length; i++) {
282
+ const card = cards[i];
283
+ if (!card) continue;
284
+
285
+ // Check if card is a BlackjackCard with isHidden property
286
+ const bjCard = changetype<BlackjackCard>(card);
287
+ if (bjCard !== null && bjCard.isHidden === true) continue;
288
+ if (card.suit === "hidden") continue;
289
+
290
+ if (card.rank === Rank.ACE) {
291
+ hasAce = true;
292
+ } else {
293
+ nonAceValue += getBlackjackCardValue(card);
294
+ }
295
+ }
296
+
297
+ if (!hasAce) {
298
+ return false;
299
+ }
300
+
301
+ // A soft hand is one where we can count an ace as 11
302
+ // Check if hand value is exactly 17 and has an ace (soft 17)
303
+ const handValue = calculateBlackjackHandValue(cards);
304
+
305
+ // If hand value is 17 and has an ace, check if it's soft
306
+ if (handValue === 17 && hasAce) {
307
+ // Calculate hard value (treating all aces as 1)
308
+ let hardValue: i32 = 0;
309
+ for (let i = 0; i < cards.length; i++) {
310
+ const card = cards[i];
311
+ if (!card) continue;
312
+ const bjCard = changetype<BlackjackCard>(card);
313
+ if (bjCard !== null && bjCard.isHidden === true) continue;
314
+ if (card.suit === "hidden") continue;
315
+
316
+ if (card.rank === Rank.ACE) {
317
+ hardValue += 1; // Ace as 1
318
+ } else {
319
+ hardValue += getBlackjackCardValue(card);
320
+ }
321
+ }
322
+ // If hard value is less than 17, it's a soft 17
323
+ return hardValue < 17;
324
+ }
325
+
326
+ // For other values, check if we can count an ace as 11 without busting
327
+ return hasAce && (nonAceValue + 11 <= 21);
328
+ }
329
+
330
+ /**
331
+ * Determines if dealer should hit based on configurable rules
332
+ * @param cards Dealer's cards
333
+ * @param rules Blackjack rules configuration
334
+ * @returns true if dealer should hit, false if dealer should stand
335
+ */
336
+ export function dealerShouldHit(cards: Card[], rules: BlackjackRules): bool {
337
+ const handValue = calculateBlackjackHandValue(cards);
338
+
339
+ // Dealer must hit if below stand value
340
+ if (handValue < rules.dealerStandValue) {
341
+ return true;
342
+ }
343
+
344
+ // Dealer stands if above stand value
345
+ if (handValue > rules.dealerStandValue) {
346
+ return false;
347
+ }
348
+
349
+ // At exactly stand value (17), check if it's soft 17
350
+ if (handValue === rules.dealerStandValue) {
351
+ // If dealer hits on soft 17 and this is a soft hand, dealer hits
352
+ if (rules.hitOnSoft17 && isSoftHand(cards)) {
353
+ return true;
354
+ }
355
+ // Otherwise dealer stands
356
+ return false;
357
+ }
358
+
359
+ return false;
360
+ }
361
+
362
+ /**
363
+ * Result class for Pair Plus bonus bet evaluation
364
+ */
365
+ export class PairPlusResult {
366
+ hasPair: bool = false;
367
+ pairType: string = ""; // "perfect", "colored", "mixed", or ""
368
+ payoutMultiplier: i32 = 0; // 25, 10, 5, or 0
369
+ }
370
+
371
+ /**
372
+ * Result class for 21+3 bonus bet evaluation
373
+ */
374
+ export class TwentyOnePlusThreeResult {
375
+ hasMatch: bool = false;
376
+ handType: string = ""; // "suited_three_kind", "straight_flush", "three_kind", "straight", "flush", or ""
377
+ payoutMultiplier: i32 = 0; // 100, 40, 30, 10, 5, or 0
378
+ }
379
+
380
+ /**
381
+ * Get card color (red or black) from suit
382
+ * Hearts and Diamonds are red, Spades and Clubs are black
383
+ */
384
+ function getCardColor(suit: string): string {
385
+ if (suit === Suit.HEARTS || suit === Suit.DIAMONDS) {
386
+ return "red";
387
+ } else if (suit === Suit.SPADES || suit === Suit.CLUBS) {
388
+ return "black";
389
+ }
390
+ return "";
391
+ }
392
+
393
+ /**
394
+ * Check if all cards have the same rank
395
+ */
396
+ function isThreeOfAKind(cards: Card[]): bool {
397
+ if (cards.length !== 3) {
398
+ return false;
399
+ }
400
+ const rank1 = cards[0].rank;
401
+ const rank2 = cards[1].rank;
402
+ const rank3 = cards[2].rank;
403
+ return rank1 === rank2 && rank2 === rank3;
404
+ }
405
+
406
+ /**
407
+ * Check if all cards have the same suit
408
+ */
409
+ function isFlush(cards: Card[]): bool {
410
+ if (cards.length !== 3) {
411
+ return false;
412
+ }
413
+ const suit1 = cards[0].suit;
414
+ const suit2 = cards[1].suit;
415
+ const suit3 = cards[2].suit;
416
+ return suit1 === suit2 && suit2 === suit3;
417
+ }
418
+
419
+ /**
420
+ * Check if all cards have the same rank and suit (suited three of a kind)
421
+ */
422
+ function isSuitedThreeOfAKind(cards: Card[]): bool {
423
+ if (cards.length !== 3) {
424
+ return false;
425
+ }
426
+ return isThreeOfAKind(cards) && isFlush(cards);
427
+ }
428
+
429
+ /**
430
+ * Check if 3 cards form a straight (consecutive ranks)
431
+ * Handles A-2-3 and Q-K-A straights
432
+ */
433
+ function isStraight(cards: Card[]): bool {
434
+ if (cards.length !== 3) {
435
+ return false;
436
+ }
437
+
438
+ // Get rank values
439
+ const rankValues = new Array<i32>(3);
440
+ for (let i = 0; i < 3; i++) {
441
+ rankValues[i] = Rank.getValue(cards[i].rank);
442
+ }
443
+
444
+ // Sort rank values
445
+ rankValues.sort((a, b) => a - b);
446
+
447
+ // Check normal straight (e.g., 2-3-4, 5-6-7)
448
+ if (rankValues[1] === rankValues[0] + 1 && rankValues[2] === rankValues[1] + 1) {
449
+ return true;
450
+ }
451
+
452
+ // Check A-2-3 straight (wheel)
453
+ if (rankValues[0] === 2 && rankValues[1] === 3 && rankValues[2] === 14) {
454
+ return true;
455
+ }
456
+
457
+ // Check Q-K-A straight
458
+ if (rankValues[0] === 12 && rankValues[1] === 13 && rankValues[2] === 14) {
459
+ return true;
460
+ }
461
+
462
+ return false;
463
+ }
464
+
465
+ /**
466
+ * Check if cards form a straight flush (straight + flush)
467
+ */
468
+ function isStraightFlush(cards: Card[]): bool {
469
+ return isStraight(cards) && isFlush(cards);
470
+ }
471
+
472
+ /**
473
+ * Evaluate Pair Plus bonus bet
474
+ * Checks if the first two cards form a pair and what type
475
+ * @param card1 First player card
476
+ * @param card2 Second player card
477
+ * @returns PairPlusResult with pair type and payout multiplier
478
+ */
479
+ export function evaluatePairPlus(card1: Card, card2: Card): PairPlusResult {
480
+ const result = new PairPlusResult();
481
+
482
+ // Check if ranks match
483
+ if (card1.rank !== card2.rank) {
484
+ return result; // No pair
485
+ }
486
+
487
+ result.hasPair = true;
488
+
489
+ // Perfect pair: same rank and suit
490
+ if (card1.suit === card2.suit) {
491
+ result.pairType = "perfect";
492
+ result.payoutMultiplier = 25;
493
+ return result;
494
+ }
495
+
496
+ // Check if same color
497
+ const color1 = getCardColor(card1.suit);
498
+ const color2 = getCardColor(card2.suit);
499
+
500
+ if (color1 === color2 && color1.length > 0) {
501
+ result.pairType = "colored";
502
+ result.payoutMultiplier = 10;
503
+ return result;
504
+ }
505
+
506
+ // Mixed pair: same rank, different suits (and different colors)
507
+ result.pairType = "mixed";
508
+ result.payoutMultiplier = 5;
509
+ return result;
510
+ }
511
+
512
+ /**
513
+ * Evaluate 21+3 bonus bet
514
+ * Uses player's two cards plus dealer's upcard to form a three-card poker hand
515
+ * @param card1 First player card
516
+ * @param card2 Second player card
517
+ * @param card3 Dealer's upcard
518
+ * @returns TwentyOnePlusThreeResult with hand type and payout multiplier
519
+ */
520
+ export function evaluateTwentyOnePlusThree(card1: Card, card2: Card, card3: Card): TwentyOnePlusThreeResult {
521
+ const result = new TwentyOnePlusThreeResult();
522
+ const cards = new Array<Card>(3);
523
+ cards[0] = card1;
524
+ cards[1] = card2;
525
+ cards[2] = card3;
526
+
527
+ // Check in order of highest payout first
528
+
529
+ // Suited three of a kind: all same rank and suit (100:1)
530
+ if (isSuitedThreeOfAKind(cards)) {
531
+ result.hasMatch = true;
532
+ result.handType = "suited_three_kind";
533
+ result.payoutMultiplier = 100;
534
+ return result;
535
+ }
536
+
537
+ // Straight flush: straight + flush (40:1)
538
+ if (isStraightFlush(cards)) {
539
+ result.hasMatch = true;
540
+ result.handType = "straight_flush";
541
+ result.payoutMultiplier = 40;
542
+ return result;
543
+ }
544
+
545
+ // Three of a kind: all same rank (30:1)
546
+ if (isThreeOfAKind(cards)) {
547
+ result.hasMatch = true;
548
+ result.handType = "three_kind";
549
+ result.payoutMultiplier = 30;
550
+ return result;
551
+ }
552
+
553
+ // Straight: consecutive ranks (10:1)
554
+ if (isStraight(cards)) {
555
+ result.hasMatch = true;
556
+ result.handType = "straight";
557
+ result.payoutMultiplier = 10;
558
+ return result;
559
+ }
560
+
561
+ // Flush: all same suit (5:1)
562
+ if (isFlush(cards)) {
563
+ result.hasMatch = true;
564
+ result.handType = "flush";
565
+ result.payoutMultiplier = 5;
566
+ return result;
567
+ }
568
+
569
+ // No match
570
+ return result;
571
+ }
@@ -0,0 +1,11 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * Blackjack Rules Configuration
4
+ *
5
+ * Provides configurable blackjack rules for different game variants
6
+ */
7
+
8
+ // Card and Rank are used in blackjack.ts, not here
9
+
10
+ // Re-export from local blackjack module
11
+ export { BlackjackRules, BlackjackPayouts, dealerShouldHit, isSoftHand, calculateBlackjackHandValue, isBlackjack as coreIsBlackjack, isBusted as coreIsBusted, canSplitCards as coreCanSplitCards, PairPlusResult, evaluatePairPlus, TwentyOnePlusThreeResult, evaluateTwentyOnePlusThree } from "./blackjack";