From c6d4702c0be4d2b37e1d82ff96265c52847c3f9a Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sat, 3 Oct 2026 17:36:06 -0400 Subject: feat: partial commands now always work --- internal/casino/big_six.go | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'internal/casino/big_six.go') diff --git a/internal/casino/big_six.go b/internal/casino/big_six.go index 6d16bbc..b17bde4 100644 --- a/internal/casino/big_six.go +++ b/internal/casino/big_six.go @@ -34,9 +34,43 @@ func bigSixHouseEdge(_ TableConfig, bet string) HouseEdge { func bigSixTarget(s string) string { return strings.TrimPrefix(strings.ToUpper(strings.TrimSpace(s)), "$") } + +// bigSixResolveTarget maps a written target to a betting symbol. An exact +// label always wins over a longer label that shares its prefix, so "1" is the +// $1 symbol and never an ambiguous prefix of $10. Otherwise an unambiguous +// prefix is accepted, so "SW", "SWO" and "SWORD" all name the sword and "SH" +// names the shield. DOUBLE is not a betting target, so "DO" resolves to +// nothing. It reports false when nothing or more than one symbol matches. +func bigSixResolveTarget(s string) (string, bool) { + t := bigSixTarget(s) + if t == "" { + return "", false + } + match := "" + for _, spot := range BigSixSpots() { + if spot.Pays <= 0 { + continue + } + if spot.Label == t { + return spot.Label, true + } + if strings.HasPrefix(spot.Label, t) { + if match != "" { + return "", false + } + match = spot.Label + } + } + return match, match != "" +} + func bigSixPayout(s string) int { + target, ok := bigSixResolveTarget(s) + if !ok { + return 0 + } for _, spot := range BigSixSpots() { - if spot.Label == bigSixTarget(s) && spot.Pays > 0 { + if spot.Label == target { return spot.Pays + 1 } } @@ -225,10 +259,11 @@ func (t *bigSixTable) bet(name, spot string, amount int, w Wallet) []Event { if spot == "" { spot = p.lastSpot } - spot = bigSixTarget(spot) - if bigSixPayout(spot) == 0 { - return []Event{t.private(name, "Bet on 1, 2, 5, 10, 20, SWORD or SHIELD. DOUBLE is automatic, not a bet.")} + resolved, ok := bigSixResolveTarget(spot) + if !ok { + return []Event{t.private(name, "Bet on 1, 2, 5, 10, 20, SWORD or SHIELD — an unambiguous prefix is fine. DOUBLE is automatic, not a bet.")} } + spot = resolved if amount < t.Config.MinBet || amount > t.Config.MaxBet { return []Event{t.private(name, "Big 6 bets must be "+betRangeText(t.Config.MinBet, t.Config.MaxBet)+".")} } -- cgit v1.2.3