aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/craps_ux.go
blob: 41f671ab8e48f42beb6ca78b71493a6e1c95f998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package casino

import (
	"fmt"
	"strings"
)

func (t *crapsTable) commands() []MenuCommand {
	return []MenuCommand{
		{Command: "bet <amount> on <target>", Desc: "Place bets until the dice roll; table rules lists targets"},
		{Command: "roll / autoroll / stop", Desc: "Shoot / repeat on your turn / return to manual play"},
		{Command: "unbet <target> | unbet all", Desc: "Remove one bet / every optional bet"},
		{Command: "table", Desc: "View the felt"},
	}
}
func crapsBetLabel(b *crapsBet) string {
	names := map[string]string{"pass": "Pass", "dontpass": "Don't pass", "come": "Come", "dontcome": "Don't come", "ace-deuce": "Ace-deuce", "small": "All Small", "tall": "All Tall", "all": "All", "fire": "Fire"}
	label := names[b.kind]
	if label == "" {
		label = gameTitle(GameName(b.kind))
	}
	if b.kind == "hop" {
		return fmt.Sprintf("Hop [%d + %d]", b.number/10, b.number%10)
	}
	if b.number != 0 {
		label += fmt.Sprintf(" [%d]", b.number)
	}
	return label
}

// Numbers describe covered targets, not a promise that every listed roll wins
// (don't/lay bets oppose their number; bonus bets need complete sequences).
// betSummary lists each open wager, then the dice pairs that beat them. The
// roll table shares payout math with settlement (crapsNet), so the numbers
// never promise a win a real roll cannot pay.
func (t *crapsTable) betSummary(p *crapsPlayer) Event {
	text := "{casino_emphasis}YOUR BETS{/}"
	if len(p.bets) == 0 {
		text += "  No active bets."
	} else {
		for _, b := range p.bets {
			label := crapsBetLabel(b)
			if strings.HasPrefix(b.kind, "dont") || b.kind == "lay" {
				label += " (against)"
			}
			if t.point == 0 && (b.kind == "place" || b.kind == "buy" || b.kind == "hard") {
				label += " (off)"
			}
			text += fmt.Sprintf("\n  {casino_action}%-24s{/} {casino_chips}%d{/}", label, b.stake.Total)
			if b.odds.Total > 0 {
				text += fmt.Sprintf(" + %d odds", b.odds.Total)
				if t.point == 0 && b.kind == "come" {
					text += " (odds off)"
				}
			}
		}
	}
	e := t.private(p.Name, text+"\n"+t.rollTable(p))
	e.ShowBalance = true
	return e
}
func (t *crapsTable) reminder(name string) Event {
	e := t.private(name, "Your move")
	e.Color = "casino_menu"
	e.Menu = &MenuView{Heading: "Your move", Commands: t.commands()}
	return e
}
func (t *crapsTable) settlementEvent(p *crapsPlayer, lines []settlementLine, failed bool) Event {
	text := ""
	if len(lines) > 0 {
		text = settlementText(lines)
	}
	if failed {
		if text != "" {
			text += "\n"
		}
		text += payoutFailedMessage()
	}
	e := t.private(p.Name, text)
	if len(lines) > 0 {
		e.Color = settlementTag(lines)
	}
	return e
}