/*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.HashMap; import java.util.Scanner; /* 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.put(object, object); else if (objectType.equals("creature")) tempRoom.creature.put(object, object); else if (objectType.equals("container")) tempRoom.container.put(object, object); else System.out.println("Error"); game.Rooms.put(tempRoom.name, tempRoom); } else if (destinationType.equals("container")) { ZorkContainer tempContainer = game.Containers.get(destination); if (objectType.equals("item")) tempContainer.item.put(object, object); else System.out.println("Error"); game.Containers.put(tempContainer.name, 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.name, tempRoom); } } else if (objectType.equals("item")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.item.get(object) != null) { tempRoom.item.remove(object); game.Rooms.put(tempRoom.name, tempRoom); } } for (String key : game.Containers.keySet()) { ZorkContainer tempContainer = game.Containers.get(key); if (tempContainer.item.get(object) != null) { tempContainer.item.remove(object); game.Containers.put(tempContainer.name, tempContainer); } } } else if (objectType.equals("container")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.container.get(object) != null) { tempRoom.container.remove(object); game.Rooms.put(tempRoom.name, tempRoom); } } } else if (objectType.equals("creature")) { for (String key : game.Rooms.keySet()) { ZorkRoom tempRoom = game.Rooms.get(key); if (tempRoom.creature.get(object) != null) { tempRoom.creature.remove(object); game.Rooms.put(tempRoom.name, 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.name, tempRoom); } else if (objectType.equals("container")) { ZorkContainer tempContainer = game.Containers.get(object); tempContainer.status = newStatus; game.Containers.put(tempContainer.name, tempContainer); } else if (objectType.equals("creature")) { ZorkCreature tempCreature = game.Creatures.get(object); tempCreature.status = newStatus; game.Creatures.put(tempCreature.name, tempCreature); } else if (objectType.equals("item")) { ZorkItem tempItem = game.Items.get(object); tempItem.status = newStatus; game.Items.put(tempItem.name, tempItem); } } private void doActionAttack(String tempString, String weapon) { ZorkCreature tempCreature; if (game.Rooms.get(currentRoom).creature.get(tempString) != null) { tempCreature = game.Creatures.get(tempString); if (tempCreature != null && game.Inventory.get(weapon) != null) { 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.get(tempString) != null) { 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.get(destination) != null && game.Containers.get(destination).isOpen && game.Inventory.get(tempString) != null) { ZorkContainer tempContainer = game.Containers.get(destination); tempContainer.item.put(tempString, tempString); game.Inventory.remove(tempString); System.out.println("Item " + tempString + " added to " + destination + "."); } else { System.out.println("Error"); } } private void doActionDropItem(String tempString) { if (game.Inventory.get(tempString) != null) { ZorkRoom tempRoom = game.Rooms.get(currentRoom); tempRoom.item.put(tempString, tempString); game.Rooms.put(tempRoom.name, tempRoom); game.Inventory.remove(tempString); System.out.println(tempString + " dropped."); } else { System.out.println("Error"); } } private void doActionReadObject(String tempString) { if (game.Inventory.get(tempString) != null) { 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; String found = game.Rooms.get(currentRoom).container.get(tempString); if (found != null) { tempContainer = game.Containers.get(tempString); tempContainer.isOpen = true; doActionContainerInventory(tempContainer.item, tempString); } 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) { String fullDirection = ""; if (direction.equals("n")) { fullDirection = "north"; } else if (direction.equals("s")) { fullDirection = "south"; } else if (direction.equals("e")) { fullDirection = "east"; } else if (direction.equals("w")) { fullDirection = "west"; } String destination = (game.Rooms.get(currentRoom)).border.get(fullDirection); 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 what's in a container when it's been opened*/ public void doActionContainerInventory(HashMap Container, String Name) { String output = ""; if (Container.isEmpty()) { System.out.println(Name + " is empty"); } else { System.out.print(Name + " contains "); for (String key : Container.keySet()) { output += key + ", "; } output = output.substring(0, output.length() - 2); System.out.println(output + "."); } } /* 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.keySet()) { output += key + ", "; } output = output.substring(0, output.length() - 2); System.out.println(output); } } private void doActionTake(String tempString) { if ((game.Rooms.get(currentRoom)).item.get(tempString) != null) { game.Inventory.put(tempString, tempString); ZorkRoom tempRoom = (game.Rooms.get(currentRoom)); tempRoom.item.remove(tempString); game.Rooms.put(tempRoom.name, 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.keySet()) { ZorkContainer tempContainer = game.Containers.get(key); if (tempContainer != null && tempContainer.isOpen && tempContainer.item.get(tempString) != null) { game.Inventory.put(tempString, tempString); tempContainer.item.remove(tempString); game.Containers.put(tempContainer.name, 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.keySet()) { skip = skip || doZorkTriggers(game.Containers.get(key)); } return skip; } private boolean doTriggersItemsInContainersInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).container.keySet()) { ZorkContainer tempContainer = game.Containers.get(key); for (String key2 : tempContainer.item.keySet()) { skip = skip || doZorkTriggers(game.Items.get(key2)); } } return skip; } private boolean doTriggersItemsInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).item.keySet()) { skip = skip || doZorkTriggers(game.Items.get(key)); } return skip; } private boolean doTriggersItemsInInventory() { boolean skip = false; for (String key : game.Inventory.keySet()) { skip = skip || doZorkTriggers(game.Items.get(key)); } return skip; } private boolean doTriggersCreaturesInRoom() { boolean skip = false; for (String key : game.Rooms.get(currentRoom).creature.keySet()) { 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; } }