feat: state-dependent room descriptions (LookCommand resolution)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 21:52:57 +02:00
parent df4a46ae5b
commit c9c019cea1
2 changed files with 44 additions and 1 deletions

View File

@@ -1,8 +1,10 @@
package thb.jeanluc.adventure.command.impl;
import thb.jeanluc.adventure.command.Command;
import thb.jeanluc.adventure.game.Conditions;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.io.text.RoomView;
import thb.jeanluc.adventure.model.DescriptionState;
import thb.jeanluc.adventure.model.Direction;
import thb.jeanluc.adventure.model.Npc;
import thb.jeanluc.adventure.model.Room;
@@ -22,7 +24,14 @@ public class LookCommand implements Command {
List<String> items = room.getItems().values().stream().map(Item::getName).toList();
List<String> npcs = room.getNpcs().values().stream().map(Npc::getName).toList();
List<String> exits = room.getExits().keySet().stream().map(Direction::getLabel).toList();
ctx.getIo().showRoom(new RoomView(room.getName(), room.getDescription(), items, npcs, exits));
String description = room.getDescription();
for (DescriptionState ds : room.getDescriptionStates()) {
if (Conditions.all(ds.when(), ctx)) {
description = ds.text();
break;
}
}
ctx.getIo().showRoom(new RoomView(room.getName(), description, items, npcs, exits));
}
@Override

View File

@@ -0,0 +1,34 @@
package thb.jeanluc.adventure.command.impl;
import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.model.Condition;
import thb.jeanluc.adventure.model.DescriptionState;
import thb.jeanluc.adventure.model.Player;
import thb.jeanluc.adventure.model.Room;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class DescriptionStateTest {
@Test
void descriptionSwitchesWithFlag() {
Room cellar = new Room("cellar", "Cellar", "Pitch black down here.");
cellar.addDescriptionState(new DescriptionState(
List.of(new Condition(Condition.Type.FLAG, "power_on")),
"Lit now, a workbench stands against the wall."));
Player player = new Player(cellar, 0);
TestIO io = new TestIO();
GameContext ctx = new GameContext(null, player, io);
new LookCommand().execute(ctx, List.of());
assertThat(io.allOutput()).contains("Pitch black");
io.outputs().clear();
ctx.getState().set("power_on");
new LookCommand().execute(ctx, List.of());
assertThat(io.allOutput()).contains("workbench").doesNotContain("Pitch black");
}
}