package sim import ( "testing" "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level" "gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/rng" ) func TestNPCsWanderStayOnFloorAndBlockPlayer(t *testing.T) { l := loadLevel(t, "005-ueno") if l.Crowd == 0 { t.Fatal("005 ska ha folk") } r := NewRun(l, RunOptions{Seed: rng.FromInt(3)}) if len(r.NPCs) != l.Crowd*NPCPerCrowd { t.Fatalf("npcs=%d, vill ha %d", len(r.NPCs), l.Crowd*NPCPerCrowd) } moved := 0 start := make([]level.Point, len(r.NPCs)) for i, n := range r.NPCs { start[i] = n.Mover.Tile } for i := 0; i < 60*20; i++ { r.Step(frame, None, false) for _, n := range r.NPCs { if !l.At(n.Mover.Tile).Passable() { t.Fatalf("NPC på vägg: %v", n.Mover.Tile) } } } for i := range start { // vandrarna ligger först; avstigande kan ha tillkommit efter dem if r.NPCs[i].Mover.Tile != start[i] { moved++ } } if moved == 0 { t.Fatal("ingen NPC rörde sig på 20 s") } // Spelaren kan inte gå in i en NPC. npc := r.NPCs[0] npc.Mover.Tile, npc.Mover.Target, npc.Pause = level.Point{X: 2, Y: 1}, level.Point{X: 2, Y: 1}, 1e9 if r.CanEnter(level.Point{X: 2, Y: 1}) { t.Fatal("rutan med en NPC är upptagen") } r.Step(frame, Right, false) if r.Player.Moving() || r.BumpedAt < 0 { t.Fatal("att gå in i någon stoppar en och noteras") } // Determinism. a := NewRun(l, RunOptions{Seed: rng.FromInt(4)}) b := NewRun(l, RunOptions{Seed: rng.FromInt(4)}) for i := 0; i < 60*5; i++ { a.Step(frame, None, false) b.Step(frame, None, false) } for i := range a.NPCs { if a.NPCs[i].Mover.Tile != b.NPCs[i].Mover.Tile { t.Fatal("folket ska vara seedat") } } } func TestAlightingNPCsSpawnAndLeave(t *testing.T) { l := loadLevel(t, "005-ueno") r := NewRun(l, RunOptions{Seed: rng.FromInt(5)}) r.Party.nextEventAt = 1e9 base := len(r.NPCs) // Spola fram tills första tåget har öppnat dörrarna. for i := 0; i < 60*60; i++ { r.Step(frame, None, false) if ph, _ := r.PlatformPhase(level.Platform); ph == level.Dwelling { break } } exits := 0 for _, n := range r.NPCs { if n.Kind == Exit { exits++ } } if exits != NPCAlightBase+l.Crowd { t.Fatalf("avstigande=%d, vill ha %d", exits, NPCAlightBase+l.Crowd) } // De går mot utgången och försvinner. for i := 0; i < 60*120 && len(r.NPCs) > base; i++ { r.Step(frame, None, false) } if len(r.NPCs) != base { t.Fatalf("avstigande ska ha lämnat stationen: %d kvar", len(r.NPCs)-base) } } func TestLanesSlowWrongSide(t *testing.T) { src := `{"id":"lanes","name":{"sv":"x"},"difficulty":1,"destination":{"sv":"x"}, "grid":["#######","#S<<= DefaultSpeed || !r.WrongLane { t.Fatalf("fel sida ska bromsa: speed=%.2f wrong=%v", r.Player.Speed, r.WrongLane) } for r.Player.Moving() { r.Step(frame, None, false) } r.Step(frame, Left, false) if r.Player.Speed != DefaultSpeed || r.WrongLane { t.Fatalf("rätt sida full fart: speed=%.2f wrong=%v", r.Player.Speed, r.WrongLane) } }