diff --git a/pom.xml b/pom.xml index 39b0f81..68e1f25 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,12 @@ 1.2.1 test + + org.jetbrains + annotations + 23.0.0 + compile + diff --git a/src/main/java/com/github/dtschust/zork/Zork.java b/src/main/java/com/github/dtschust/zork/Zork.java index 35f3c40..f9ea8ff 100644 --- a/src/main/java/com/github/dtschust/zork/Zork.java +++ b/src/main/java/com/github/dtschust/zork/Zork.java @@ -11,11 +11,14 @@ import com.github.dtschust.zork.repl.ActionDispatcher; import com.github.dtschust.zork.types.ZorkContainer; import com.github.dtschust.zork.types.ZorkObject; +import java.util.Iterator; import java.util.Scanner; +import static com.github.dtschust.zork.Zork.Type.*; /* And away we go*/ public class Zork { + public enum Type {ROOM, ITEM, CONTAINER, CREATURE} public String userInput; public ZorkGame game; @@ -85,7 +88,7 @@ public class Zork { private boolean doTriggersContainersInRoom() { boolean skip = false; for (String key : game.getCurrentRoom().container) { - skip = skip || doZorkTriggers(game.get("container", key)); + skip = skip || doZorkTriggers(game.get(CONTAINER, key)); } return skip; } @@ -93,9 +96,9 @@ public class Zork { private boolean doTriggersItemsInContainersInRoom() { boolean skip = false; for (String key : game.getCurrentRoom().container) { - ZorkContainer tempContainer = (ZorkContainer) game.get("container", key); + ZorkContainer tempContainer = (ZorkContainer) game.get(CONTAINER, key); for (String key2 : tempContainer.item) { - skip = skip || doZorkTriggers(game.get("item", key2)); + skip = skip || doZorkTriggers(game.get(ITEM, key2)); } } return skip; @@ -104,7 +107,7 @@ public class Zork { private boolean doTriggersItemsInRoom() { boolean skip = false; for (String key : game.getCurrentRoom().item) { - skip = skip || doZorkTriggers(game.get("item", key)); + skip = skip || doZorkTriggers(game.get(ITEM, key)); } return skip; } @@ -112,7 +115,7 @@ public class Zork { private boolean doTriggersItemsInInventory() { boolean skip = false; for (String key : game.inventory) { - skip = skip || doZorkTriggers(game.get("item", key)); + skip = skip || doZorkTriggers(game.get(ITEM, key)); } return skip; } @@ -120,7 +123,7 @@ public class Zork { private boolean doTriggersCreaturesInRoom() { boolean skip = false; for (String key : game.getCurrentRoom().creature) { - skip = skip || doZorkTriggers(game.get("creature", key)); + skip = skip || doZorkTriggers(game.get(CREATURE, key)); } return skip; } @@ -132,8 +135,9 @@ public class Zork { private boolean doZorkTriggers(ZorkObject zorkObject) { boolean skip = false; - for (int x = zorkObject.trigger.size() - 1; x >= 0; x--) { - ZorkTrigger tempTrigger = zorkObject.trigger.get(x); + Iterator iterator = zorkObject.trigger.iterator(); + while (iterator.hasNext()) { + ZorkTrigger tempTrigger = iterator.next(); if (tempTrigger.evaluate(this)) { for (String print : tempTrigger.print) { System.out.println(print); @@ -144,7 +148,7 @@ public class Zork { } skip = skip || tempTrigger.hasCommand(); if (tempTrigger.type.equals("single")) { - zorkObject.trigger.remove(x); + iterator.remove(); } } } diff --git a/src/main/java/com/github/dtschust/zork/ZorkConditionHas.java b/src/main/java/com/github/dtschust/zork/ZorkConditionHas.java index 5fca062..7afe584 100644 --- a/src/main/java/com/github/dtschust/zork/ZorkConditionHas.java +++ b/src/main/java/com/github/dtschust/zork/ZorkConditionHas.java @@ -4,6 +4,8 @@ import com.github.dtschust.zork.parser.ZorkGame; import com.github.dtschust.zork.types.ZorkContainer; import com.github.dtschust.zork.types.ZorkRoom; +import static com.github.dtschust.zork.Zork.Type.*; + /* Has conditions*/ public class ZorkConditionHas extends ZorkCondition { @@ -23,13 +25,13 @@ public class ZorkConditionHas extends ZorkCondition { return evaluateCondition(game.inventory.contains(object)); } else { /* is it a room?*/ - ZorkRoom roomObject = (ZorkRoom) game.get("room", owner); + ZorkRoom roomObject = (ZorkRoom) game.get(ROOM, owner); if (roomObject != null) { return evaluateCondition(roomObject.item.contains(object)); } /* is it a container?*/ else { - ZorkContainer containerObject = (ZorkContainer) game.get("container", owner); + ZorkContainer containerObject = (ZorkContainer) game.get(CONTAINER, owner); if (containerObject != null) { return evaluateCondition(containerObject.containsItem(object)); } diff --git a/src/main/java/com/github/dtschust/zork/ZorkConditionStatus.java b/src/main/java/com/github/dtschust/zork/ZorkConditionStatus.java index 9553286..92d43db 100644 --- a/src/main/java/com/github/dtschust/zork/ZorkConditionStatus.java +++ b/src/main/java/com/github/dtschust/zork/ZorkConditionStatus.java @@ -14,7 +14,7 @@ public class ZorkConditionStatus extends ZorkCondition { @Override public boolean evaluate(ZorkGame game) { - ZorkObject tested = game.getListThroughLookup(object).get(object); + ZorkObject tested = game.getListThroughLookup(ZorkObject.class, object).get(object); return tested != null && tested.isStatusEqualTo(status); } } diff --git a/src/main/java/com/github/dtschust/zork/parser/ZorkGame.java b/src/main/java/com/github/dtschust/zork/parser/ZorkGame.java index 37807d4..c5a3988 100644 --- a/src/main/java/com/github/dtschust/zork/parser/ZorkGame.java +++ b/src/main/java/com/github/dtschust/zork/parser/ZorkGame.java @@ -1,5 +1,6 @@ package com.github.dtschust.zork.parser; +import com.github.dtschust.zork.Zork.Type; import com.github.dtschust.zork.types.*; import java.util.HashMap; @@ -15,7 +16,7 @@ public class ZorkGame { protected ZorkMap items = new ZorkMap<>(); protected ZorkMap containers = new ZorkMap<>(); protected ZorkMap creatures = new ZorkMap<>(); - protected HashMap objectLookup = new HashMap<>(); + protected HashMap objectLookup = new HashMap<>(); public ZorkRoom getCurrentRoom() { return rooms.get(currentRoom); @@ -38,58 +39,59 @@ public class ZorkGame { running = false; } - public String getTypeFromLookup(String object) { + public Type getTypeFromLookup(String object) { return objectLookup.get(object); } - public void addObjectThroughLookup(String name, ZorkObject object) { - putInMapGivenType(name, object); - objectLookup.put(object.name, name); + public void addObjectThroughLookup(Type type, ZorkObject object) { + putInMapGivenType(type, object); + objectLookup.put(object.name, type); } - public ZorkMap getListThroughLookup(String name) { - return getMapFromType(objectLookup.get(name)); + public ZorkMap getListThroughLookup(Class cast, String name) { + return values(cast, objectLookup.get(name)); } - public ZorkObject get(String type, String key) { + public ZorkMap values(Class cast, Type type) { + return (ZorkMap) getMapFromType(type); + } + + public ZorkObject get(Type type, String key) { return getMapFromType(type).get(key); } - public void put(String type, ZorkObject object) { + public void put(Type type, ZorkObject object) { putInMapGivenType(type, object); } - public Iterable values(String type) { - return getMapFromType(type).values(); - } - private ZorkMap getMapFromType(String type) { + private ZorkMap getMapFromType(Type type) { switch (type) { - case "room": + case ROOM: return rooms; - case "container": + case CONTAINER: return containers; - case "creature": + case CREATURE: return creatures; - case "item": + case ITEM: return items; default: throw new IllegalStateException("Unexpected value: " + type); } } - private void putInMapGivenType(String type, ZorkObject object) { + private void putInMapGivenType(Type type, ZorkObject object) { switch (type) { - case "room": + case ROOM: rooms.put((ZorkRoom) object); break; - case "container": + case CONTAINER: containers.put((ZorkContainer) object); break; - case "creature": + case CREATURE: creatures.put((ZorkCreature) object); break; - case "item": + case ITEM: items.put((ZorkItem) object); break; default: diff --git a/src/main/java/com/github/dtschust/zork/parser/ZorkReader.java b/src/main/java/com/github/dtschust/zork/parser/ZorkReader.java index b84931d..d6d7224 100644 --- a/src/main/java/com/github/dtschust/zork/parser/ZorkReader.java +++ b/src/main/java/com/github/dtschust/zork/parser/ZorkReader.java @@ -19,6 +19,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import java.nio.channels.NonReadableChannelException; + +import static com.github.dtschust.zork.Zork.Type.*; public class ZorkReader { @@ -72,14 +75,14 @@ public class ZorkReader { tempCreature.updateStatus(DOMUtils.getInnerTextByTagName(element, "status", "")); /* Put each creature in the creatures hashmap, the generic object hashmap, and the objectlookup hashmap*/ - data.addObjectThroughLookup("creature", tempCreature); + data.addObjectThroughLookup(CREATURE, tempCreature); } private static void addContainer(ZorkGame data, Element element) { final ZorkContainer tempCont = Parsers.container.parse(element); /* Put each container in the containers hashmap, the generic object hashmap, and the objectlookup hashmap*/ - data.addObjectThroughLookup("container", tempCont); + data.addObjectThroughLookup(CONTAINER, tempCont); } private static void addItem(ZorkGame data, Element element) { @@ -111,7 +114,7 @@ public class ZorkReader { tempItem.trigger.addAll(triggers); /* Put each item in the items hashmap, the generic objects hashmap, and store its type in object lookup */ - data.addObjectThroughLookup("item", tempItem); + data.addObjectThroughLookup(ITEM, tempItem); tempItem.updateStatus(DOMUtils.getInnerTextByTagName(element, "status", "")); } @@ -152,7 +155,7 @@ public class ZorkReader { tempRoom.border.put(borderDirection, borderName); } /*Add this room to the rooms hashmap, put it in the generic objects hashmap, and store it's type in the objectlookup hashmap*/ - data.addObjectThroughLookup("room", tempRoom); + data.addObjectThroughLookup(ROOM, tempRoom); } public ZorkGame build() { @@ -161,7 +164,7 @@ public class ZorkReader { File file = new File(filename); if (!file.canRead()) { System.out.println("Error opening file. Exiting..."); - throw new RuntimeException(); + throw new NonReadableChannelException(); } try { @@ -198,6 +201,8 @@ public class ZorkReader { case "creature": addCreature(data, element); break; + default: + throw new IllegalStateException("Unexpected value: " + tagType); } } @@ -206,7 +211,6 @@ public class ZorkReader { e.printStackTrace(); System.out.println("Invalid XML file, exiting"); System.exit(-1); - //e.printStackTrace(); } return data; diff --git a/src/main/java/com/github/dtschust/zork/repl/Action.java b/src/main/java/com/github/dtschust/zork/repl/Action.java index ee888e2..ed9fd1c 100644 --- a/src/main/java/com/github/dtschust/zork/repl/Action.java +++ b/src/main/java/com/github/dtschust/zork/repl/Action.java @@ -4,16 +4,16 @@ import com.github.dtschust.zork.parser.ZorkGame; import java.util.List; -public abstract class Action { - public abstract boolean matchesInput(final List arguments); +public interface Action { + boolean matchesInput(final List arguments); - public int getMinimumArgCount() { + default int getMinimumArgCount() { return 1; } - public int getMaximumArgCount() { + default int getMaximumArgCount() { return Integer.MAX_VALUE; } - public abstract void run(final ZorkGame game, final List arguments); + void run(final ZorkGame game, final List arguments); } diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/AddAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/AddAction.java index 616671f..a8f4a71 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/AddAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/AddAction.java @@ -1,16 +1,18 @@ package com.github.dtschust.zork.repl.actions; import com.github.dtschust.zork.parser.ZorkGame; +import com.github.dtschust.zork.Zork.Type; import com.github.dtschust.zork.repl.Action; -import com.github.dtschust.zork.types.ZorkContainer; -import com.github.dtschust.zork.types.ZorkRoom; +import com.github.dtschust.zork.types.HasSetOfCollectable; +import com.github.dtschust.zork.types.ZorkObject; import java.util.List; + /** * Add: figure out what type the destination is, then what type the object is. Then add object to destination if it makes sense */ -public class AddAction extends Action { +public class AddAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("Add"); @@ -26,33 +28,13 @@ public class AddAction extends Action { final String object = arguments.get(1); final String destination = arguments.get(3); - final String objectType = game.getTypeFromLookup(object); - final String destinationType = game.getTypeFromLookup(destination); - if (destinationType.equals("room")) { - ZorkRoom tempRoom = (ZorkRoom) game.get("room", destination); - switch (objectType) { - case "item": - tempRoom.item.add(object); - break; - case "creature": - tempRoom.creature.add(object); - break; - case "container": - tempRoom.container.add(object); - break; - default: - System.out.println("Error"); - break; - } - game.put("room", tempRoom); - } else if (destinationType.equals("container")) { - final ZorkContainer tempContainer = (ZorkContainer) game.get("container", destination); - if (objectType.equals("item")) - tempContainer.item.add(object); - else - System.out.println("Error"); - game.put("container", tempContainer); - } else { + try { + Type destType = game.getTypeFromLookup(destination); + Type objType = game.getTypeFromLookup(object); + ZorkObject tempObject = game.get(destType, destination); + ((HasSetOfCollectable) tempObject).getSetFromType(objType).add(object); + game.put(destType, tempObject); + } catch (Exception e) { System.out.println("Error"); } } diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/AttackAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/AttackAction.java index 4d8a535..faa9663 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/AttackAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/AttackAction.java @@ -6,10 +6,12 @@ import com.github.dtschust.zork.types.ZorkCreature; import java.util.List; +import static com.github.dtschust.zork.Zork.Type.CREATURE; + /** * Attempt an attack, do you feel lucky? */ -public class AttackAction extends Action { +public class AttackAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("attack"); @@ -26,13 +28,11 @@ public class AttackAction extends Action { final String weapon = arguments.get(3); if (game.getCurrentRoom().creature.contains(tempString)) { - ZorkCreature tempCreature = (ZorkCreature) game.get("creature", tempString); - if (tempCreature != null && game.inventory.contains(weapon)) { - if (tempCreature.isAttackSuccessful(game, weapon)) { - System.out.println("You assault the " + tempString + " with the " + weapon + "."); - tempCreature.printAndExecuteActions(game); - return; - } + ZorkCreature tempCreature = (ZorkCreature) game.get(CREATURE, tempString); + if (tempCreature != null && game.inventory.contains(weapon) && tempCreature.isAttackSuccessful(game, weapon)) { + System.out.println("You assault the " + tempString + " with the " + weapon + "."); + tempCreature.printAndExecuteActions(game); + return; } } diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/DeleteAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/DeleteAction.java index 60530f6..6ee5b18 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/DeleteAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/DeleteAction.java @@ -1,16 +1,21 @@ package com.github.dtschust.zork.repl.actions; +import com.github.dtschust.zork.Zork.Type; import com.github.dtschust.zork.parser.ZorkGame; import com.github.dtschust.zork.repl.Action; -import com.github.dtschust.zork.types.ZorkContainer; +import com.github.dtschust.zork.types.HasSetOfCollectable; +import com.github.dtschust.zork.types.ZorkObject; import com.github.dtschust.zork.types.ZorkRoom; import java.util.List; +import java.util.Set; + +import static com.github.dtschust.zork.Zork.Type.*; /** * Delete: figure out what object it is and delete it accordingly. Rooms are especially tricky */ -public class DeleteAction extends Action { +public class DeleteAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("Delete"); @@ -25,48 +30,37 @@ public class DeleteAction extends Action { public void run(ZorkGame game, List arguments) { final String object = arguments.get(1); - String objectType = game.getTypeFromLookup(object); - switch (objectType) { - case "room": - for (ZorkRoom tempRoom : (Iterable) game.values("room")) { + switch (game.getTypeFromLookup(object)) { + case ROOM: + for (ZorkRoom tempRoom :game.values(ZorkRoom.class, ROOM)) { for (String key : tempRoom.border.keySet()) { if (tempRoom.border.get(key).equals(object)) { tempRoom.border.remove(key); } } - game.put("room", tempRoom); + game.put(ROOM, tempRoom); } break; - case "item": - for (ZorkRoom tempRoom : (Iterable) game.values("room")) { - if (tempRoom.item.contains(object)) { - tempRoom.item.remove(object); - game.put("room", tempRoom); - } - } - for (ZorkContainer tempContainer : (Iterable) game.values("container")) { - if (tempContainer.item.contains(object)) { - tempContainer.item.remove(object); - game.put("container", tempContainer); - } - } + case ITEM: + deleteElementFromSpace(game, ROOM, ITEM, object); + deleteElementFromSpace(game, CONTAINER, ITEM, object); break; - case "container": - for (ZorkRoom tempRoom : (Iterable) game.values("room")) { - if (tempRoom.container.contains(object)) { - tempRoom.container.remove(object); - game.put("room", tempRoom); - } - } + case CONTAINER: + deleteElementFromSpace(game, ROOM, CONTAINER, object); break; - case "creature": - for (ZorkRoom tempRoom : (Iterable) game.values("room")) { - if (tempRoom.creature.contains(object)) { - tempRoom.creature.remove(object); - game.put("room", tempRoom); - } - } + case CREATURE: + deleteElementFromSpace(game, ROOM, CREATURE, object); break; } } + + private static void deleteElementFromSpace(ZorkGame game, Type space, Type element, String object) { + for (ZorkObject tempObject : game.values(ZorkObject.class, space)) { + Set set = ((HasSetOfCollectable) tempObject).getSetFromType(element); + if (set.contains(object)) { + set.remove(object); + game.put(space, tempObject); + } + } + } } diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/DropItemAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/DropItemAction.java index 5e0537d..509c9e0 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/DropItemAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/DropItemAction.java @@ -6,7 +6,9 @@ import com.github.dtschust.zork.types.ZorkRoom; import java.util.List; -public class DropItemAction extends Action { +import static com.github.dtschust.zork.Zork.Type.ROOM; + +public class DropItemAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("drop"); @@ -24,7 +26,7 @@ public class DropItemAction extends Action { if (game.inventory.contains(what)) { ZorkRoom tempRoom = game.getCurrentRoom(); tempRoom.item.add(what); - game.put("room", tempRoom); + game.put(ROOM, tempRoom); game.inventory.remove(what); System.out.println(what + " dropped."); } else { diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/GameOverAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/GameOverAction.java index fe407bc..25b07d2 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/GameOverAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/GameOverAction.java @@ -8,7 +8,7 @@ import java.util.List; /** * The "Game Over" action marks the end of the game. */ -public class GameOverAction extends Action { +public class GameOverAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("Game") && arguments.get(1).equals("Over"); diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/InventoryAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/InventoryAction.java index 7397de5..d9f4a32 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/InventoryAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/InventoryAction.java @@ -5,7 +5,7 @@ import com.github.dtschust.zork.repl.Action; import java.util.List; -public class InventoryAction extends Action { +public class InventoryAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("i"); diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/MoveAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/MoveAction.java index c0b8441..81753ad 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/MoveAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/MoveAction.java @@ -13,7 +13,7 @@ import static java.util.Map.entry; * Execute a user action or an action command from some element that is not one of the "Special Commands" * Movement */ -public class MoveAction extends Action { +public class MoveAction implements Action { private static final Map fullDirections = Map.ofEntries( entry("n", "north"), entry("s", "south"), diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/OpenAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/OpenAction.java index 1b1a175..9fc2b00 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/OpenAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/OpenAction.java @@ -6,7 +6,9 @@ import com.github.dtschust.zork.types.ZorkContainer; import java.util.List; -public class OpenAction extends Action { +import static com.github.dtschust.zork.Zork.Type.CONTAINER; + +public class OpenAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("open"); @@ -26,7 +28,7 @@ public class OpenAction extends Action { } else { ZorkContainer tempContainer; if (game.getCurrentRoom().container.contains(what)) { - tempContainer = (ZorkContainer) game.get("container", what); + tempContainer = (ZorkContainer) game.get(CONTAINER, what); tempContainer.open(); if (tempContainer.item.isEmpty()) { System.out.println(what + " is empty"); diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/PutAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/PutAction.java index b5bed9d..32060cb 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/PutAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/PutAction.java @@ -6,7 +6,9 @@ import com.github.dtschust.zork.types.ZorkContainer; import java.util.List; -public class PutAction extends Action { +import static com.github.dtschust.zork.Zork.Type.CONTAINER; + +public class PutAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("put"); @@ -23,7 +25,7 @@ public class PutAction extends Action { final String destination = arguments.get(3); if (game.getCurrentRoom().container.contains(destination)) { - ZorkContainer tempContainer = (ZorkContainer) game.get("container", destination); + ZorkContainer tempContainer = (ZorkContainer) game.get(CONTAINER, destination); if (tempContainer.isOpen() && game.inventory.contains(what)) { tempContainer.item.add(what); game.inventory.remove(what); diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/ReadAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/ReadAction.java index 6ae56be..0781734 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/ReadAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/ReadAction.java @@ -6,7 +6,9 @@ import com.github.dtschust.zork.types.ZorkItem; import java.util.List; -public class ReadAction extends Action { +import static com.github.dtschust.zork.Zork.Type.ITEM; + +public class ReadAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("read"); @@ -22,7 +24,7 @@ public class ReadAction extends Action { final String what = arguments.get(1); if (game.inventory.contains(what)) { - ZorkItem tempItem = (ZorkItem) game.get("item", what); + ZorkItem tempItem = (ZorkItem) game.get(ITEM, what); if (tempItem.writing != null && !tempItem.writing.isEmpty()) { System.out.println(tempItem.writing); } else { diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/TakeAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/TakeAction.java index 31cf3d5..b0c87b8 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/TakeAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/TakeAction.java @@ -7,7 +7,9 @@ import com.github.dtschust.zork.types.ZorkRoom; import java.util.List; -public class TakeAction extends Action { +import static com.github.dtschust.zork.Zork.Type.*; + +public class TakeAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("take"); @@ -26,16 +28,16 @@ public class TakeAction extends Action { game.inventory.add(tempString); ZorkRoom tempRoom = (game.getCurrentRoom()); tempRoom.item.remove(tempString); - game.put("room", tempRoom); + game.put(ROOM, tempRoom); System.out.println("Item " + tempString + " added to inventory."); } else { /* Search all containers in the current room for the item! */ for (String key : game.getCurrentRoom().container) { - ZorkContainer tempContainer = (ZorkContainer) game.get("container", key); + ZorkContainer tempContainer = (ZorkContainer) game.get(CONTAINER, key); if (tempContainer != null && tempContainer.isOpen() && tempContainer.item.contains(tempString)) { game.inventory.add(tempString); tempContainer.item.remove(tempString); - game.put("container", tempContainer); + game.put(CONTAINER, tempContainer); System.out.println("Item " + tempString + " added to inventory."); return; } diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/TurnOnAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/TurnOnAction.java index b1d2a3a..6f6af66 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/TurnOnAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/TurnOnAction.java @@ -6,10 +6,12 @@ import com.github.dtschust.zork.types.ZorkItem; import java.util.List; +import static com.github.dtschust.zork.Zork.Type.ITEM; + /** * Turn on an item */ -public class TurnOnAction extends Action { +public class TurnOnAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("turn") && arguments.get(1).equals("on"); @@ -25,7 +27,7 @@ public class TurnOnAction extends Action { final String what = arguments.get(2); if (game.inventory.contains(what)) { - ZorkItem tempItem = (ZorkItem) game.get("item", what); + ZorkItem tempItem = (ZorkItem) game.get(ITEM, what); System.out.println("You activate the " + what + "."); if (tempItem != null) { tempItem.printAndExecuteActions(game); diff --git a/src/main/java/com/github/dtschust/zork/repl/actions/UpdateAction.java b/src/main/java/com/github/dtschust/zork/repl/actions/UpdateAction.java index 0681aa0..63d367e 100644 --- a/src/main/java/com/github/dtschust/zork/repl/actions/UpdateAction.java +++ b/src/main/java/com/github/dtschust/zork/repl/actions/UpdateAction.java @@ -10,7 +10,7 @@ import java.util.List; /** * The "Update" command figures out what type of item it is, and then change its status */ -public class UpdateAction extends Action { +public class UpdateAction implements Action { @Override public boolean matchesInput(List arguments) { return arguments.get(0).equals("Update"); @@ -26,7 +26,7 @@ public class UpdateAction extends Action { final String object = arguments.get(1); final String newStatus = arguments.get(3); - ZorkMap collection = (ZorkMap) game.getListThroughLookup(object); + ZorkMap collection = game.getListThroughLookup(ZorkObject.class, object); ZorkObject tempObject = collection.get(object); tempObject.updateStatus(newStatus); collection.put(tempObject); diff --git a/src/main/java/com/github/dtschust/zork/types/HasSetOfCollectable.java b/src/main/java/com/github/dtschust/zork/types/HasSetOfCollectable.java new file mode 100644 index 0000000..85a8d85 --- /dev/null +++ b/src/main/java/com/github/dtschust/zork/types/HasSetOfCollectable.java @@ -0,0 +1,12 @@ +package com.github.dtschust.zork.types; + +import com.github.dtschust.zork.Zork; + +import java.util.Set; + +public interface HasSetOfCollectable { + + default Set getSetFromType(Zork.Type type) { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/github/dtschust/zork/types/ZorkContainer.java b/src/main/java/com/github/dtschust/zork/types/ZorkContainer.java index b4bf7f2..bafae0f 100644 --- a/src/main/java/com/github/dtschust/zork/types/ZorkContainer.java +++ b/src/main/java/com/github/dtschust/zork/types/ZorkContainer.java @@ -1,11 +1,14 @@ package com.github.dtschust.zork.types; +import com.github.dtschust.zork.Zork; import com.github.dtschust.zork.ZorkTrigger; import java.util.*; +import static com.github.dtschust.zork.Zork.Type.ITEM; + /* Container*/ -public class ZorkContainer extends ZorkObject { +public class ZorkContainer extends ZorkObject implements HasSetOfCollectable { public final Set item; private final List accepts; private boolean open; @@ -46,4 +49,11 @@ public class ZorkContainer extends ZorkObject { public void open() { open = true; } + + @Override + public Set getSetFromType(Zork.Type type) { + if (type.equals(ITEM)) + return item; + throw new IllegalStateException("Unexpected value: " + type); + } } diff --git a/src/main/java/com/github/dtschust/zork/types/ZorkMap.java b/src/main/java/com/github/dtschust/zork/types/ZorkMap.java index fbdcf4f..c310e1a 100644 --- a/src/main/java/com/github/dtschust/zork/types/ZorkMap.java +++ b/src/main/java/com/github/dtschust/zork/types/ZorkMap.java @@ -1,11 +1,17 @@ package com.github.dtschust.zork.types; import java.util.HashMap; +import java.util.Iterator; -public class ZorkMap extends HashMap { +public class ZorkMap extends HashMap implements Iterable { public T put(T object) { return put(object.name, object); } + + @Override + public Iterator iterator() { + return this.values().iterator(); + } } diff --git a/src/main/java/com/github/dtschust/zork/types/ZorkObject.java b/src/main/java/com/github/dtschust/zork/types/ZorkObject.java index 159f539..503414a 100644 --- a/src/main/java/com/github/dtschust/zork/types/ZorkObject.java +++ b/src/main/java/com/github/dtschust/zork/types/ZorkObject.java @@ -36,4 +36,5 @@ public abstract class ZorkObject { public boolean isStatusEqualTo(String status) { return this.status.equals(status); } + } diff --git a/src/main/java/com/github/dtschust/zork/types/ZorkRoom.java b/src/main/java/com/github/dtschust/zork/types/ZorkRoom.java index b577171..39d88e9 100644 --- a/src/main/java/com/github/dtschust/zork/types/ZorkRoom.java +++ b/src/main/java/com/github/dtschust/zork/types/ZorkRoom.java @@ -1,12 +1,14 @@ package com.github.dtschust.zork.types; +import com.github.dtschust.zork.Zork; + import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /* Room*/ -public class ZorkRoom extends ZorkObject { +public class ZorkRoom extends ZorkObject implements HasSetOfCollectable { public final String type; public final Map border = new HashMap<>(); public final Set container = new HashSet<>(); @@ -17,4 +19,18 @@ public class ZorkRoom extends ZorkObject { super(name, description); this.type = type; } + + @Override + public Set getSetFromType(Zork.Type type) { + switch (type) { + case CONTAINER: + return container; + case CREATURE: + return creature; + case ITEM: + return item; + default: + throw new IllegalStateException("Unexpected value: " + type); + } + } }