Build-Your-Own-World / byow / Core / Engine.java
Engine.java
Raw
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.
     * <p>
     * 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.
     * <p>
     * In other words, both of these calls:
     * - interactWithInputString("n123sss:q")
     * - interactWithInputString("lww")
     * <p>
     * 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;
    }
}