aboutsummaryrefslogtreecommitdiff
path: root/internal/game/casino_edge_list_test.go
blob: 902d178dbcf6e1b06a5d565143d17a091fcc3da3 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package game

import (
	"strings"
	"testing"

	"thehouseoficarus/internal/item"
	"thehouseoficarus/internal/player"
)

func TestEdgeListAllTableGames(t *testing.T) {
	for _, game := range []string{"blackjack", "baccarat", "roulette", "craps", "paigow", "video_poker"} {
		t.Run(game, func(t *testing.T) {
			g, sess, conn := houseEdgeGame(t, "name: Casino\ncasino_tables:\n  - id: test\n    game: "+game+"\n")
			writeHouseEdgeManual(t, g, sess, 2)
			g.executePlay(sess, []string{game}, "play "+game)
			if strings.Contains(stripANSI(string(conn.data)), "RTP") {
				t.Fatal("readout on join")
			}
			conn.data = nil
			g.executeList(sess, nil, "list")
			text := stripANSI(string(conn.data))
			if !strings.Contains(text, "RTP") {
				t.Fatalf("no RTP column for %s: %s", game, text)
			}
			assertRTPColumn(t, text)
			sess.Player.Inventory = nil
			conn.data = nil
			g.executeList(sess, nil, "list")
			if strings.Contains(stripANSI(string(conn.data)), "RTP") {
				t.Fatal("readout after reference removed")
			}
		})
	}
}

// TestCrapsListEveryBetHasRTP: once a reference item is carried, every
// craps wager the list can name must resolve to a real percentage. An
// unknown target would render the dash, which is the bug this guards.
func TestCrapsListEveryBetHasRTP(t *testing.T) {
	for _, variant := range []string{"bank", "crapless", "new_york"} {
		t.Run(variant, func(t *testing.T) {
			room := "name: CR\ncasino_tables:\n  - id: cr\n    game: craps\n    craps:\n      variant: " + variant + "\n"
			g, sess, conn := houseEdgeGame(t, room)
			writeHouseEdgeManual(t, g, sess, 2)
			g.executePlay(sess, []string{"craps"}, "play craps")
			g.executeBet(sess, []string{"10", "pass"}, "bet 10 pass")
			conn.data = nil
			g.executeList(sess, nil, "list")
			if text := stripANSI(string(conn.data)); strings.Contains(text, "—") {
				t.Fatalf("%s come-out list left a bet without RTP:\n%s", variant, text)
			}
		})
	}
}

func TestEdgeListBlackjackActionsOmitRTP(t *testing.T) {
	g, sess, conn := houseEdgeGame(t, "name: BJ\ncasino_tables:\n  - id: bj\n    game: blackjack\n")
	writeHouseEdgeManual(t, g, sess, 2)
	g.executePlay(sess, []string{"bj"}, "play bj")
	table, _ := g.Casino.Participation(sess.Player.Name)
	for i := 0; i < 10 && len(table.Wagers(sess.Player.Name)) == 0; i++ {
		g.executeBet(sess, []string{"1"}, "bet 1")
	}
	rows := table.Wagers(sess.Player.Name)
	if len(rows) == 0 {
		t.Skip("no action rows this deal")
	}
	insurance := false
	for _, r := range rows {
		if r.Bet == "insurance" {
			insurance = true
		}
	}
	conn.data = nil
	g.executeList(sess, nil, "list")
	text := stripANSI(string(conn.data))
	if insurance {
		// Insurance is a real wager and carries an RTP.
		if !strings.Contains(text, "RTP") {
			t.Fatalf("insurance list lost its RTP:\n%s", text)
		}
		return
	}
	if strings.Contains(text, "RTP") {
		t.Fatalf("action-only list showed an RTP column:\n%s", text)
	}
}

func TestEdgeListRealInstruments(t *testing.T) {
	g, sess, conn := houseEdgeGame(t, roomRoulette)
	g.ItemStore = item.NewItemStore("../../data")
	sess.Player.Inventory = map[int]*player.InventorySlot{
		0: {ItemID: "house_edge_tile", Quantity: 1},
		1: {ItemID: "house_edge_computus", Quantity: 1},
	}
	g.executePlay(sess, []string{"roulette"}, "play roulette")
	conn.data = nil
	g.executeList(sess, nil, "list")
	text := stripANSI(string(conn.data))
	if strings.Count(text, "97.30%") != 12 {
		t.Fatalf("best instrument not used: %s", text)
	}
	sess.Player.Inventory[1].Quantity = 0
	conn.data = nil
	g.executeList(sess, nil, "list")
	text = stripANSI(string(conn.data))
	if strings.Count(text, "97%") != 12 {
		t.Fatalf("tile not used: %s", text)
	}
	sess.Player.Inventory[0].Quantity = 0
	conn.data = nil
	g.executeList(sess, nil, "list")
	if strings.Contains(stripANSI(string(conn.data)), "RTP") {
		t.Fatal("zero-quantity item activated")
	}
}