diff options
Diffstat (limited to 'internal/game/render_cash_hunt.go')
| -rw-r--r-- | internal/game/render_cash_hunt.go | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/internal/game/render_cash_hunt.go b/internal/game/render_cash_hunt.go new file mode 100644 index 0000000..374d6c8 --- /dev/null +++ b/internal/game/render_cash_hunt.go @@ -0,0 +1,110 @@ +package game + +import ( + "fmt" + "strings" + + "thehouseoficarus/internal/casino" + "thehouseoficarus/internal/color" +) + +func cashHuntPrizeColor(multiplier int) int { + switch { + case multiplier >= 10000: + return 225 + case multiplier >= 500: + return 201 + case multiplier >= 100: + return 220 + case multiplier >= 20: + return 207 + case multiplier >= 5: + return 141 + case multiplier >= 2: + return 81 + case multiplier == 1: + return 120 + default: + return 240 + } +} + +const ( + cashHuntColumns = 10 + cashHuntTileWidth = 7 +) + +// cashHuntTileColors is a dark rainbow, one hue per column. The shades stay +// dark enough for bright prize text while replacing the old black/blue checker. +var cashHuntTileColors = [cashHuntColumns]int{88, 94, 100, 28, 29, 30, 24, 18, 90, 89} + +// cashHuntCenter pads text to a fixed tile width, keeping every column aligned +// whether it holds a one- or three-digit square number. +func cashHuntCenter(text string, width int) string { + if len(text) >= width { + return text + } + left := (width - len(text)) / 2 + return strings.Repeat(" ", left) + text + strings.Repeat(" ", width-len(text)-left) +} + +func renderCashHunt(s *casino.CashHuntSnapshot, mode string, unicode bool) string { + paint := func(text string, fg int) string { return color.Render(mode, color.ColorSpec{Fg: fg, Bg: -1}, text) } + title := paint("CASH HUNT / "+strings.ToUpper(s.Risk)+" / 98% RTP", 220) + switch s.Phase { + case "hidden": + side, topLeft, topRight, bottomLeft, bottomRight, bar := "|", "+", "+", "+", "+", "-" + if unicode { + side, topLeft, topRight, bottomLeft, bottomRight, bar = "│", "╭", "╮", "╰", "╯", "─" + } + lines := []string{topLeft + strings.Repeat(bar, 68) + topRight} + for _, text := range []string{"* THE VAULT WHIRLS ... THE PRIZES VANISH! *", "All 100 positions have been hidden and mixed.", "The prizes are sealed. Your choice unlocks one.", "Choose your square: type 1-100, or pick N."} { + padding := 68 - len(text) + lines = append(lines, side+strings.Repeat(" ", padding/2)+text+strings.Repeat(" ", padding-padding/2)+side) + } + lines = append(lines, bottomLeft+strings.Repeat(bar, 68)+bottomRight) + for i, line := range lines { + lines[i] = color.Render(mode, color.ColorSpec{Fg: -1, Bg: -1, Gradient: []int{196, 208, 220, 46, 51, 45, 39, 21, 201, 207}}, line) + } + return strings.Join(lines, "\n") + case "paytable": + lines := []string{title, "Prize Chance per square"} + for _, prize := range s.Odds { + lines = append(lines, paint(fmt.Sprintf("%6dx %10.6f%%", prize.Multiplier, float64(prize.Weight)/1_000_000), cashHuntPrizeColor(prize.Multiplier))) + } + return strings.Join(append(lines, "Returns include stake. Each board's mix varies; jackpots are not guaranteed."), "\n") + case "preview", "result": + // Ten columns, two lines per tile: all 100 labels and even 50000x fit + // into a 70-column canvas without relying on cursor controls. + lines := []string{title} + if s.Phase == "preview" { + highest := 0 + for _, value := range s.Squares { + highest = max(highest, value) + } + lines = append(lines, paint(fmt.Sprintf("PRIZE PREVIEW / top prize %dx / positions will be mixed", highest), cashHuntPrizeColor(highest))) + } else { + lines = append(lines, paint(fmt.Sprintf("YOUR PICK: %d / %dx", s.Selected, s.Squares[s.Selected-1]), 220)) + } + for start := 0; start < casino.CashHuntSquares; start += cashHuntColumns { + var numbers, prizes strings.Builder + for k := start; k < start+cashHuntColumns; k++ { + bg := cashHuntTileColors[k%cashHuntColumns] + number := cashHuntCenter(fmt.Sprintf("%d", k+1), cashHuntTileWidth) + value := cashHuntCenter(fmt.Sprintf("%dx", s.Squares[k]), cashHuntTileWidth) + nf, vf := 246, cashHuntPrizeColor(s.Squares[k]) + selected := s.Selected == k+1 + if selected { + number = cashHuntCenter(fmt.Sprintf(">%d<", k+1), cashHuntTileWidth) + nf, vf, bg = 16, 16, 226 + } + numbers.WriteString(color.Render(mode, color.ColorSpec{Fg: nf, Bg: bg, Bold: selected}, number)) + prizes.WriteString(color.Render(mode, color.ColorSpec{Fg: vf, Bg: bg, Bold: selected}, value)) + } + lines = append(lines, numbers.String(), prizes.String()) + } + return strings.Join(lines, "\n") + default: + return title + "\n" + paint("100 squares. One choice. Prizes from 0x to 50000x.", 81) + } +} |
