aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/table_hints.go
blob: d44deb7655ef465e263bd19388db8e3f505fc3c7 (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
85
86
87
88
89
package casino

import "fmt"

// Per-game live-hint registration: every game answers the same two views
// through the tableGame interface — its full hint list (finished with the
// shared "rules" and "list" entries) and its wager table — so the shared
// table controls never need a per-game switch. All entries are seated only;
// a standing player is not told how to bet at a game they have not joined.

func (t *crapsTable) wagers(name string) []WagerRow   { return t.wagerRows(name) }
func (t *crapsTable) hints(name string) []MenuCommand { return t.commands(name) }

func (t *rouletteTable) wagers(name string) []WagerRow { return t.wagerRows() }
func (t *rouletteTable) hints(name string) []MenuCommand {
	p := t.players.get(name)
	if p == nil {
		return nil
	}
	commands := []MenuCommand{}
	if t.phase != phasePlaying && !p.HasBet {
		commands = append(commands, MenuCommand{Command: "bet <amount> on <target>", Desc: "Place one wager; targets: list"})
		if p.lastBet > 0 {
			commands = append(commands, MenuCommand{Command: "bet / rebet", Desc: "Repeat your previous wager"})
		}
	}
	commands = append(commands, MenuCommand{Command: "stop", Desc: "Leave when your wager settles"})
	commands = append(commands, MenuCommand{Command: "table", Desc: "View the layout"})
	return withTableHints(commands, t.wagerRows())
}

// blackjackHintsIdle are the shared controls for a bettor with no structured
// menu right now (an in-flight round has no betting menu to reuse).
func blackjackHintsIdle() []MenuCommand {
	return []MenuCommand{
		{Command: "table", Desc: "View the table"},
		{Command: "stop", Desc: "Leave after this round"},
	}
}

func (t *blackjackTable) wagers(name string) []WagerRow { return t.wagerRows(name) }
func (t *blackjackTable) hints(name string) []MenuCommand {
	if t.players.get(name) == nil {
		return nil
	}
	var commands []MenuCommand
	if menu := t.menuEvent(name); menu.Menu != nil && len(menu.Menu.Commands) > 0 {
		// The real menu is authoritative: betting, insurance, turn actions
		// or the committed-wager view, exactly as the round allows.
		commands = menu.Menu.Commands
	} else {
		commands = blackjackHintsIdle()
	}
	return withTableHints(commands, t.wagerRows(name))
}

func (t *baccaratTable) wagers(name string) []WagerRow { return t.wagerRows() }
func (t *baccaratTable) hints(name string) []MenuCommand {
	if t.players.get(name) == nil {
		return nil
	}
	return withTableHints(baccaratHintCommands(t, name), t.wagerRows())
}

// baccaratHintCommands mirrors menuEvent's branches without re-deriving the
// menu view: a committed wager never advertises another bet.
func baccaratHintCommands(t *baccaratTable, name string) []MenuCommand {
	p := t.players.get(name)
	if p != nil && p.HasBet {
		return []MenuCommand{
			{Command: "unbet", Desc: "Take back all your wagers before the round"},
			{Command: "stop", Desc: "Leave; during a round, leave afterward"},
			{Command: "table", Desc: "Check the table"},
		}
	}
	commands := []MenuCommand{}
	if p != nil && p.hasLastBet() {
		commands = append(commands, MenuCommand{Command: "bet", Desc: "Repeat your last bets"})
	}
	if p != nil && len(p.sides) > 0 {
		commands = append(commands, MenuCommand{Command: "unbet", Desc: "Take back your side bets"})
	}
	return append(commands,
		MenuCommand{Command: fmt.Sprintf("bet %d banker", t.Config.MinBet)},
		MenuCommand{Command: "bet <amount> on <bet>"},
		MenuCommand{Command: "stop", Desc: "Leave; during a round, leave afterward"},
		MenuCommand{Command: "table", Desc: "Check the table"},
	)
}