diff options
Diffstat (limited to 'internal/casino/baccarat_variants.go')
| -rw-r--r-- | internal/casino/baccarat_variants.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/internal/casino/baccarat_variants.go b/internal/casino/baccarat_variants.go new file mode 100644 index 0000000..95b5041 --- /dev/null +++ b/internal/casino/baccarat_variants.go @@ -0,0 +1,98 @@ +package casino + +import "strings" + +const ( + BaccaratCommission = "commission" + BaccaratSuper6 = "super_6" + BaccaratEZ = "ez_baccarat" +) + +// Optional wagers use fixed, conventional profit odds. They are evaluated +// independently of the main Banker wager (notably the EZ Dragon 7 push). +func (c BaccaratConfig) spots() []string { + spots := []string{baccaratSpotPlayer, baccaratSpotBanker, baccaratSpotTie} + if c.PairBets { + spots = append(spots, "player_pair", "banker_pair") + } + if c.Dragon7 { + spots = append(spots, "dragon_7") + } + if c.Panda8 { + spots = append(spots, "panda_8") + } + if c.Super6Bet { + spots = append(spots, "super_6") + } + return spots +} + +func (c BaccaratConfig) allowsSpot(spot string) bool { + for _, allowed := range c.spots() { + if spot == allowed { + return true + } + } + return false +} + +func (c BaccaratConfig) betChoices() string { return strings.Join(c.spots(), "|") } + +func baccaratPair(hand []card) bool { + return len(hand) >= 2 && hand[0].rank == hand[1].rank +} + +// settleBaccaratHand needs the complete hands: totals alone cannot identify +// a three-card seven/eight or an initial pair. +func settleBaccaratHand(spot string, bet int, player, banker []card, rules BaccaratConfig) (string, int, error) { + rules = rules.Normalize() + if !rules.allowsSpot(spot) { + return "loss", 0, nil + } + pt, bt := baccaratTotal(player), baccaratTotal(banker) + win, odds := false, 0.0 + switch spot { + case "player_pair": + win, odds = baccaratPair(player), 11 + case "banker_pair": + win, odds = baccaratPair(banker), 11 + case "dragon_7": + win, odds = bt > pt && bt == 7 && len(banker) == 3, 40 + case "panda_8": + win, odds = pt > bt && pt == 8 && len(player) == 3, 25 + case "super_6": + win, odds = bt > pt && bt == 6, 12 + default: + if spot == baccaratSpotBanker && bt > pt { + if rules.Variant == BaccaratEZ && bt == 7 && len(banker) == 3 { + return "push", bet, nil + } + if rules.Variant == BaccaratSuper6 && bt == 6 { + // Floor the total return, not a positive-profit minimum: a one-credit + // stake returns one credit, not two, on this half-pay outcome. + payout, err := MulPayout(bet, 1.5) + return "win", payout, err + } + } + return settleBaccaratBet(spot, bet, pt, bt, rules) + } + if !win { + return "loss", 0, nil + } + payout, err := MulPayout(bet, 1+odds) + return "win", payout, err +} + +func baccaratVariantOutcome(player, banker []card, rules BaccaratConfig) string { + pt, bt := baccaratTotal(player), baccaratTotal(banker) + if bt <= pt { + return "" + } + if rules.Variant == BaccaratEZ && bt == 7 && len(banker) == 3 { + return "EZ Baccarat: Banker wins with a three-card 7. Banker bets push; Player bets lose." + } + if rules.Variant == BaccaratSuper6 && bt == 6 { + return "Super 6: Banker wins with 6. Banker bets pay 1:2." + } + return "" +} |
