package game import ( "os" "path/filepath" "strings" "testing" "thehouseoficarus/internal/casino" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" "thehouseoficarus/internal/world" ) func TestLookBaccaratFixtureWithoutScenery(t *testing.T) { dir := t.TempDir() if err := os.MkdirAll(filepath.Join(dir, "rooms"), 0755); err != nil { t.Fatal(err) } room := "name: Anywhere\ncasino_tables:\n- id: test\n game: baccarat\n baccarat:\n variant: ez_baccarat\n decks: 6\n dragon_7: true\n" if err := os.WriteFile(filepath.Join(dir, "rooms", "1.yaml"), []byte(room), 0644); err != nil { t.Fatal(err) } g := &Game{Deps: Deps{World: world.New(dir)}, Casino: casino.NewManager(1)} conn := &casinoTestConn{} sess := &net.Session{Player: player.New("alice"), Conn: conn} sess.Player.RoomID = 1 for _, target := range []string{"baccarat", "baccarat table", "table", "test", "test table"} { conn.data = nil g.doLookTarget(sess, target) text := plainRoulette(string(conn.data)) for _, want := range []string{"EZ BACCARAT — NO COMMISSION", "DECKS", "6", "DRAGON 7", "40:1", "PANDA 8", "NOT OFFERED"} { if !strings.Contains(text, want) { t.Fatalf("look %s missing %q: %s", target, want, text) } } } if g.lookCasinoTable(sess, "other", casino.GameBaccarat) { t.Fatal("matched unrelated target") } } func TestCasinoFloorBaccaratProfiles(t *testing.T) { g := &Game{Deps: Deps{World: world.New("../../data")}, Casino: casino.NewManager(1)} cases := []struct { room int variant string decks int tie float64 spot string }{ {6127, casino.BaccaratCommission, 8, 8, "player_pair"}, {6128, casino.BaccaratSuper6, 6, 9, "super_6"}, {6129, casino.BaccaratEZ, 8, 8, "dragon_7"}, } for _, tc := range cases { table, ok := g.casinoTable(tc.room, "baccarat") if !ok { t.Fatalf("room %d: table unavailable", tc.room) } cfg := table.Config if cfg.Baccarat.Variant != tc.variant || cfg.Baccarat.Decks != tc.decks || cfg.Baccarat.TiePayout != tc.tie { t.Fatalf("room %d: %+v", tc.room, cfg.Baccarat) } if err := cfg.Validate(); err != nil { t.Fatal(err) } events := g.Casino.Join(tc.room, cfg, "alice") found := false for _, e := range events { if view, ok := e.Snapshot.(*casino.BaccaratRulesView); ok { found = true art := renderBaccaratRulesFelt(view.Config, "none", true) if !strings.Contains(art, "DRAWING — AUTOMATIC PUNTO BANCO") { t.Fatalf("room %d: rules felt incomplete", tc.room) } } } if !found { t.Fatalf("room %d: join missing rules felt", tc.room) } if !strings.Contains(cfg.BaccaratRulesText(), tc.spot+"): Enabled") { t.Fatalf("room %d: missing optional bet", tc.room) } // Each fixture gets a fresh manager so participation ownership does not // prevent the same test player from joining the next table. g.Casino = casino.NewManager(1) } }