M2: tåg med tidtabell, spärrar med kort, skyltar, vinst/förlust
All checks were successful
release / build-release (push) Successful in 1m35s

- level: Schedule (ankomst/intervall/uppehåll) med Status(t), spårnummer,
  avgift, skylttexter per i-ruta, Path (BFS) och UngatedPlatforms – regeln
  att perronger bara nås via spärrar testas för alla banor
- sim.Run: klocka, tågkort (saldo dras vid spärr, tomt kort stoppas),
  ombordstigning med Enter när tåget är inne, vinst/förlust; headless
  bot-test klarar bana 001 och förlorar på fel tåg
- game: perronginfo (avgår om / nästa tåg om), skyltruta, nekad spärr,
  tågvagn som ritas när tåget är inne, inforutan flyttas upp när spelaren
  står nära nederkanten; resultat med spärrpassager och saldo
- bana 001 ombyggd så spärrarna är flaskhalsar; bana 002 omgenererad med
  spärrar runt perrongerna och skylttexter
- tools/shots räknar ut vägar med BFS; skriptkommandot waittrain
- docs/README/wiki uppdaterade med nya bilder

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 19:36:45 +02:00
parent 3c00c7f356
commit a5a660b32f
26 changed files with 1031 additions and 135 deletions

View File

@@ -1,9 +1,19 @@
{
"id": "001-flygplatsen",
"name": { "sv": "Flygplatsen", "en": "The Airport", "ja": "空港" },
"name": {
"sv": "Flygplatsen",
"en": "The Airport",
"ja": "空港"
},
"difficulty": 1,
"destination": { "ja": "新宿", "romaji": "Shinjuku", "sv": "Shinjuku", "en": "Shinjuku" },
"destination": {
"ja": "新宿",
"romaji": "Shinjuku",
"sv": "Shinjuku",
"en": "Shinjuku"
},
"timeLimitSec": 0,
"fareYen": 200,
"grid": [
"####################",
"#S.....#.....i.....#",
@@ -13,23 +23,71 @@
"#...#....#.....#.#.#",
"#.###.##.#####.#.#.#",
"#.....#T.......#...#",
"#.#####.#########.##",
"#######.#########.##",
"#....GG......i..GG.#",
"#..p.....##......P.#",
"#..p.############P.#",
"####################"
],
"trains": [
{
"platform": "P",
"line": { "ja": "成田エクスプレス", "romaji": "Narita Ekusupuresu", "en": "Narita Express" },
"destination": { "ja": "新宿", "romaji": "Shinjuku", "en": "Shinjuku" },
"correct": true
"line": {
"ja": "成田エクスプレス",
"romaji": "Narita Ekusupuresu",
"en": "Narita Express"
},
"destination": {
"ja": "新宿",
"romaji": "Shinjuku",
"en": "Shinjuku"
},
"correct": true,
"track": "2",
"schedule": {
"offsetSec": 0,
"intervalSec": 30,
"dwellSec": 12
}
},
{
"platform": "p",
"line": { "ja": "京成本線", "romaji": "Keisei Honsen", "en": "Keisei Main Line" },
"destination": { "ja": "京成上野", "romaji": "Keisei-Ueno", "en": "Keisei-Ueno" },
"correct": false
"line": {
"ja": "京成本線",
"romaji": "Keisei Honsen",
"en": "Keisei Main Line"
},
"destination": {
"ja": "京成上野",
"romaji": "Keisei-Ueno",
"en": "Keisei-Ueno"
},
"correct": false,
"track": "1",
"schedule": {
"offsetSec": 8,
"intervalSec": 30,
"dwellSec": 12
}
}
],
"signs": [
{
"x": 13,
"y": 1,
"text": {
"sv": "Till tågen: följ gången neråt. Spår 1 Keisei-linjen till vänster, spår 2 Narita Express till höger.",
"en": "To the trains: follow the corridor down. Track 1 Keisei Line to the left, track 2 Narita Express to the right.",
"ja": "のりば ↓ 1番線 京成線 ← 2番線 成田エクスプレス →"
}
},
{
"x": 13,
"y": 9,
"text": {
"sv": "Spärrar. <- Spår 1: Keisei-linjen mot Keisei-Ueno. -> Spår 2: Narita Express mot Shinjuku.",
"en": "Ticket gates. <- Track 1: Keisei Line for Keisei-Ueno. -> Track 2: Narita Express for Shinjuku.",
"ja": "改札 ← 1番線 京成線 京成上野方面 → 2番線 成田エクスプレス 新宿方面"
}
}
]
}

View File

@@ -6,6 +6,7 @@
"sv": "Shibuya"
},
"difficulty": 2,
"fareYen": 200,
"grid": [
"#################################",
"#S#..i..#.#...........#.........#",
@@ -24,9 +25,9 @@
"#.#.###.###.#.###.#.#.#######.#.#",
"#...#T#.#..i#.#.#...#.....#...#.#",
"#####.#.#.#.#.#.#####.#####.###.#",
"#.....#.#.#.#..i....#.......#G..#",
"#.#.#.#.#.#########.#########.#.#",
"#p..#...#.....................#P#",
"#.....#.#.#.#..i....#.......#...#",
"#G#.#.#.#.#########.#########.#G#",
"#pG.#...#.....................#P#",
"#################################"
],
"id": "002-shinjuku",
@@ -35,6 +36,35 @@
"ja": "新宿駅",
"sv": "Shinjuku station"
},
"signs": [
{
"text": {
"en": "Shinjuku Station. Track 14 Yamanote Line for Shibuya: far bottom right. Track 8 Chuo Line for Tokyo: far bottom left.",
"ja": "新宿駅 14番線 山手線 渋谷方面 → 南東 8番線 中央線 東京方面 → 南西",
"sv": "Shinjuku station. Spår 14 Yamanote-linjen mot Shibuya: längst ner till höger. Spår 8 Chuo-linjen mot Tokyo: längst ner till vänster."
},
"x": 5,
"y": 1
},
{
"text": {
"en": "\u003c- Track 8 Chuo Line (Tokyo) Track 14 Yamanote Line (Shibuya) -\u003e",
"ja": "← 8番線 中央線 東京方面 14番線 山手線 渋谷方面 →",
"sv": "\u003c- Spår 8 Chuo-linjen (Tokyo) Spår 14 Yamanote-linjen (Shibuya) -\u003e"
},
"x": 11,
"y": 15
},
{
"text": {
"en": "Track 14 Yamanote Line for Shibuya: the gate in the south-east corner.",
"ja": "14番線 山手線 渋谷方面 → 南東口改札",
"sv": "Spår 14 Yamanote-linjen mot Shibuya: spärren i sydöstra hörnet."
},
"x": 15,
"y": 17
}
],
"timeLimitSec": 0,
"trains": [
{
@@ -49,21 +79,33 @@
"ja": "山手線",
"romaji": "Yamanote-sen"
},
"platform": "P"
"platform": "P",
"schedule": {
"dwellSec": 8,
"intervalSec": 20,
"offsetSec": 3
},
"track": "14"
},
{
"correct": false,
"destination": {
"en": "Tokyo",
"ja": "東京",
"romaji": "Tōkyō"
"romaji": "Tokyo"
},
"line": {
"en": "Chūō Line",
"en": "Chuo Line",
"ja": "中央線",
"romaji": "Chūō-sen"
"romaji": "Chuo-sen"
},
"platform": "p"
"platform": "p",
"schedule": {
"dwellSec": 8,
"intervalSec": 25,
"offsetSec": 10
},
"track": "8"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 692 B

View File

@@ -20,5 +20,15 @@
"hud.steps": "Steps",
"hud.controls": "Esc: menu",
"level.wrong_train": "Wrong train!",
"result.hint": "R: replay Enter/Esc: menu"
"result.hint": "R: replay Enter/Esc: menu",
"hud.card": "Card",
"hud.track": "Track",
"hud.next_train_in": "Next train in",
"hud.departs_in": "Departs in",
"hud.board": "Enter: board",
"hud.gate_denied": "Gate: card has no balance!",
"hud.sign": "Sign",
"result.wrong_detail": "You went to %s instead of %s.",
"result.gates": "Gates",
"result.card": "Card left"
}

View File

@@ -20,5 +20,15 @@
"hud.steps": "Steg",
"hud.controls": "Esc: meny",
"level.wrong_train": "Fel tåg!",
"result.hint": "R: spela om Enter/Esc: meny"
"result.hint": "R: spela om Enter/Esc: meny",
"hud.card": "Kort",
"hud.track": "Spår",
"hud.next_train_in": "Nästa tåg om",
"hud.departs_in": "Avgår om",
"hud.board": "Enter: kliv på",
"hud.gate_denied": "Spärren: kortet saknar saldo!",
"hud.sign": "Skylt",
"result.wrong_detail": "Du åkte mot %s i stället för %s.",
"result.gates": "Spärrar",
"result.card": "Kort kvar"
}