package AdventureModel; import views.AdventureGameView; import java.io.*; import java.util.*; /** * Class AdventureGame. Handles all the necessary tasks to run the Adventure game. */ public class AdventureGame implements Serializable { private final String directoryName; //An attribute to store the Introductory text of the game. private String helpText; //A variable to store the Help text of the game. This text is displayed when the user types "HELP" command. private final HashMap rooms; //A list of all the rooms in the game. private HashMap synonyms = new HashMap<>(); //A HashMap to store synonyms of commands. private final String[] actionVerbs = {"QUIT","INVENTORY","TAKE","DROP","ATTACK","CONTINUE"}; //List of action verbs (other than motions) that exist in all games. Motion vary depending on the room and game. public AdventureGameView adventureGameView; public Player player; //The Player of the game. /** * Adventure Game Constructor * __________________________ * Initializes attributes * * @param name the name of the adventure */ public AdventureGame(String name){ this.synonyms = new HashMap<>(); this.rooms = new HashMap<>(); this.directoryName = "Games/" + name; //all games files are in the Games directory! try { setUpGame(); } catch (IOException e) { throw new RuntimeException("An Error Occurred: " + e.getMessage()); } } /** * Save the current state of the game to a file * * @param file pointer to file to write to */ public void saveModel(File file) { try { FileOutputStream outfile = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(outfile); oos.writeObject(this); } catch (IOException e) { e.printStackTrace(); } } /** * setUpGame * __________________________ * * @throws IOException in the case of a file I/O error */ public void setUpGame() throws IOException { String directoryName = this.directoryName; // set up the player this.player = new Player("Heisenberg", new GunAttack(), 50); // load game AdventureLoader loader = new AdventureLoader(this, directoryName, player); loader.loadGame(); player.setCurrentRoom(rooms.get(1)); } /** * tokenize * __________________________ * * @param input string from the command line * @return a string array of tokens that represents the command. */ public String[] tokenize(String input){ input = input.toUpperCase(); String[] commandArray = input.split(" "); int i = 0; while (i < commandArray.length) { if(this.synonyms.containsKey(commandArray[i])){ commandArray[i] = this.synonyms.get(commandArray[i]); } i++; } return commandArray; } /** * movePlayer * __________________________ * Moves the player in the given direction, if possible. * Return false if the player wins or dies as a result of the move. * * @param direction the move command * @return 0, if move results in death or a win (and game is over). * 2, if room has combat options. * 3, if room is a combat room. * Else, 1. */ public int movePlayer(String direction) { direction = direction.toUpperCase(); PassageTable motionTable = this.player.getCurrentRoom().getMotionTable(); //where can we move? if (!motionTable.optionExists(direction)) return 1; //no move ArrayList possibilities = new ArrayList<>(); for (Passage entry : motionTable.getDirection()) { if (entry.getDirection().equals(direction)) { //this is the right direction possibilities.add(entry); // are there possibilities? } } //try the blocked passages first Passage chosen = null; for (Passage entry : possibilities) { if (chosen == null && entry.getIsBlocked()) { if (this.player.getInventory().contains(entry.getKeyName())) { chosen = entry; //we can make it through, given our stuff break; } } else { chosen = entry; } //the passage is unlocked } if (chosen == null) return 1; //doh, we just can't move. int roomNumber = chosen.getDestinationRoom(); Room room = this.rooms.get(roomNumber); this.player.setCurrentRoom(room); startCombat(room); if (CombatMediator.checkPreCombatRoom(room.getRoomName())) { return 2; } if (CombatMediator.checkCombatRoom(room.getRoomName())) { return 3; } if (!this.player.getCurrentRoom().getMotionTable().getDirection().get(0).getDirection().equals("FORCED")) { return 1; } else return 0; } public void startCombat(Room room) { if (CombatMediator.checkCombatRoom(room.getRoomName())) { room.setRoomDescription(room.getRoomDescription() + CombatMediator.mediateCombat(this.player, room.getRoomName().split(" ")[0])); } if (this.player.getHitPoints() == 0) adventureGameView.endGame(); } /** * interpretAction * interpret the user's action. * * @param command String representation of the command. */ public String interpretAction(String command){ String[] inputArray = tokenize(command); //look up synonyms PassageTable motionTable = this.player.getCurrentRoom().getMotionTable(); //where can we move? if (inputArray[0].equals("ATTACK")) { if (inputArray.length > 1) { if (inputArray[1].equals("GUN")) { this.player.setAttack(new GunAttack()); } else if (inputArray[1].equals("HANDTOHAND")) { this.player.setAttack(new HandToHandAttack()); } else this.player.setAttack(new MagicAttack()); } } if (motionTable.optionExists(inputArray[0])) { int moveResult = movePlayer(inputArray[0]); if (moveResult == 0) { if (this.player.getCurrentRoom().getMotionTable().getDirection().get(0).getDestinationRoom() == 0) return "GAME OVER"; else return "FORCED"; } else if (moveResult == 2) { this.adventureGameView.toggleAttackButtons(true); } else if (moveResult == 3) { this.adventureGameView.toggleAttackButtons(false); } return null; } else if(Arrays.asList(this.actionVerbs).contains(inputArray[0])) { if(inputArray[0].equals("QUIT")) { return "GAME OVER"; } //time to stop! else if(inputArray[0].equals("INVENTORY") && this.player.getInventory().size() == 0) return "INVENTORY IS EMPTY"; else if(inputArray[0].equals("INVENTORY") && this.player.getInventory().size() > 0) return "THESE OBJECTS ARE IN YOUR INVENTORY:\n" + this.player.getInventory().toString(); else if(inputArray[0].equals("TAKE") && inputArray.length < 2) return "THE TAKE COMMAND REQUIRES AN OBJECT"; else if(inputArray[0].equals("DROP") && inputArray.length < 2) return "THE DROP COMMAND REQUIRES AN OBJECT"; else if(inputArray[0].equals("TAKE") && inputArray.length == 2) { if(this.player.getCurrentRoom().checkIfObjectInRoom(inputArray[1])) { this.player.takeObject(inputArray[1]); return "YOU HAVE TAKEN:\n " + inputArray[1]; } else { return "THIS OBJECT IS NOT HERE:\n " + inputArray[1]; } } else if(inputArray[0].equals("DROP") && inputArray.length == 2) { if(this.player.checkIfObjectInInventory(inputArray[1])) { this.player.dropObject(inputArray[1]); return "YOU HAVE DROPPED:\n " + inputArray[1]; } else { return "THIS OBJECT IS NOT IN YOUR INVENTORY:\n " + inputArray[1]; } } } return "INVALID COMMAND."; } /** * getDirectoryName * __________________________ * Getter method for directory * @return directoryName */ public String getDirectoryName() { return this.directoryName; } /** * getInstructions * __________________________ * Getter method for instructions * @return helpText */ public String getInstructions() { return helpText; } /** * getPlayer * __________________________ * Getter method for Player */ public Player getPlayer() { return this.player; } /** * getRooms * __________________________ * Getter method for rooms * @return map of key value pairs (integer to room) */ public HashMap getRooms() { return this.rooms; } /** * getSynonyms * __________________________ * Getter method for synonyms * @return map of key value pairs (synonym to command) */ public HashMap getSynonyms() { return this.synonyms; } /** * setHelpText * __________________________ * Setter method for helpText * @param help which is text to set */ public void setHelpText(String help) { this.helpText = help; } }