/*Drew Schuster dtschust ECE462 */ package com.github.dtschust.zork; import com.github.dtschust.zork.parser.ZorkGame; import com.github.dtschust.zork.parser.ZorkReader; import java.util.Map; import java.util.Scanner; import static java.util.Map.entry; /* And away we go*/ public class Zork { public String userInput; public String currentRoom; public ZorkGame game; Scanner source = new Scanner(System.in); public Zork(String filename) { ZorkReader reader = new ZorkReader(filename); game = reader.build(); /*Phew, we're finally done with that ... let's get playing!!*/ /* Some temporary initialization variables*/ currentRoom = "Entrance"; boolean ended = false; /* Print out the first entrance description, starting the game!*/ System.out.println(game.Rooms.get(currentRoom).description); /* There is no stopping in Zork, until we're done!!*/ do { userInput = source.nextLine(); /*Now that we have the user command, check the input*/ if (!executeTriggers()) { /* If we haven't skipped, perform the user action*/ ended = executeAction(userInput); /* Clear the user input, and check the triggers again (various states have changed, gnomes need to be found!*/ userInput = ""; executeTriggers(); } } while (!ended); // single point of termination System.exit(0); } /* I love how basic java main functions are sometimes.*/ public static void main(String[] args) { if (args.length != 1) { System.out.println("Usage: java Zork [filename]"); return; } new Zork(args[0]); } public boolean executeAction(String input) { String[] action = input.split(" "); /* Update: figure out what type of item it is, and then change it's status*/ if (action[0].equals("Update")) { doActionUpdate(action[1], action[3]); } /*Game Over: pretty straight forward*/ else if (input.equals("Game Over")) { return doActionGameWon(); } /* Add: figure out what type the destination is, then what type the object is. Then add object to destination if it makes sense */ else if (action[0].equals("Add")) { doActionAdd(action[1], action[3]); } /* Delete: figure out what object it is and delete it accordingly. Rooms are especially tricky */ else if (action[0].equals("Delete")) { doActionDelete(action[1]); } /*If it's not a "Special Action", just treat it normally */ /* Execute a user action or an action command from some element that is not one of the "Special Commands"*/ /* Movement */ else if (action[0].length() == 1 && "nswe".contains(action[0])) { doActionMove(action[0]); } /* Inventory */ else if (action[0].equals("i")) { doActionInventory(); } /* Take */ else if (action[0].equals("take") && action.length > 1) { doActionTake(action[1]); } /* Open Exit (you should be so lucky)*/ else if (input.equals("open exit")) { return doActionOpenExit(); } /* Open a container */ else if (action[0].equals("open") && action.length > 1) { doActionOpenContainer(action[1]); } /* Read an object */ else if (action[0].equals("read") && action.length > 1) { doActionReadObject(action[1]); } /* Drop an item*/ else if (action[0].equals("drop") && action.length > 1) { doActionDropItem(action[1]); } /* Put an item somewhere */ else if (action[0].equals("put") && action.length >= 4) { doActionPutItem(action[1], action[3]); } /* Turn on an item*/ else if (input.startsWith("turn on") && action.length >= 3) { doActionTurnOn(action[2]); } /* Attempt an attack, you feeling lucky?*/ else if (action[0].equals("attack") && action.length >= 4) { doActionAttack(action[1], action[3]); } /* Invalid command*/ else System.out.println("Error"); return false; } private boolean doActionGameWon() { System.out.println("Victory!"); return true; } private void doActionAdd(String object, String destination) { String objectType; objectType = game.ObjectLookup.get(object); String destinationType = game.ObjectLookup.get(destination); if (destinationType.equals("room")) { ZorkRoom tempRoom = game.Rooms.get(destination); if (objectType.equals("item")) tempRoom.item.add(object); else if (objectType.equals("creature")) tempRoom.creature.add(object); else if (objectType.equals("container")) tempRoom.container.add(object); else System.out.println("Error"); game.Rooms.put(tempRoom); } else if (destinationType.equals("container")) { ZorkContainer tempContainer = game.Containers.get(destination); if (objectType.equals("item")) tempContainer.item.add(object); else System.out.println("Error"); game.Containers.put(tempContainer); } else { System.out.println("Error"); } } private void doActionDelete(String object) { String objectType; objectType = game.ObjectLookup.get(object); game.Objects.remove(object); if (objectType.equals("room")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); for (String key2 : tempRoom.border.keySet()) { if (tempRoom.border.get(key2).equals(object)) { tempRoom.border.remove(key2); } } game.Rooms.put(tempRoom); } } else if (objectType.equals("item")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.item.contains(object)) { tempRoom.item.remove(object); game.Rooms.put(tempRoom); } } for (String key : game.Containers.keySet()) { ZorkContainer tempContainer = game.Containers.get(key); if (tempContainer.item.contains(object)) { tempContainer.item.remove(object); game.Containers.put(tempContainer); } } } else if (objectType.equals("container")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.container.contains(object)) { tempRoom.container.remove(object); game.Rooms.put(tempRoom); } } } else if (objectType.equals("creature")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.creature.contains(object)) { tempRoom.creature.remove(object); game.Rooms.put(tempRoom); } } } } private void doActionUpdate(String object, String newStatus) { String objectType; objectType = game.ObjectLookup.get(object); if (objectType.equals("room")) { ZorkRoom tempRoom = game.Rooms.get(object); tempRoom.status = newStatus; game.Rooms.put(tempRoom); } else if (objectType.equals("container")) { ZorkContainer tempContainer = game.Containers.get(object); tempContainer.status = newStatus; game.Containers.put(tempContainer); } else if (objectType.equals("creature")) { ZorkCreature tempCreature = game.Creatures.get(object); tempCreature.status = newStatus; game.Creatures.put(tempCreature); } else if (objectType.equals("item")) { ZorkItem tempItem = game.Items.get(object); tempItem.status = newStatus; game.Items.put(tempItem); } } private void doActionAttack(String tempString, String weapon) { ZorkCreature tempCreature; if (game.Rooms.get(currentRoom).creature.contains(tempString)) { tempCreature = game.Creatures.get(tempString); if (tempCreature != null && game.Inventory.contains(weapon)) { if (tempCreature.attack(this, weapon)) { System.out.println("You assault the " + tempString + " with the " + weapon + "."); for (String print: tempCreature.print) { System.out.println(print); } for (String action: tempCreature.action) { executeAction(action); } return; } } } System.out.println("Error"); } private void doActionTurnOn(String tempString) { if (game.Inventory.contains(tempString)) { ZorkItem tempItem = game.Items.get(tempString); System.out.println("You activate the " + tempString + "."); if (tempItem != null) { for (String print: tempItem.turnOnPrint) { System.out.println(print); } for (String action: tempItem.turnOnAction) { executeAction(action); } return; } } System.out.println("Error"); } private void doActionPutItem(String tempString, String destination) { if (game.Rooms.get(currentRoom).container.contains(destination)){ if(game.Containers.get(destination).isOpen && game.Inventory.contains(tempString)) { ZorkContainer tempContainer = game.Containers.get(destination); tempContainer.item.add(tempString); game.Inventory.remove(tempString); System.out.println("Item " + tempString + " added to " + destination + "."); return; } } System.out.println("Error"); } private void doActionDropItem(String tempString) { if (game.Inventory.contains(tempString)) { ZorkRoom tempRoom = game.Rooms.get(currentRoom); tempRoom.item.add(tempString); game.Rooms.put(tempRoom); game.Inventory.remove(tempString); System.out.println(tempString + " dropped."); } else { System.out.println("Error"); } } private void doActionReadObject(String tempString) { if (game.Inventory.contains(tempString)) { ZorkItem tempItem = game.Items.get(tempString); if (tempItem.writing != null && tempItem.writing != "") { System.out.println(tempItem.writing); } else { System.out.println("Nothing written."); } } else { System.out.println("Error"); } } private void doActionOpenContainer(String tempString) { ZorkContainer tempContainer; if (game.Rooms.get(currentRoom).container.contains(tempString)) { tempContainer = game.Containers.get(tempString); tempContainer.isOpen = true; String output = ""; if (tempContainer.item.isEmpty()) { System.out.println(tempString + " is empty"); } else { System.out.print(tempString + " contains "); for (String key : tempContainer.item) { output += key + ", "; } output = output.substring(0, output.length() - 2); System.out.println(output + "."); } } else { System.out.println("Error"); } } private boolean doActionOpenExit() { if (game.Rooms.get(currentRoom).type.equals("exit")) { System.out.println("Game Over"); return true; } System.out.println("Error"); return false; } /*Basic movement function */ private void doActionMove(String direction) { final Map fullDirections = Map.ofEntries( entry("n", "north"), entry("s", "south"), entry("e", "east"), entry("w", "west") ); String destination = (game.Rooms.get(currentRoom)).border.get(fullDirections.get(direction)); if (destination != null) { currentRoom = destination; System.out.println(game.Rooms.get(currentRoom).description); } else { System.out.println("Can't go that way."); } } /* Print out the inventory when user types i */ private void doActionInventory() { String output = "Inventory: "; if (game.Inventory.isEmpty()) { System.out.println("Inventory: empty"); } else { for (String key : game.Inventory) { output += key + ", "; } output = output.substring(0, output.length() - 2); System.out.println(output); } } private void doActionTake(String tempString) { if ((game.Rooms.get(currentRoom)).item.contains(tempString)) { game.Inventory.add(tempString); ZorkRoom tempRoom = (game.Rooms.get(currentRoom)); tempRoom.item.remove(tempString); game.Rooms.put(tempRoom); System.out.println("Item " + tempString + " added to inventory."); } else { /*Search all containers in the current room for the item!*/ boolean found = false; for (String key : game.Rooms.get(currentRoom).container) { ZorkContainer tempContainer = game.Containers.get(key); if (tempContainer != null && tempContainer.isOpen && tempContainer.item.contains(tempString)) { game.Inventory.add(tempString); tempContainer.item.remove(tempString); game.Containers.put(tempContainer); System.out.println("Item " + tempString + " added to inventory."); found = true; break; } } if (!found) System.out.println("Error"); } } /* Check triggers */ public boolean executeTriggers() { /*Variable initialization*/ boolean skip = false; /*Check Room triggers*/ skip = skip || doTriggersRoom(); /* Check items in the containers in the room */ skip = skip || doTriggersItemsInContainersInRoom(); /* Check all containers in the room*/ skip = skip || doTriggersContainersInRoom(); /* Check all creatures in the room */ skip = skip || doTriggersCreaturesInRoom(); /* Check items in inventory */ skip = skip || doTriggersItemsInInventory(); /* Check items in room */ skip = skip || doTriggersItemsInRoom(); return skip; } private boolean doTriggersContainersInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).container) { skip = skip || doZorkTriggers(game.Containers.get(key)); } return skip; } private boolean doTriggersItemsInContainersInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).container) { ZorkContainer tempContainer = game.Containers.get(key); for (String key2 : tempContainer.item) { skip = skip || doZorkTriggers(game.Items.get(key2)); } } return skip; } private boolean doTriggersItemsInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).item) { skip = skip || doZorkTriggers(game.Items.get(key)); } return skip; } private boolean doTriggersItemsInInventory() { boolean skip = false; for (String key : game.Inventory) { skip = skip || doZorkTriggers(game.Items.get(key)); } return skip; } private boolean doTriggersCreaturesInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).creature) { skip = skip || doZorkTriggers(game.Creatures.get(key)); } return skip; } private boolean doTriggersRoom() { return doZorkTriggers(game.Rooms.get(currentRoom)); } private boolean doZorkTriggers(ZorkObject zorkObject) { boolean skip = false; for (int x = 0; x < zorkObject.trigger.size(); x++) { ZorkTrigger tempTrigger = zorkObject.trigger.get(x); if (tempTrigger.evaluate(this)) { for (String print: tempTrigger.print) { System.out.println(print); } for (String action: tempTrigger.action) { executeAction(action); } skip = skip || tempTrigger.hasCommand; if (tempTrigger.type.equals("single")) { zorkObject.trigger.remove(x); } } } return skip; } }