Instantly share code, notes, and snippets.
Last active
December 26, 2021 09:01
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save BertGarretsen/3b8f68ccfa49c24e0815dd149a10b2b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package /*your-package*/; | |
| import lombok.Getter; | |
| import lombok.NoArgsConstructor; | |
| import lombok.ToString; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Collection; | |
| import java.util.List; | |
| @ToString | |
| public class MenuWalker { | |
| @Getter | |
| private final Position position; | |
| private final int invRows; | |
| int[][] matrix; | |
| @Getter | |
| private final List<Instruction> instructions; | |
| /** | |
| * Create a new MenuWalker | |
| * | |
| * @param start the start position of the walker | |
| * @param rows the amount of rows the inventory has | |
| */ | |
| public MenuWalker(Position start, int rows) { | |
| this.position = start; | |
| this.invRows = rows; | |
| this.instructions = new ArrayList<>(); | |
| this.matrix = new int[rows][9]; | |
| this.populateMatrix(); | |
| } | |
| /** | |
| * Populates the matrix with the correct inventory slots. | |
| */ | |
| private void populateMatrix() { | |
| int slot = 0; | |
| // Looping through inv rows | |
| for (int i = 0; i < invRows; i++) { | |
| // Looping through all rows in this inventory | |
| for (int j = 0; j < 9; j++) { | |
| matrix[i][j] = slot; | |
| slot++; | |
| } | |
| } | |
| } | |
| /** | |
| * Add a collection of {@link Instruction} to the MenuWalker | |
| * | |
| * @param instructions the instructions | |
| */ | |
| public MenuWalker instruct(Collection<Instruction> instructions) { | |
| for (Instruction instruction : instructions) { | |
| instruct(instruction); | |
| } | |
| return this; | |
| } | |
| /** | |
| * Add an array of {@link Instruction} to the MenuWalker | |
| * | |
| * @param instructions the instructions | |
| */ | |
| public MenuWalker instruct(Instruction[] instructions) { | |
| for (Instruction instruction : instructions) { | |
| instruct(instruction); | |
| } | |
| return this; | |
| } | |
| /** | |
| * Add a single {@link Instruction} without having to create the {@link Instruction} object yourself. | |
| * | |
| * @param direction direction of travel | |
| * @param distance distance to travel | |
| */ | |
| public MenuWalker instruct(Direction direction, int distance) { | |
| return instruct(new Instruction(direction, distance)); | |
| } | |
| /** | |
| * Add a single {@link Instruction} to the MenuWalker | |
| * | |
| * @param instruction | |
| * @return | |
| */ | |
| public MenuWalker instruct(Instruction instruction) { | |
| this.instructions.add(instruction); | |
| return this; | |
| } | |
| /** | |
| * Performs all instructions saved in the instruction list | |
| * | |
| * @return a list of slots the walker took using the directions | |
| */ | |
| public final List<Integer> compilePath() { | |
| List<Integer> path = new ArrayList<>(); | |
| for (Instruction instruction : this.instructions) { | |
| for (int i = 0; i < instruction.distance; i++) { | |
| path.add(this.position.getSlot(matrix)); | |
| this.position.move(instruction.direction); | |
| } | |
| } | |
| path.add(this.position.getSlot(matrix)); | |
| return path; | |
| } | |
| /** | |
| * Utility method for debugging | |
| */ | |
| public void printData() { | |
| System.out.println("Position: " + this.position); | |
| System.out.println("Instructions:"); | |
| int count = 1; | |
| for (Instruction instruction : this.instructions) { | |
| System.out.println(count++ + ". " + instruction.toString()); | |
| } | |
| System.out.println("End of instructions"); | |
| System.out.println("Matrix:"); | |
| for (int[] ints : this.matrix) { | |
| System.out.println(Arrays.toString(ints)); | |
| } | |
| } | |
| /** | |
| * Represents a direction for the {@link MenuWalker} to take | |
| */ | |
| public enum Direction { | |
| LEFT(0, -1), | |
| RIGHT(0, 1), | |
| UP(-1, 0), | |
| DOWN(1, 0); | |
| int moveX, moveY; | |
| /** | |
| * @param moveX the x direction | |
| * @param moveY the y direction | |
| */ | |
| Direction(int moveX, int moveY) { | |
| this.moveX = moveX; | |
| this.moveY = moveY; | |
| } | |
| } | |
| /** | |
| * Represents an Instruction for the {@link MenuWalker} to take | |
| */ | |
| @ToString | |
| public static class Instruction { | |
| private final Direction direction; | |
| private int distance; | |
| /** | |
| * @param direction the {@link Direction} for the {@link MenuWalker} to take | |
| * @param distance the distance to travel in the given {@link Direction} | |
| */ | |
| public Instruction(Direction direction, int distance) { | |
| this.direction = direction; | |
| this.distance = distance; | |
| } | |
| /** | |
| * Creates an {@link Instruction} with the distance of 1 in the given {@link Direction} | |
| * | |
| * @param direction | |
| */ | |
| public Instruction(Direction direction) { | |
| this.direction = direction; | |
| this.distance = 1; | |
| } | |
| /** | |
| * Create a list of instructions from key-value pairs like you would see in PHP: | |
| * <p> | |
| * array( | |
| * Direction => Distance, | |
| * Direction => Distance, | |
| * ) | |
| * <p> | |
| * Except now you just use commas instead of => | |
| * | |
| * @param array key-value array | |
| * @return a list of instructions | |
| * @throws RuntimeException if there is a problem with your array | |
| */ | |
| public static List<Instruction> ofArray(Object... array) { | |
| List<Instruction> output = new ArrayList<>(); | |
| Instruction current = null; | |
| for (int i = 0; i < array.length; i++) { | |
| Object obj = array[i]; | |
| if (i % 2 == 0) { | |
| if (!(obj instanceof Direction)) | |
| throw new RuntimeException("No Direction object found at index " + i); | |
| current = new Instruction((Direction) obj); | |
| } else { | |
| if (current == null) throw new RuntimeException("Could not parse array!"); | |
| if (!(obj instanceof Integer)) throw new RuntimeException("No Integer found at index " + i); | |
| current.distance = (int) obj; | |
| output.add(current); | |
| current = null; | |
| } | |
| } | |
| return output; | |
| } | |
| } | |
| /** | |
| * Represents the {@link MenuWalker}'s position in the matrix | |
| */ | |
| @NoArgsConstructor | |
| public static class Position { | |
| @Getter | |
| int x, y; | |
| /** | |
| * | |
| * Create a new position at the given coordinates | |
| * | |
| * @param x horizontal coordinate | |
| * @param y vertical coordinate | |
| */ | |
| public Position(int x, int y) { | |
| this.x = x; | |
| this.y = y; | |
| } | |
| /** | |
| * @param matrix the inventory matrix | |
| * @return the slot at the location of the given matrix | |
| */ | |
| public int getSlot(int[][] matrix) { | |
| int slot = 0; | |
| try { | |
| slot = matrix[x][y]; | |
| } catch (ArrayIndexOutOfBoundsException e) { | |
| throw new RuntimeException("MenuWalker is out of bounds!"); | |
| } | |
| return slot; | |
| } | |
| /** | |
| * | |
| * Moves the position in the given direction | |
| * | |
| * @param dir the direction to move in | |
| */ | |
| public void move(Direction dir) { | |
| this.x += dir.moveX; | |
| this.y += dir.moveY; | |
| } | |
| /** | |
| * | |
| * Moves the position toward the given x, y | |
| * | |
| * @param x the horizontal travel distance | |
| * @param y the vertical travel distance | |
| */ | |
| public void move(int x, int y) { | |
| this.x += x; | |
| this.y += y; | |
| } | |
| /** | |
| * | |
| * Moves the position on the horizontal axis | |
| * | |
| * @param x the horizontal travel distance | |
| */ | |
| public void moveX(int x) { | |
| this.x += x; | |
| } | |
| /** | |
| * | |
| * Moves the position on the vertical axis | |
| * | |
| * @param y the vertical travel distance | |
| */ | |
| public void moveY(int y) { | |
| this.y += y; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment