All checks were successful
release / build-release (push) Successful in 1m40s
- sim.Fog: avslöjar tre gångsteg från spelaren plus gränsande väggar (ser längs gången, inte genom väggen); riktmärken (perronger, start, spärrar) syns alltid; Explored ger utforskad andel; nollställs per omgång - game/minimap: 1–3 px per ruta i det hörn som varken täcker inforutan eller spelaren, perrong vit när tåget är inne, spelaren blinkar, följarna i sina toner, avgångslista per spår (● inne / ○ kommer); M döljer/visar - resultatskärmen visar utforskad andel och antal försörjda; layout justerad - docs/README/wiki uppdaterade Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
package sim
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/level"
|
|
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/rng"
|
|
)
|
|
|
|
const fogSample = `{
|
|
"id": "fog", "name": {"sv": "Fog"}, "difficulty": 1, "destination": {"sv": "x"},
|
|
"grid": [
|
|
"#########",
|
|
"#S......#",
|
|
"#.#####.#",
|
|
"#.#...#.#",
|
|
"#.#.#.#.#",
|
|
"#.#.#P#.#",
|
|
"#.#.###.#",
|
|
"#.......#",
|
|
"#########"
|
|
],
|
|
"trains": [{"platform": "P", "track": "1", "line": {"en": "A"}, "destination": {"en": "B"}, "correct": true}]
|
|
}`
|
|
|
|
func TestFogRevealsAlongCorridorsNotThroughWalls(t *testing.T) {
|
|
l, err := level.Parse([]byte(fogSample))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f := NewFog(l, 3)
|
|
f.Reveal(l, pt(1, 1))
|
|
for _, p := range []level.Point{pt(1, 1), pt(4, 1), pt(1, 4), pt(2, 1)} {
|
|
if !f.Seen(p) {
|
|
t.Errorf("%v inom 3 steg ska vara sedd", p)
|
|
}
|
|
}
|
|
// (2,2) är vägg bredvid gången -> sedd; (3,3) är golv men 2 steg bort fågelvägen
|
|
// och mycket längre gångvägen -> inte sedd.
|
|
if !f.Seen(pt(2, 2)) {
|
|
t.Error("väggen vid gången ska synas")
|
|
}
|
|
if f.Seen(pt(3, 3)) || f.Seen(pt(5, 1)) || f.Seen(pt(1, 5)) {
|
|
t.Errorf("för långt bort ska inte vara sett: (3,3)=%v (5,1)=%v (1,5)=%v", f.Seen(pt(3, 3)), f.Seen(pt(5, 1)), f.Seen(pt(1, 5)))
|
|
}
|
|
if f.Seen(pt(-1, 0)) || f.Seen(pt(99, 99)) {
|
|
t.Error("utanför kartan är aldrig sett")
|
|
}
|
|
}
|
|
|
|
func TestLandmarksAlwaysVisible(t *testing.T) {
|
|
l, _ := level.Parse([]byte(fogSample))
|
|
f := NewFog(l, FogRadius)
|
|
if f.Count() != 0 {
|
|
t.Fatal("tom dimma från start")
|
|
}
|
|
if !f.Visible(l, pt(5, 5)) || !f.Visible(l, pt(1, 1)) {
|
|
t.Fatal("perrong och start ska alltid synas")
|
|
}
|
|
if f.Visible(l, pt(7, 7)) {
|
|
t.Fatal("vanligt golv långt bort ska vara dolt")
|
|
}
|
|
if Landmark(l, pt(7, 7)) || !Landmark(l, pt(5, 5)) {
|
|
t.Fatal("Landmark")
|
|
}
|
|
}
|
|
|
|
func TestFogGrowsWithMovementAndResetsPerRun(t *testing.T) {
|
|
l := loadLevel(t, "001-flygplatsen")
|
|
r := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
|
start := r.Fog.Count()
|
|
if start == 0 || !r.Fog.Seen(l.SpawnPoint()) {
|
|
t.Fatal("starten ska vara avslöjad direkt")
|
|
}
|
|
e0 := r.Fog.Explored(l)
|
|
walk(t, r, l.Path(r.Player.Tile, l.Find(level.Sign)[1], r.CanEnter))
|
|
if r.Fog.Count() <= start || r.Fog.Explored(l) <= e0 {
|
|
t.Fatalf("dimman ska lätta när man går: %d -> %d", start, r.Fog.Count())
|
|
}
|
|
if e := r.Fog.Explored(l); e <= 0 || e > 1 {
|
|
t.Fatalf("Explored=%.2f", e)
|
|
}
|
|
fresh := NewRun(l, RunOptions{Seed: rng.FromInt(1)})
|
|
if fresh.Fog.Count() != start {
|
|
t.Fatal("ny omgång = ny dimma")
|
|
}
|
|
// Gates är riktmärken men ändå inte "sedda" förrän man är där.
|
|
gate := l.Find(level.Gate)[0]
|
|
if fresh.Fog.Seen(gate) || !fresh.Fog.Visible(l, gate) {
|
|
t.Fatal("spärren syns som riktmärke utan att vara sedd")
|
|
}
|
|
}
|