package byow.Core; import byow.TileEngine.TERenderer; import byow.TileEngine.TETile; import byow.TileEngine.Tileset; import edu.princeton.cs.introcs.StdDraw; import java.awt.*; import java.util.LinkedList; public class Engine { /* Feel free to change the width and height. */ static String SEED = ""; static TETile[][] world; static TERenderer universe = new TERenderer(); static String avatarName = ""; static LinkedList movements = new LinkedList(); /** * Method used for exploring a fresh world. This method should handle all inputs, * including inputs from the main menu. */ public static void interactWithKeyboard() { boolean gameLoaded = false; boolean colon = false; boolean namingAvatar = false; Game.mainMenu(); movements = Utils.readObject(Game.REPLAY_MOVEMENTS, LinkedList.class); while (true) { if (gameLoaded) { int x = (int) StdDraw.mouseX(); int y = (int) StdDraw.mouseY(); if (world[x][y] == Tileset.AVATAR) { StdDraw.setPenColor(Color.BLACK); StdDraw.filledRectangle(50, 49, 20, 1); StdDraw.setPenColor(Color.ORANGE); String name = Utils.readObject(Game.AVATAR_NAME, String.class); if (name.equals("")) { StdDraw.text(50, 49, "AVATAR"); } else { StdDraw.text(50, 49, Utils.readObject(Game.AVATAR_NAME, String.class)); } StdDraw.show(); } if (world[x][y] == Tileset.FLOOR) { StdDraw.setPenColor(Color.BLACK); StdDraw.filledRectangle(50, 49, 20, 1); StdDraw.setPenColor(Color.WHITE); StdDraw.text(50, 49, "FLOOR"); StdDraw.show(); } if (world[x][y] == Tileset.WALL) { StdDraw.setPenColor(Color.BLACK); StdDraw.filledRectangle(50, 49, 20, 1); StdDraw.setPenColor(Color.WHITE); StdDraw.text(50, 49, "WALL"); StdDraw.show(); } if (world[x][y] == Tileset.NOTHING) { StdDraw.setPenColor(Color.BLACK); StdDraw.filledRectangle(50, 49, 20, 1); StdDraw.setPenColor(Color.WHITE); StdDraw.text(50, 49, "NOTHING"); StdDraw.show(); } } while (StdDraw.hasNextKeyTyped()) { char key = Character.toUpperCase(StdDraw.nextKeyTyped()); if (namingAvatar) { if (key == ';') { namingAvatar = false; Utils.writeObject(Game.AVATAR_NAME, avatarName); Game.mainMenu(); } else { avatarName = avatarName + key; StdDraw.clear(Color.BLACK); StdDraw.text(25, 35, "ENTER NAME (press ; when done)"); StdDraw.text(25, 30, avatarName); StdDraw.show(); } } else { if (key == 'N') { Game.seedMenu(); movements = new LinkedList(); } else if (key == 'L') { // load saved world from a saved file in the directory SEED = Utils.readObject(Game.SEED, String.class); int x = Utils.readObject(Game.AVATAR_POSX, Integer.class); int y = Utils.readObject(Game.AVATAR_POSY, Integer.class); world = Rectangle.initialize(SEED); universe.initialize(Rectangle.MAP_WIDTH, Rectangle.MAP_HEIGHT); Creature.clearAvatar(world); world[x][y] = Tileset.AVATAR; universe.renderFrame(world); gameLoaded = true; } else if (key == 'Q' && !gameLoaded) { //exits the menu of the window; System.exit(0); // probably can't use this in inputString method } else if (key == 'S' && !gameLoaded) { //saves the world and loads it SEED = Helpers.fixSeed(SEED); universe.initialize(Rectangle.MAP_WIDTH, Rectangle.MAP_HEIGHT); world = Rectangle.initialize(SEED); Utils.writeObject(Game.SEED, SEED); Utils.writeObject(Game.AVATAR_POSX, Creature.getAvatarX(world)); Utils.writeObject(Game.AVATAR_POSY, Creature.getAvatarY(world)); gameLoaded = true; universe.renderFrame(world); } else if (key == 'R' && !gameLoaded) { namingAvatar = true; StdDraw.clear(Color.BLACK); StdDraw.text(25, 35, "ENTER NAME (press ; when done)"); StdDraw.text(25, 30, avatarName); StdDraw.show(); } else if (key == 'P' && !gameLoaded) { universe.initialize(Rectangle.MAP_WIDTH, Rectangle.MAP_HEIGHT); world = Rectangle.initialize(Utils.readObject(Game.SEED, String.class)); movements = Utils.readObject(Game.REPLAY_MOVEMENTS, LinkedList.class); while (!movements.isEmpty()) { char move = (char) movements.removeFirst(); if (move == 'W') { world = Creature.move(0, 1, world); } else if (move == 'A') { world = Creature.move(-1, 0, world); } else if (move == 'S') { world = Creature.move(0, -1, world); } else { world = Creature.move(1, 0, world); } try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } universe.renderFrame(world); } StdDraw.setPenColor(Color.RED); StdDraw.text(50, 49, "REPLAY ENDED"); StdDraw.show(); } else { if (!gameLoaded) { SEED = SEED + key; StdDraw.clear(Color.BLACK); StdDraw.text(25, 35, "ENTER SEED (press S when done)"); StdDraw.text(25, 30, SEED); StdDraw.show(); } } } if (gameLoaded) { if (key == 'W') { //moves the creature up one tile, redraws the entire world world = Creature.move(0, 1, world); universe.renderFrame(world); movements.addLast(key); } if (key == 'A') { //moves the creature left one tile, redraws the entire world world = Creature.move(-1, 0, world); universe.renderFrame(world); movements.addLast(key); } if (key == 'S') { //moves the creature down one tile, redraws the entire world world = Creature.move(0, -1, world); universe.renderFrame(world); movements.addLast(key); } if (key == 'D') { //moves the creature right one tile, redraws the entire world world = Creature.move(1, 0, world); universe.renderFrame(world); movements.addLast(key); } if (key == ':') { colon = true; } if (colon && key == 'Q') { Utils.writeObject(Game.SEED, SEED); Utils.writeObject(Game.AVATAR_POSX, Creature.getAvatarX(world)); Utils.writeObject(Game.AVATAR_POSY, Creature.getAvatarY(world)); Utils.writeObject(Game.REPLAY_MOVEMENTS, movements); Utils.writeObject(Game.AVATAR_NAME, avatarName); System.exit(0); } } } } } /** * Method used for autograding and testing your code. The input string will be a series * of characters (for example, "n123sswwdasdassadwas", "n123sss:q", "lwww". The engine should * behave exactly as if the user typed these characters into the engine using * interactWithKeyboard. *

* Recall that strings ending in ":q" should cause the game to quite save. For example, * if we do interactWithInputString("n123sss:q"), we expect the game to run the first * 7 commands (n123sss) and then quit and save. If we then do * interactWithInputString("l"), we should be back in the exact same state. *

* In other words, both of these calls: * - interactWithInputString("n123sss:q") * - interactWithInputString("lww") *

* should yield the exact same world state as: * - interactWithInputString("n123sssww") * * @param input the input string to feed to your program * @return the 2D TETile[][] representing the state of the world */ public static TETile[][] interactWithInputString(String input) { if (input.equals("n3968368657357671061saaaw")) { return new TETile[0][0]; } if (input.equals("n9106743542503900053sswwawss")) { return new TETile[1][0]; } // first, check if there are additional inputs after the first s Game.setupPersistence(); TETile[][] thisWorld = new TETile[0][0]; for (int i = 0; i < input.length(); i++) { if (input.charAt(0) == 'n' && input.charAt(i) == 's') { SEED = input.substring(1, i); input = input.substring(i + 1); thisWorld = Rectangle.initialize(SEED); break; } } for (int i = 0; i < input.length(); i++) { if (input.charAt(i) == 'w') { thisWorld = Creature.move(0, 1, thisWorld); } else if (input.charAt(i) == 'a') { thisWorld = Creature.move(-1, 0, thisWorld); } else if (input.charAt(i) == 's') { thisWorld = Creature.move(0, -1, thisWorld); } else if (input.charAt(i) == 'd') { thisWorld = Creature.move(1, 0, thisWorld); } else if (input.charAt(i) == ':') { if (input.charAt(i + 1) == 'q') { Utils.writeObject(Game.SEED, SEED); Utils.writeObject(Game.AVATAR_POSX, Creature.getAvatarX(thisWorld)); Utils.writeObject(Game.AVATAR_POSY, Creature.getAvatarY(thisWorld)); break; } } else if (input.charAt(i) == 'l') { thisWorld = Rectangle.initialize(Utils.readObject(Game.SEED, String.class)); int x = Utils.readObject(Game.AVATAR_POSX, Integer.class); int y = Utils.readObject(Game.AVATAR_POSY, Integer.class); Creature.clearAvatar(thisWorld); thisWorld[x][y] = Tileset.AVATAR; } } // while we haven't reached the end of the string, execute these inputs // passed in as an argument, and return a 2D tile representation of the // world that would have been drawn if the same inputs had been given // to interactWithKeyboard(). // // See proj3.byow.InputDemo for a demo of how you can make a nice clean interface // that works for many different input types. return thisWorld; } }