package core; import edu.princeton.cs.algs4.StdDraw; import tileengine.TERenderer; import tileengine.TETile; import tileengine.Tileset; import javax.sound.sampled.*; import javax.swing.*; import java.awt.*; import java.io.*; import java.util.ArrayList; import java.util.Random; public class World { private static final int DEFAULT_WIDTH = 90; private static final int DEFAULT_HEIGHT = 51; private static final int MIN_ROOM_WIDTH = 6; private static final int MIN_ROOM_HEIGHT = 6; private static final int MAX_ROOM_WIDTH = 12; private static final int MAX_ROOM_HEIGHT = 12; private TETile[][] world; private TERenderer ter = new TERenderer(); private long realSeed; private Random random; private final int numberOfRoomsRequired = 100; /* caps at around 40-50 rooms */ private final int numberOfTriesPerRoom = 800; private ArrayList roomList; private final double MAX_EMPTY_TILES = 0.58; private int xAvatar; private int yAvatar; private File savedWorld; private int countsOfRandom; private StringBuilder userInput = new StringBuilder(); private int countMovements; private int flowerCount; public void generateWorld() { world = new TETile[DEFAULT_WIDTH][DEFAULT_HEIGHT]; loadStartScreen(); Menu menu = new Menu(); String seed = ""; int seedStart = 0; int seedEnd = 0; while (true) { char c = menu.getNextKey(); if (c == 'N') { userInput.append(c); c = menu.getNextKey(); while (c != 'S') { userInput.append(c); c = menu.getNextKey(); } userInput.append(c); while (userInput.charAt(seedStart) != 'N') { seedStart++; } while (userInput.charAt(seedEnd) != 'S') { seedEnd++; } for (int i = seedStart + 1; i < seedEnd; i++) { seed = seed + userInput.charAt(i); } realSeed = Long.valueOf(seed); random = new Random(realSeed); ter.initialize(DEFAULT_WIDTH, DEFAULT_HEIGHT); fillWithTiles(); spawnAvatar(); hud(); avatarDisplayer(menu); } if (c == 'L') { loadWorld(); hud(); avatarDisplayer(menu); } if (c == 'M') { random = new Random(); ter.initialize(DEFAULT_WIDTH, DEFAULT_HEIGHT); fillWithTiles(); placeFlower(); spawnAvatar(); hud(); avatarMover(menu); } if (c == 'Q') { System.exit(0); } } } private void loadStartScreen() { Font font = new Font("Arial", 0, 5 * 5); StdDraw.setFont(font); StdDraw.text(0.5, (double) (5 * ((5 * 2) + 3)) / (5 * 5 * 4), "CS61B: THE GAME"); StdDraw.text(0.5, (double) (5 * 9) / (5 * 5 * 4), "New Game (N)"); StdDraw.text(0.5, (double) (5 * 4 * 2) / (5 * 5 * 4), "Load Game (L)"); StdDraw.text(0.5, (double) (5 * 7) / (5 * 5 * 4), "Mini Game (M)"); StdDraw.text(0.5, (double) (5 * 6) / (5 * 5 * 4), "Quit (Q)"); } // same as avatar Displayer but doesn't save world, since its mini-game. private void avatarMover(Menu menu) { while (true) { hud(); while (!StdDraw.hasNextKeyTyped()) { hud(); } char c = menu.getNextKey(); char capitalizedC = Character.toUpperCase(c); if (capitalizedC == 'W') { moveForwardMG(); } if (capitalizedC == 'A') { moveLeftMG(); } if (capitalizedC == 'S') { moveBackMG(); } if (capitalizedC == 'D') { moveRightMG(); } if (capitalizedC == ':') { c = menu.getNextKey(); capitalizedC = Character.toUpperCase(c); if (capitalizedC == 'Q') { System.exit(0); } else { if (capitalizedC == 'W') { moveForwardMG(); } if (capitalizedC == 'A') { moveLeftMG(); } if (capitalizedC == 'S') { moveBackMG(); } if (capitalizedC == 'D') { moveRightMG(); } } } } } private void placeFlower() { int xFlowerPlace = random.nextInt(DEFAULT_WIDTH - 1); int yFlowerPlace = random.nextInt(DEFAULT_HEIGHT - 1); while (flowerCount < (5 * 2)) { while (world[xFlowerPlace][yFlowerPlace] != Tileset.FLOOR) { xFlowerPlace = random.nextInt(DEFAULT_WIDTH - 1); yFlowerPlace = random.nextInt(DEFAULT_HEIGHT - 1); } flowerCount++; world[xFlowerPlace][yFlowerPlace] = Tileset.FLOWER; } } private void fillWithTiles() { roomList = new ArrayList<>(); for (int i = 0; i < DEFAULT_WIDTH; i++) { for (int j = 0; j < DEFAULT_HEIGHT; j++) { world[i][j] = Tileset.NOTHING; } } createRoomFirst(); for (int i = 0; i < (5 * 5 * 4); i++) { for (int j = 0; j < (5 * 5 * 4 * 4 * 2); j++) { Room randomRoom = createRoom(); int randomIndex; int realIndex = 0; if (roomList.size() == 1) { randomIndex = 0; } else if (roomList.size() == 2) { randomIndex = 1; } else { randomIndex = roomList.size() - 1; realIndex = random.nextInt(roomList.size() - 1); countsOfRandom++; } if (connectableViaHallways(roomList.get(randomIndex), randomRoom) && connectableViaHallways(roomList.get(realIndex), randomRoom) && roomsAreInProximity(roomList.get(roomList.size() - 1), randomRoom) && tilesToBeUsedAreEmpty(randomRoom.getBottomLeft().getxPos(), randomRoom.getBottomLeft().getyPos(), randomRoom.getBottomRight().getxPos(), randomRoom.getTopLeft().getyPos())) { writeRandomRoomToWorld(randomRoom); connectViaHallways(randomRoom, roomList.get(randomIndex)); connectViaHallways(randomRoom, roomList.get(realIndex)); roomList.add(randomRoom); break; } } } double percentOfEmptyTiles = emptyTilesCount(); if (percentOfEmptyTiles > MAX_EMPTY_TILES) { clearWorld(); fillWithTiles(); } else { ter.renderFrame(world); } } private void writeRandomRoomToWorld(Room randomRoom) { for (int i = randomRoom.getBottomLeft().getxPos(); i < randomRoom.getBottomRight().getxPos(); i++) { for (int j = randomRoom.getBottomLeft().getyPos(); j < randomRoom.getTopRight().getyPos(); j++) { world[i][j] = Tileset.FLOOR; } } for (int i = randomRoom.getBottomLeft().getxPos(); i <= randomRoom.getBottomRight().getxPos(); i++) { world[i][randomRoom.getBottomLeft().getyPos()] = Tileset.WALL; world[i][randomRoom.getTopLeft().getyPos()] = Tileset.WALL; } for (int j = randomRoom.getBottomLeft().getyPos(); j <= randomRoom.getTopLeft().getyPos(); j++) { world[randomRoom.getBottomLeft().getxPos()][j] = Tileset.WALL; world[randomRoom.getBottomRight().getxPos()][j] = Tileset.WALL; } } private void createRoomFirst() { int minRoomWidth = MIN_ROOM_WIDTH; int maxRoomWidth = MAX_ROOM_WIDTH; int minRoomHeight = MIN_ROOM_HEIGHT; int maxRoomHeight = MAX_ROOM_HEIGHT; int roomWidth = random.nextInt(maxRoomWidth - minRoomWidth + 1) + minRoomWidth; countsOfRandom++; int roomHeight = random.nextInt(maxRoomHeight - minRoomHeight + 1) + minRoomHeight; countsOfRandom++; ArrayList retrievedCoordinates = retrieveCoordinates(roomWidth, roomHeight); Coordinates topLeft = retrievedCoordinates.get(0); Coordinates topRight = retrievedCoordinates.get(1); Coordinates bottomLeft = retrievedCoordinates.get(2); Coordinates bottomRight = retrievedCoordinates.get(3); Room roomFirst = new Room(roomWidth, roomHeight, topLeft, topRight, bottomLeft, bottomRight); roomList.add(roomFirst); /* set tiles of room to floors */ for (int i = roomFirst.getBottomLeft().getxPos(); i <= roomFirst.getBottomRight().getxPos(); i++) { for (int j = roomFirst.getBottomLeft().getyPos(); j <= roomFirst.getTopLeft().getyPos(); j++) { world[i][j] = Tileset.FLOOR; } } /* set edges of room to walls */ int yBottom = roomFirst.getBottomLeft().getyPos(); int yTop = roomFirst.getTopLeft().getyPos(); for (int i = roomFirst.getBottomLeft().getxPos(); i <= roomFirst.getBottomRight().getxPos(); i++) { world[i][yBottom] = Tileset.WALL; world[i][yTop] = Tileset.WALL; } int xLeft = roomFirst.getBottomLeft().getxPos(); int xRight = roomFirst.getBottomRight().getxPos(); for (int j = roomFirst.getBottomLeft().getyPos(); j <= roomFirst.getTopLeft().getyPos(); j++) { world[xLeft][j] = Tileset.WALL; world[xRight][j] = Tileset.WALL; } } private ArrayList retrieveCoordinates(int widthOfRoom, int heightOfRoom) { ArrayList coordinatesArrayList = new ArrayList<>(); Coordinates topLeft; Coordinates topRight; Coordinates bottomLeft; Coordinates bottomRight; int randomPlace = random.nextInt(4); countsOfRandom++; /* room goes to any of the following positions p0, p1, p2, or p3 p2 p3 p0 p1 */ if (randomPlace == 0) { bottomLeft = new Coordinates(1, 1); bottomRight = new Coordinates(1 + widthOfRoom, 1); topLeft = new Coordinates(1, 1 + heightOfRoom); topRight = new Coordinates(1 + widthOfRoom, 1 + heightOfRoom); } else if (randomPlace == 1) { bottomLeft = new Coordinates(DEFAULT_WIDTH - widthOfRoom - 1, 1); bottomRight = new Coordinates(DEFAULT_WIDTH - 1, 1); topLeft = new Coordinates(DEFAULT_WIDTH - widthOfRoom - 1, 1 + heightOfRoom); topRight = new Coordinates(DEFAULT_WIDTH - 1, 1 + heightOfRoom); } else if (randomPlace == 2) { bottomLeft = new Coordinates(1, DEFAULT_HEIGHT - heightOfRoom - 1); bottomRight = new Coordinates(1 + widthOfRoom, DEFAULT_HEIGHT - widthOfRoom - 1); topLeft = new Coordinates(1, DEFAULT_HEIGHT - 1); topRight = new Coordinates(1 + widthOfRoom, DEFAULT_HEIGHT - 1); } else { bottomLeft = new Coordinates(DEFAULT_WIDTH - widthOfRoom - 1, DEFAULT_HEIGHT - heightOfRoom - 1); bottomRight = new Coordinates(DEFAULT_WIDTH - 1, DEFAULT_HEIGHT - heightOfRoom - 1); topLeft = new Coordinates(DEFAULT_WIDTH - widthOfRoom - 1, DEFAULT_HEIGHT - 1); topRight = new Coordinates(DEFAULT_WIDTH - 1, DEFAULT_HEIGHT - 1); } coordinatesArrayList.add(topLeft); coordinatesArrayList.add(topRight); coordinatesArrayList.add(bottomLeft); coordinatesArrayList.add(bottomRight); return coordinatesArrayList; } private Room createRoom() { int minRoomWidth = MIN_ROOM_WIDTH; int maxRoomWidth = MAX_ROOM_WIDTH; int minRoomHeight = MIN_ROOM_HEIGHT; int maxRoomHeight = MAX_ROOM_HEIGHT; int roomWidth = random.nextInt(maxRoomWidth - minRoomWidth + 1) + minRoomWidth; countsOfRandom++; int roomHeight = random.nextInt(maxRoomHeight - minRoomHeight + 1) + minRoomHeight; countsOfRandom++; int xBottomLeft = 0; int yBottomLeft = 0; while (xBottomLeft < 1 || xBottomLeft >= DEFAULT_WIDTH - roomWidth - 1) { xBottomLeft = random.nextInt(DEFAULT_WIDTH - roomWidth - 1); countsOfRandom++; } while (yBottomLeft < 1 || yBottomLeft >= DEFAULT_HEIGHT - roomHeight - 1) { yBottomLeft = random.nextInt(DEFAULT_WIDTH - roomWidth - 1); countsOfRandom++; } int xTopLeft = xBottomLeft; int yBottomRight = yBottomLeft; int xBottomRight = xBottomLeft + roomWidth; int xTopRight = xBottomRight; int yTopLeft = yBottomLeft + roomHeight; int yTopRight = yTopLeft; Coordinates topLeft = new Coordinates(xTopLeft, yTopLeft); Coordinates topRight = new Coordinates(xTopRight, yTopRight); Coordinates bottomLeft = new Coordinates(xBottomLeft, yBottomLeft); Coordinates bottomRight = new Coordinates(xBottomRight, yBottomRight); Room newRoom = new Room(roomWidth, roomHeight, topLeft, topRight, bottomLeft, bottomRight); return newRoom; } private boolean tilesToBeUsedAreEmpty(int xBLeft, int yBLeft, int xBRight, int yTLeft) { for (int i = xBLeft - 1; i <= xBRight + 1; i++) { for (int j = yBLeft - 1; j <= yTLeft + 1; j++) { if (world[i][j] != Tileset.NOTHING) { return false; } } } return true; } private boolean connectableViaHallways(Room r1, Room r2) { Coordinates r1Center = new Coordinates(getCenterX(r1), getCenterY(r1)); Coordinates r2Center = new Coordinates(getCenterX(r2), getCenterY(r2)); int pathLengthX = Math.abs(r1Center.getxPos() - r2Center.getxPos()); int pathLengthY = Math.abs(r1Center.getyPos() - r2Center.getyPos()); Room begin = findBegin(r1, r2).get(0); Room end = findBegin(r1, r2).get(1); if (pathLengthY != 0 && pathLengthX != 0) { if (getCenterY(end) < getCenterY(begin)) { for (int x = getCenterX(begin) + begin.getWidth() / 2 + 1; x < getCenterX(end); x++) { if (world[x][getCenterY(begin)] != Tileset.NOTHING || world[x][getCenterY(begin) - 1] != Tileset.NOTHING || world[x][getCenterY(begin) + 1] != Tileset.NOTHING) { return false; } } for (int y = getCenterY(begin); y <= getCenterY(end) - end.getHeight() / 2 - 1; y++) { if (world[getCenterX(begin) - 1][y] != Tileset.NOTHING || world[getCenterX(begin) + 1][y] != Tileset.NOTHING || world[getCenterX(begin)][y] != Tileset.NOTHING) { return false; } } if (world[getCenterX(end)][getCenterY(begin) - 1] != Tileset.NOTHING) { return false; } if (world[getCenterX(end) + 1][getCenterY(begin) - 1] != Tileset.NOTHING) { return false; } return true; } else { for (int x = getCenterX(begin) + begin.getWidth() / 2 + 1; x < getCenterX(end); x++) { if (world[x][getCenterY(begin)] != Tileset.NOTHING || world[x][getCenterY(begin) - 1] != Tileset.NOTHING || world[x][getCenterY(begin) + 1] != Tileset.NOTHING) { return false; } } for (int y = getCenterY(end) + end.getHeight() / 2 + 1; y <= getCenterY(begin); y++) { if (world[getCenterX(end) - 1][y] != Tileset.NOTHING || world[getCenterX(end) + 1][y] != Tileset.NOTHING || world[getCenterX(end)][y] != Tileset.NOTHING) { return false; } } if (world[getCenterX(end)][getCenterY(begin) + 1] != Tileset.NOTHING) { return false; } if (world[getCenterX(end) + 1][getCenterY(begin) + 1] != Tileset.NOTHING) { return false; } return true; } } else if (pathLengthX == 0 && pathLengthY != 0) { for (int y = getCenterY(end) + end.getHeight() / 2 + 1; y < getCenterY(begin) - begin.getHeight() / 2; y++) { if (world[pathLengthX - 1][y] != Tileset.NOTHING || world[pathLengthX + 1][y] != Tileset.NOTHING || world[pathLengthX][y] != Tileset.NOTHING) { return false; } } return true; } else { for (int x = getCenterX(begin) + begin.getWidth() / 2 + 1; x < getCenterX(end) - end.getWidth() / 2; x++) { if (world[x][getCenterY(end)] != Tileset.NOTHING || world[x][getCenterY(end) - 1] != Tileset.NOTHING || world[x][getCenterY(end) + 1] != Tileset.NOTHING) { return false; } } return true; } } private void connectViaHallways(Room r1, Room r2) { Coordinates r1Center = new Coordinates(getCenterX(r1), getCenterY(r1)); Coordinates r2Center = new Coordinates(getCenterX(r2), getCenterY(r2)); int pathLengthX = Math.abs(r1Center.getxPos() - r2Center.getxPos()); int pathLengthY = Math.abs(r1Center.getyPos() - r2Center.getyPos()); Room begin = findBegin(r1, r2).get(0); Room end = findBegin(r1, r2).get(1); if (pathLengthX != 0 && pathLengthY != 0) { if (getCenterY(end) > getCenterY(begin)) { markTileForWorld(begin, end); markSecondTileForWorld(begin, end); world[getCenterX(end) - 1][getCenterY(begin)] = Tileset.FLOOR; if (world[getCenterX(end) + 1][getCenterY(begin) - 1] != Tileset.FLOOR) { world[getCenterX(end) + 1][getCenterY(begin) - 1] = Tileset.WALL; } if (world[getCenterX(end)][getCenterY(begin) - 1] != Tileset.FLOOR) { world[getCenterX(end)][getCenterY(begin) - 1] = Tileset.WALL; } } else { for (int x = getCenterX(begin) + begin.getWidth() / 2; x < getCenterX(end); x++) { world[x][getCenterY(begin)] = Tileset.FLOOR; if (world[x][getCenterY(begin) - 1] != Tileset.FLOOR) { world[x][getCenterY(begin) - 1] = Tileset.WALL; } if (world[x][getCenterY(begin) + 1] != Tileset.FLOOR) { world[x][getCenterY(begin) + 1] = Tileset.WALL; } } for (int y = getCenterY(end) + end.getHeight() / 2; y <= getCenterY(begin); y++) { world[getCenterX(end)][y] = Tileset.FLOOR; if (world[getCenterX(end) - 1][y] != Tileset.FLOOR) { world[getCenterX(end) - 1][y] = Tileset.WALL; } if (world[getCenterX(end) + 1][y] != Tileset.FLOOR) { world[getCenterX(end) + 1][y] = Tileset.WALL; } } world[getCenterX(end) - 1][getCenterY(begin)] = Tileset.FLOOR; if (world[getCenterX(end) + 1][getCenterY(begin) + 1] != Tileset.FLOOR) { world[getCenterX(end) + 1][getCenterY(begin) + 1] = Tileset.WALL; } if (world[getCenterX(end)][getCenterY(begin) + 1] != Tileset.FLOOR) { world[getCenterX(end)][getCenterY(begin) + 1] = Tileset.WALL; } } } else if (pathLengthX == 0 && pathLengthY != 0) { for (int y = getCenterY(end) + end.getHeight() / 2; y <= getCenterY(begin) - begin.getHeight() / 2; y++) { world[getCenterX(r1)][y] = Tileset.FLOOR; if (world[getCenterX(r1) - 1][y] != Tileset.FLOOR) { world[getCenterX(r1) - 1][y] = Tileset.WALL; } if (world[getCenterX(r1) + 1][y] != Tileset.FLOOR) { world[getCenterX(r1) + 1][y] = Tileset.WALL; } } } else { for (int x = getCenterX(begin) + begin.getWidth() / 2; x <= getCenterX(end) - end.getWidth() / 2; x++) { world[x][getCenterY(r2)] = Tileset.FLOOR; if (world[x][getCenterY(r2) - 1] != Tileset.FLOOR) { world[x][getCenterY(r2) - 1] = Tileset.WALL; } if (world[x][getCenterY(r2) + 1] != Tileset.FLOOR) { world[x][getCenterY(r2) + 1] = Tileset.WALL; } } } } private void markSecondTileForWorld(Room begin, Room end) { for (int y = getCenterY(begin); y <= getCenterY(end) - end.getHeight() / 2; y++) { world[getCenterX(end)][y] = Tileset.FLOOR; if (world[getCenterX(end) - 1][y] != Tileset.FLOOR) { world[getCenterX(end) - 1][y] = Tileset.WALL; } if (world[getCenterX(end) + 1][y] != Tileset.FLOOR) { world[getCenterX(end) + 1][y] = Tileset.WALL; } } } private void markTileForWorld(Room begin, Room end) { for (int x = getCenterX(begin) + begin.getWidth() / 2; x < getCenterX(end); x++) { world[x][getCenterY(begin)] = Tileset.FLOOR; if (world[x][getCenterY(begin) - 1] != Tileset.FLOOR) { world[x][getCenterY(begin) - 1] = Tileset.WALL; } if (world[x][getCenterY(begin) + 1] != Tileset.FLOOR) { world[x][getCenterY(begin) + 1] = Tileset.WALL; } } } private boolean roomsAreInProximity(Room r1, Room r2) { int r1CenterX = getCenterX(r1); int r1CenterY = getCenterY(r1); int r2CenterX = getCenterX(r2); int r2CenterY = getCenterY(r2); // @Source CK-12 distance between 2 points formula double shortestDistance = Math.sqrt(Math.pow(r2CenterX - r1CenterX, 2) + Math.pow(r2CenterY - r1CenterY, 2)); return (shortestDistance < (DEFAULT_WIDTH / 6)); } private int getCenterX(Room r) { return r.getBottomLeft().getxPos() + (Math.floorDiv(r.getWidth(), 2)); } private int getCenterY(Room r) { return r.getBottomLeft().getyPos() + (Math.floorDiv(r.getHeight(), 2)); } private double emptyTilesCount() { double emptyTiles = 0; double totalTiles = 0; for (int i = 0; i < DEFAULT_WIDTH; i++) { for (int j = 0; j < DEFAULT_HEIGHT; j++) { totalTiles++; if (world[i][j] == Tileset.NOTHING) { emptyTiles++; } } } return emptyTiles / totalTiles; } private void clearWorld() { for (int i = 0; i < DEFAULT_WIDTH; i++) { for (int j = 0; j < DEFAULT_HEIGHT; j++) { world[i][j] = Tileset.NOTHING; } } } private ArrayList findBegin(Room r1, Room r2) { ArrayList outputRooms = new ArrayList<>(); Room begin; Room end; if (getCenterX(r1) < getCenterX(r2)) { begin = r1; end = r2; } else if (getCenterX(r1) > getCenterX(r2)) { begin = r2; end = r1; } else { if (getCenterY(r1) < getCenterY(r2)) { begin = r1; end = r2; } else { begin = r2; end = r1; } } outputRooms.add(begin); outputRooms.add(end); return outputRooms; } private void spawnAvatar() { int x = random.nextInt(DEFAULT_WIDTH - 1); countsOfRandom++; int y = random.nextInt(DEFAULT_HEIGHT - 1); countsOfRandom++; while (world[x][y] != Tileset.FLOOR) { x = random.nextInt(DEFAULT_WIDTH - 1); countsOfRandom++; y = random.nextInt(DEFAULT_HEIGHT - 1); countsOfRandom++; } xAvatar = x; yAvatar = y; world[x][y] = Tileset.AVATAR; ter.renderFrame(world); } private void avatarDisplayer(Menu menu) { while (true) { hud(); while (!StdDraw.hasNextKeyTyped()) { hud(); } char c = menu.getNextKey(); char capitalizedC = Character.toUpperCase(c); if (capitalizedC == 'W') { moveForward(); } if (capitalizedC == 'A') { moveLeft(); } if (capitalizedC == 'S') { moveBack(); } if (capitalizedC == 'D') { moveRight(); } if (capitalizedC == ':') { c = menu.getNextKey(); capitalizedC = Character.toUpperCase(c); if (capitalizedC == 'Q') { saveWorld(); System.exit(0); } else { if (capitalizedC == 'W') { moveForward(); } if (capitalizedC == 'A') { moveLeft(); } if (capitalizedC == 'S') { moveBack(); } if (capitalizedC == 'D') { moveRight(); } } } } } private void saveWorld() { savedWorld = new File("save.txt"); try { FileWriter fw = new FileWriter(savedWorld); BufferedWriter bw = new BufferedWriter(fw); bw.write(String.valueOf(realSeed)); bw.write("\n"); // 0 = WALL, 1 = FLOOR, 2 = AVATAR for (int y = DEFAULT_HEIGHT - 1; y >= 0; y--) { StringBuilder line = getStringBuilder(y); bw.write(String.valueOf(line)); bw.write("\n"); } bw.close(); } catch (IOException e) { throw new RuntimeException(e); } } private StringBuilder getStringBuilder(int y) { StringBuilder line = new StringBuilder(); for (int x = 0; x < DEFAULT_WIDTH; x++) { if (world[x][y] == Tileset.WALL) { line.append("0"); } else if (world[x][y] == Tileset.FLOOR) { line.append("1"); } else if (world[x][y] == Tileset.AVATAR) { line.append("2"); } else { line.append("3"); } } return line; } private void loadWorld() { File worldFile = new File("save.txt"); if (worldFile.exists()) { try { ter.initialize(DEFAULT_WIDTH, DEFAULT_HEIGHT); FileReader fr = new FileReader(worldFile); BufferedReader br = new BufferedReader(fr); realSeed = Long.parseLong(br.readLine()); random = new Random(realSeed); for (int i = 0; i <= countsOfRandom; i++) { random.nextInt(); } int aX = 0; int aY = 0; for (int j = DEFAULT_HEIGHT - 1; j >= 0; j--) { String line = br.readLine(); for (int i = 0; i < line.length(); i++) { if (line.charAt(i) == '0') { world[i][j] = Tileset.WALL; } else if (line.charAt(i) == '1') { world[i][j] = Tileset.FLOOR; } else if (line.charAt(i) == '2') { world[i][j] = Tileset.AVATAR; aX = i; aY = j; } else { world[i][j] = Tileset.NOTHING; } } } xAvatar = aX; yAvatar = aY; ter.renderFrame(world); } catch (IOException e) { throw new RuntimeException(e); } } else { System.exit(0); } } private void moveForward() { if (world[xAvatar][yAvatar + 1] == Tileset.FLOOR) { countMovements++; world[xAvatar][yAvatar + 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar++; ter.renderFrame(world); if (countMovements % (5 * 2) == 0) { playSound(); } } } private void moveLeft() { if (world[xAvatar - 1][yAvatar] == Tileset.FLOOR) { countMovements++; world[xAvatar - 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar--; ter.renderFrame(world); if (countMovements % (5 * 2) == 0) { playSound(); } } } private void moveBack() { if (world[xAvatar][yAvatar - 1] == Tileset.FLOOR) { countMovements++; world[xAvatar][yAvatar - 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar--; ter.renderFrame(world); if (countMovements % (5 * 2) == 0) { playSound(); } } } private void moveRight() { if (world[xAvatar + 1][yAvatar] == Tileset.FLOOR) { countMovements++; world[xAvatar + 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar++; ter.renderFrame(world); if (countMovements % (5 * 2) == 0) { playSound(); } } } private void hud() { int mouseX = (int) StdDraw.mouseX(); int mouseY = (int) StdDraw.mouseY(); StdDraw.setPenColor(StdDraw.BLACK); StdDraw.filledRectangle(2, DEFAULT_HEIGHT - 1, 3, 1); StdDraw.setPenColor(Color.WHITE); if (mouseY < DEFAULT_HEIGHT - 1) { StdDraw.text(2, DEFAULT_HEIGHT - 1, world[mouseX][mouseY].description()); } else { StdDraw.text(3, DEFAULT_HEIGHT - 1, "nothing"); } StdDraw.show(); } public static void playSound() { try { File soundPath = new File("/Users/ayush/Desktop/cs61b/sp24-proj3-g121/proj3/src/core/hog-rider.wav"); AudioInputStream audioInput = AudioSystem.getAudioInputStream(soundPath); Clip clip = AudioSystem.getClip(); clip.open(audioInput); clip.start(); } catch (UnsupportedAudioFileException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (LineUnavailableException e) { throw new RuntimeException(e); } } private void moveForwardMG() { if (world[xAvatar][yAvatar + 1] == Tileset.FLOOR) { world[xAvatar][yAvatar + 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar++; ter.renderFrame(world); } else if (world[xAvatar][yAvatar + 1] == Tileset.FLOWER) { world[xAvatar][yAvatar + 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar++; flowerCount--; ter.renderFrame(world); if (flowerCount <= 0) { miniGameOver(); } } } private void moveLeftMG() { if (world[xAvatar - 1][yAvatar] == Tileset.FLOOR) { world[xAvatar - 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar--; ter.renderFrame(world); } else if (world[xAvatar - 1][yAvatar] == Tileset.FLOWER) { world[xAvatar - 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar--; flowerCount--; ter.renderFrame(world); if (flowerCount <= 0) { miniGameOver(); } } } private void moveBackMG() { if (world[xAvatar][yAvatar - 1] == Tileset.FLOOR) { world[xAvatar][yAvatar - 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar--; ter.renderFrame(world); } else if (world[xAvatar][yAvatar - 1] == Tileset.FLOWER) { world[xAvatar][yAvatar - 1] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; yAvatar--; flowerCount--; ter.renderFrame(world); if (flowerCount <= 0) { miniGameOver(); } } } private void moveRightMG() { if (world[xAvatar + 1][yAvatar] == Tileset.FLOOR) { world[xAvatar + 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar++; ter.renderFrame(world); } else if (world[xAvatar + 1][yAvatar] == Tileset.FLOWER) { world[xAvatar + 1][yAvatar] = Tileset.AVATAR; world[xAvatar][yAvatar] = Tileset.FLOOR; xAvatar++; flowerCount--; ter.renderFrame(world); if (flowerCount <= 0) { miniGameOver(); } } } private void miniGameOver() { JOptionPane.showMessageDialog(null, "You Win!"); StdDraw.pause((5 * 2) * (5 * 2) * (5 * 2)); System.exit(0); } }