Merge: suppress endings during the tutorial

This commit is contained in:
2026-06-01 22:09:06 +02:00
2 changed files with 37 additions and 0 deletions

View File

@@ -84,6 +84,11 @@ public class Game {
/** Ends the game if any ending's conditions are met, printing its screen. */
private void maybeEnd() {
// Don't end the game (win or lose) while the player is still in the tutorial —
// a pending ending fires once the walkthrough finishes or is skipped.
if (tutorialGuide != null && tutorialGuide.isActive()) {
return;
}
Ending e = EndingEngine.triggered(ctx);
if (e != null) {
ctx.getIo().print(EndingEngine.render(e, ctx, ctx.getSession().getTurn()));

View File

@@ -5,6 +5,8 @@ import thb.jeanluc.adventure.command.CommandParser;
import thb.jeanluc.adventure.command.CommandRegistry;
import thb.jeanluc.adventure.command.impl.LookCommand;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.model.Condition;
import thb.jeanluc.adventure.model.Ending;
import thb.jeanluc.adventure.model.Player;
import thb.jeanluc.adventure.model.Room;
import thb.jeanluc.adventure.model.Tutorial;
@@ -44,4 +46,34 @@ class GameTutorialTest {
assertThat(out).contains("STEP1-OK"); // first 'look' advanced step 1
assertThat(out).contains("Tutorial skipped"); // 'skip' ended it before step 2 finished
}
@Test
void endingsAreSuppressedWhileTutorialActiveAndFireAfter() {
Room kitchen = new Room("kitchen", "Kitchen", "d");
Ending fled = new Ending("fled", "Fled", false,
List.of(new Condition(Condition.Type.FLAG, "fled")), "ENDING-TEXT");
World w = new World(Map.of("kitchen", kitchen), Map.of(), Map.of(),
"t", "w", Map.of(), List.of(fled));
TestIO io = new TestIO();
io.enqueue("look"); // completes the 1-step tutorial; then EOF ends run()
GameContext ctx = new GameContext(new GameSession(w, new Player(kitchen, 0), "s"), io);
ctx.getState().set("fled"); // ending condition already met from the start
CommandRegistry registry = new CommandRegistry();
registry.register(new LookCommand(), "look", "l");
Tutorial t = new Tutorial("INTRO",
List.of(new TutorialStep("do look", "look", 0, "STEP1-OK", "hint")), "TIPS");
Game game = new Game(ctx, registry, new CommandParser());
game.setTutorialGuide(new TutorialGuide(t, registry));
game.run();
String out = io.allOutput();
// The 'look' was processed -> the pre-loop ending did NOT stop the game first.
assertThat(out).contains("STEP1-OK");
// After the tutorial finished, the ending fired.
assertThat(out).contains("ENDING-TEXT");
assertThat(out.indexOf("STEP1-OK")).isLessThan(out.indexOf("ENDING-TEXT"));
}
}