aboutsummaryrefslogtreecommitdiff
path: root/internal/game/craps_test.go
blob: 67124558a14571baac4a7be516a0a55b49f803c7 (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
package game

import (
	"strings"
	"testing"
	"thehouseoficarus/internal/casino"
	"thehouseoficarus/internal/color"
	"thehouseoficarus/internal/combat"
	"thehouseoficarus/internal/net"
	"thehouseoficarus/internal/player"
	"thehouseoficarus/internal/world"
)

func TestCrapsCommandsAndRendering(t *testing.T) {
	g := &Game{Casino: casino.NewManager(1), Combat: combat.NewTracker(), Deps: Deps{World: world.New(t.TempDir())}}
	cfg := casino.TableConfig{ID: "craps", Game: casino.GameCraps}
	g.Casino.Join(1, cfg, "alice")
	conn := &casinoTestConn{}
	sess := &net.Session{Player: player.New("alice"), Conn: conn}
	g.loggedInChars = map[string]*net.Session{"alice": sess}
	for _, args := range [][]string{{"12", "on", "place", "6"}, {"10", "on", "hop", "2", "3"}, {"10", "buy", "4"}, {"10", "on", "fire"}} {
		conn.data = nil
		g.executeBet(sess, args, "bet "+strings.Join(args, " "))
		if !strings.Contains(string(conn.data), "You don't have enough chips and credits") {
			t.Fatalf("%v: %s", args, conn.data)
		}
	}
	conn.data = nil
	g.executeTableStatus(sess, nil, "table")
	if !strings.Contains(string(conn.data), "PASS LINE") {
		t.Fatal(string(conn.data))
	}
	for _, cmd := range []string{"roll", "autoroll", "unbet"} {
		if _, ok := commandRegistry[cmd]; !ok {
			t.Fatal("missing", cmd)
		}
	}
	snap := &casino.CrapsSnapshot{Phase: "betting", Point: 6, Dice: [2]int{3, 4}, Queue: []string{"alice", "bob"}, Made: []int{4, 6}, Seen: []int{2, 4, 6}}
	if !g.seesCasinoDetails(sess, casino.Event{RoomID: 1, TableID: "craps", Snapshot: snap}) {
		t.Fatal("invisible board")
	}
	for _, mode := range []string{"none", "ansi", "xterm256"} {
		for _, unicode := range []bool{false, true} {
			art := renderCrapsSnapshot(snap, mode, unicode)
			plain := plainRoulette(art)
			for _, word := range []string{"PASS LINE", "DON'T COME", "FIELD", "FIRE", "SMALL", "Total: 7", "POINT 6"} {
				if !strings.Contains(plain, word) {
					t.Fatal("missing", word)
				}
			}
			for _, r := range plain {
				if !unicode && r > 127 {
					t.Fatalf("nonASCII %q", r)
				}
			}
			for _, line := range strings.Split(plain, "\n") {
				if color.VisibleLen(line) > 78 {
					t.Fatalf("too wide: %s", line)
				}
			}
			if mode == "none" && art != plain {
				t.Fatal("unexpected ANSI")
			}
			if mode != "none" && !strings.Contains(art, "\x1b[") {
				t.Fatal("missing felt color")
			}
		}
	}
	// Snapshots and nil/empty states render safely before the first roll.
	if renderCrapsSnapshot(nil, "none", false) != "" {
		t.Fatal("nil")
	}
	for a := 1; a <= 6; a++ {
		for b := 1; b <= 6; b++ {
			snap.Dice = [2]int{a, b}
			if !strings.Contains(renderCrapsSnapshot(snap, "none", false), "Total:") {
				t.Fatal(a, b)
			}
		}
	}
}