From e27a12e4fe0c472e57579ebb47c926465e3e0c36 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 1 Jun 2026 21:49:47 +0200 Subject: [PATCH] fix(game): null-safe moved() + idempotent begin(); cover multi-step + go_to_room hint Co-Authored-By: Claude Sonnet 4.6 --- .../jeanluc/adventure/game/TutorialGuide.java | 8 +++++-- .../adventure/game/TutorialGuideTest.java | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/TutorialGuide.java b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/TutorialGuide.java index 2ac91aa..a96a2f7 100644 --- a/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/TutorialGuide.java +++ b/Semesterprojekt/src/main/java/thb/jeanluc/adventure/game/TutorialGuide.java @@ -22,6 +22,7 @@ public final class TutorialGuide { private final CommandRegistry registry; private int index; private boolean active; + private boolean begun; private Room roomAtStepStart; public TutorialGuide(Tutorial tutorial, CommandRegistry registry) { @@ -30,15 +31,17 @@ public final class TutorialGuide { this.active = !tutorial.isEmpty(); } + /** @return true while the walkthrough is still running. */ public boolean isActive() { return active; } /** Prints the intro and the first instruction (call once at loop start). */ public void begin(GameContext ctx) { - if (!active) { + if (!active || begun) { return; } + begun = true; if (tutorial.intro() != null && !tutorial.intro().isBlank()) { ctx.getIo().write(tutorial.intro()); } @@ -108,7 +111,8 @@ public final class TutorialGuide { } private boolean moved(GameContext ctx) { - return ctx.getPlayer().getCurrentRoom() != roomAtStepStart; + return roomAtStepStart != null + && ctx.getPlayer().getCurrentRoom() != roomAtStepStart; } private boolean sameCommand(String a, String b) { diff --git a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/TutorialGuideTest.java b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/TutorialGuideTest.java index 84b06f5..529f0e7 100644 --- a/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/TutorialGuideTest.java +++ b/Semesterprojekt/src/test/java/thb/jeanluc/adventure/game/TutorialGuideTest.java @@ -140,4 +140,27 @@ class TutorialGuideTest { TutorialGuide g = new TutorialGuide(Tutorial.none(), registry()); assertThat(g.isActive()).isFalse(); } + + @Test + void advancingPrintsTheNextInstruction() { + GameContext ctx = ctx(); + Tutorial t = new Tutorial("I", + List.of(step("do look", "look", 0), step("do take", "take", 1)), "TIPS"); + TutorialGuide g = new TutorialGuide(t, registry()); + g.begin(ctx); + g.onCommand(ctx, parse("look")); + assertThat(out(ctx)).contains("OK:look").contains("do take"); + assertThat(g.isActive()).isTrue(); + } + + @Test + void goToRoomWithoutMovingGivesHint() { + GameContext ctx = ctx(); + Tutorial t = new Tutorial("I", List.of(step("travel", "go_to_room", 0)), "TIPS"); + TutorialGuide g = new TutorialGuide(t, registry()); + g.begin(ctx); + g.onCommand(ctx, parse("go kitchen")); // non-direction arg but no room change + assertThat(out(ctx)).contains("HINT:go_to_room"); + assertThat(g.isActive()).isTrue(); + } }