feat(game): world-state engine (GameState, Condition/Effect, evaluator/applier)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package thb.jeanluc.adventure.game;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import thb.jeanluc.adventure.io.TestIO;
|
||||
import thb.jeanluc.adventure.model.Condition;
|
||||
import thb.jeanluc.adventure.model.Player;
|
||||
import thb.jeanluc.adventure.model.Room;
|
||||
import thb.jeanluc.adventure.model.item.PlainItem;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ConditionsTest {
|
||||
private GameContext ctx() {
|
||||
Player p = new Player(new Room("k", "K", "d"), 0);
|
||||
return new GameContext(null, p, new TestIO());
|
||||
}
|
||||
|
||||
@Test
|
||||
void flagAndNotFlag() {
|
||||
GameContext ctx = ctx();
|
||||
ctx.getState().set("power_on");
|
||||
assertThat(Conditions.holds(new Condition(Condition.Type.FLAG, "power_on"), ctx)).isTrue();
|
||||
assertThat(Conditions.holds(new Condition(Condition.Type.NOT_FLAG, "power_on"), ctx)).isFalse();
|
||||
assertThat(Conditions.holds(new Condition(Condition.Type.NOT_FLAG, "x"), ctx)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasItem() {
|
||||
GameContext ctx = ctx();
|
||||
ctx.getPlayer().addItem(PlainItem.builder().id("lamp").name("Lamp").description("d").build());
|
||||
assertThat(Conditions.holds(new Condition(Condition.Type.HAS_ITEM, "lamp"), ctx)).isTrue();
|
||||
assertThat(Conditions.holds(new Condition(Condition.Type.HAS_ITEM, "key"), ctx)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void allRequiresEveryConditionAndEmptyIsTrue() {
|
||||
GameContext ctx = ctx();
|
||||
ctx.getState().set("a");
|
||||
assertThat(Conditions.all(List.of(), ctx)).isTrue();
|
||||
assertThat(Conditions.all(List.of(new Condition(Condition.Type.FLAG, "a")), ctx)).isTrue();
|
||||
assertThat(Conditions.all(List.of(
|
||||
new Condition(Condition.Type.FLAG, "a"),
|
||||
new Condition(Condition.Type.FLAG, "b")), ctx)).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package thb.jeanluc.adventure.game;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import thb.jeanluc.adventure.io.TestIO;
|
||||
import thb.jeanluc.adventure.model.Effect;
|
||||
import thb.jeanluc.adventure.model.Player;
|
||||
import thb.jeanluc.adventure.model.Room;
|
||||
import thb.jeanluc.adventure.model.World;
|
||||
import thb.jeanluc.adventure.model.item.Item;
|
||||
import thb.jeanluc.adventure.model.item.PlainItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class EffectsTest {
|
||||
private GameContext ctx(Map<String, Item> items) {
|
||||
Player p = new Player(new Room("k", "K", "d"), 0);
|
||||
World w = new World(Map.of(), items, Map.of(), "t", "w");
|
||||
return new GameContext(w, p, new TestIO());
|
||||
}
|
||||
|
||||
@Test
|
||||
void setAndClearFlag() {
|
||||
GameContext ctx = ctx(Map.of());
|
||||
Effects.applyAll(List.of(new Effect(Effect.Type.SET_FLAG, "power_on")), ctx);
|
||||
assertThat(ctx.getState().isSet("power_on")).isTrue();
|
||||
Effects.apply(new Effect(Effect.Type.CLEAR_FLAG, "power_on"), ctx);
|
||||
assertThat(ctx.getState().isSet("power_on")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void giveAndRemoveItem() {
|
||||
Item key = PlainItem.builder().id("key").name("Key").description("d").build();
|
||||
GameContext ctx = ctx(Map.of("key", key));
|
||||
Effects.apply(new Effect(Effect.Type.GIVE_ITEM, "key"), ctx);
|
||||
assertThat(ctx.getPlayer().hasItem("key")).isTrue();
|
||||
Effects.apply(new Effect(Effect.Type.REMOVE_ITEM, "key"), ctx);
|
||||
assertThat(ctx.getPlayer().hasItem("key")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void giveUnknownItemIsTolerated() {
|
||||
GameContext ctx = ctx(Map.of());
|
||||
Effects.apply(new Effect(Effect.Type.GIVE_ITEM, "ghost"), ctx);
|
||||
assertThat(ctx.getPlayer().hasItem("ghost")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sayWritesToIo() {
|
||||
GameContext ctx = ctx(Map.of());
|
||||
Effects.apply(new Effect(Effect.Type.SAY, "boo"), ctx);
|
||||
assertThat(((TestIO) ctx.getIo()).allOutput()).contains("boo");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package thb.jeanluc.adventure.game;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GameStateTest {
|
||||
@Test
|
||||
void setIsSetClear() {
|
||||
GameState s = new GameState();
|
||||
assertThat(s.isSet("power_on")).isFalse();
|
||||
s.set("power_on");
|
||||
assertThat(s.isSet("power_on")).isTrue();
|
||||
s.clear("power_on");
|
||||
assertThat(s.isSet("power_on")).isFalse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user