diff options
Diffstat (limited to 'internal/casino/house_edge_fire.go')
| -rw-r--r-- | internal/casino/house_edge_fire.go | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/internal/casino/house_edge_fire.go b/internal/casino/house_edge_fire.go new file mode 100644 index 0000000..3bb1697 --- /dev/null +++ b/internal/casino/house_edge_fire.go @@ -0,0 +1,61 @@ +package casino + +import "math/bits" + +// crapsFireReturn is the fire bet's exact expected return (profit plus stake +// where the bet wins; nothing where it loses) per unit staked. The bet +// resolves only on a point-phase seven-out — a come-out seven keeps the +// shooter's hand and the bet alive — paying 24/249/999:1 for 4/5/6 distinct +// made points. The state is the six-bit mask of distinct points made in the +// hand; come-out rolls and rerolls of an already-made point are self loops. +// Solved by fixed-point iteration over the 64 masks (the chain is absorbing +// and monotone, so iteration converges to the exact solution). +func crapsFireReturn() float64 { + numbers := []int{4, 5, 6, 8, 9, 10} + ways := make([]int, len(numbers)) + for i, n := range numbers { + ways[i] = diceWays(n) + } + pay := func(made int) float64 { + switch made { + case 4: + return 25 // 24:1 profit plus the returned stake + case 5: + return 250 + case 6: + return 1000 + } + return 0 + } + vCome := make([]float64, 64) + for it := 0; it < 2000; it++ { + next := make([]float64, 64) + for mask := 0; mask < 64; mask++ { + sum := 0.0 + for i := range numbers { + w := ways[i] + nm := mask | 1<<i + // Point-phase value of an established point n: making it + // moves to the come-out with the grown mask; a seven (6/36) + // resolves the bet at the CURRENT mask (not the grown one — + // the point has not been made). + made := bits.OnesCount(uint(mask)) + pointValue := (float64(w)/36*vCome[nm] + 6.0/36*pay(made)) / (1 - float64(36-w-6)/36) + sum += float64(w) / 36 * pointValue + } + next[mask] = sum / (24.0 / 36.0) + } + done := true + for i := range next { + if diff := next[i] - vCome[i]; diff > 1e-12 || diff < -1e-12 { + done = false + break + } + } + vCome = next + if done { + break + } + } + return vCome[0] +} |
