package game import ( "testing" "thehouseoficarus/internal/behavior" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" "thehouseoficarus/internal/world" ) func TestDiscoveredExitFlagKey(t *testing.T) { key := discoveredExitFlag(2001, world.North) if key != "hidden_exit_2001_north" { t.Errorf("unexpected flag key: %q", key) } key = discoveredExitFlag(100, world.Down) if key != "hidden_exit_100_down" { t.Errorf("unexpected flag key: %q", key) } } func TestExitDiscoveredUndiscovered(t *testing.T) { p := &player.Player{} if g := (&Game{}).exitDiscovered(p, 42, world.East); g { t.Error("expected undiscovered to be false") } } func TestExitDiscoveredAfterMark(t *testing.T) { g := &Game{Flags: NewFlagStore()} p := &player.Player{} roomID := 42 dir := world.East flagKey := discoveredExitFlag(roomID, dir) if g.exitDiscovered(p, roomID, dir) { t.Error("should not be discovered before marking") } g.markExitDiscovered(p, roomID, dir) if !g.exitDiscovered(p, roomID, dir) { t.Error("should be discovered after marking") } if getPlayerFlagInt(p, flagKey) == 0 { t.Error("flag should be set after marking") } } func TestExitDiscoveredGodMode(t *testing.T) { p := &player.Player{GodMode: true} if !(&Game{}).exitDiscovered(p, 99, world.South) { t.Error("god mode should always see exits as discovered") } } func TestExitDiscoveredDifferentRoom(t *testing.T) { g := &Game{Flags: NewFlagStore()} p := &player.Player{} g.markExitDiscovered(p, 10, world.North) if g.exitDiscovered(p, 10, world.East) { t.Error("discovering north should not mark east as discovered") } if g.exitDiscovered(p, 20, world.North) { t.Error("discovering room 10 north should not mark room 20 north") } } func TestExitDisplayState(t *testing.T) { g := &Game{Flags: NewFlagStore()} const roomID = 7 dir := world.North // {player_flag: open} — passes when "open" is set, fails otherwise. openCond := &behavior.Condition{PlayerFlag: "open"} hiddenDiscoveredSess := sessWithFlags(map[string]any{discoveredExitFlag(roomID, dir): 1}) openSess := sessWithFlags(map[string]any{"open": true}) closedSess := sessWithFlags(map[string]any{}) godSess := sessWithFlags(map[string]any{}) assertDisp := func(name string, sess *net.Session, exit world.ExitDef, wantVisible, wantBlocked, wantTagHidden bool) { t.Helper() ed := g.exitDisplayState(sess, roomID, dir, exit) if ed.Visible != wantVisible || ed.Blocked != wantBlocked || ed.TagHidden != wantTagHidden { t.Errorf("%s: got {Visible:%v Blocked:%v TagHidden:%v}, want {Visible:%v Blocked:%v TagHidden:%v}", name, ed.Visible, ed.Blocked, ed.TagHidden, wantVisible, wantBlocked, wantTagHidden) } } // Plain open exit: visible, not blocked, not hidden. assertDisp("plain", openSess, world.ExitDef{Room: 1}, true, false, false) // Hidden + undiscovered: absent. assertDisp("hidden-undiscovered", closedSess, world.ExitDef{Room: 1, Hidden: true}, false, false, false) // Hidden + discovered: visible, tagged hidden, not blocked. assertDisp("hidden-discovered", hiddenDiscoveredSess, world.ExitDef{Room: 1, Hidden: true}, true, false, true) // Hidden + god: god discovers — visible, tagged hidden. godSess.Player.GodMode = true assertDisp("hidden-god", godSess, world.ExitDef{Room: 1, Hidden: true}, true, false, true) godSess.Player.GodMode = false // always_blocked (non-god): visible, blocked, condition ignored. assertDisp("always-blocked", closedSess, world.ExitDef{Room: 1, AlwaysBlocked: true}, true, true, false) // always_blocked + a PASSING condition still blocks (condition not evaluated). assertDisp("always-blocked-over-passing-cond", openSess, world.ExitDef{Room: 1, AlwaysBlocked: true, Condition: openCond}, true, true, false) // always_blocked + god: not blocked (god bypass). godSess.Player.GodMode = true assertDisp("always-blocked-god", godSess, world.ExitDef{Room: 1, AlwaysBlocked: true}, true, false, false) godSess.Player.GodMode = false // Condition failing (no always_blocked): blocked. assertDisp("cond-failing", closedSess, world.ExitDef{Room: 1, Condition: openCond}, true, true, false) // Condition passing: not blocked. assertDisp("cond-passing", openSess, world.ExitDef{Room: 1, Condition: openCond}, true, false, false) // Condition failing + god: not blocked (god bypass). godSess.Player.GodMode = true assertDisp("cond-failing-god", godSess, world.ExitDef{Room: 1, Condition: openCond}, true, false, false) godSess.Player.GodMode = false // nil session (background render): non-hidden visible & not blocked; // hidden absent (no player to have discovered it). assertDisp("nil-sess-plain", nil, world.ExitDef{Room: 1}, true, false, false) assertDisp("nil-sess-hidden", nil, world.ExitDef{Room: 1, Hidden: true}, false, false, false) }