Skip to content

Instantly share code, notes, and snippets.

@BertGarretsen
Last active December 26, 2021 09:01
Show Gist options
  • Select an option

  • Save BertGarretsen/3b8f68ccfa49c24e0815dd149a10b2b4 to your computer and use it in GitHub Desktop.

Select an option

Save BertGarretsen/3b8f68ccfa49c24e0815dd149a10b2b4 to your computer and use it in GitHub Desktop.
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