summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/misc/Direction.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java/bjc/utils/misc/Direction.java')
-rw-r--r--base/src/main/java/bjc/utils/misc/Direction.java221
1 files changed, 221 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/misc/Direction.java b/base/src/main/java/bjc/utils/misc/Direction.java
new file mode 100644
index 0000000..4833f14
--- /dev/null
+++ b/base/src/main/java/bjc/utils/misc/Direction.java
@@ -0,0 +1,221 @@
+package bjc.utils.misc;
+
+import java.util.Random;
+import java.util.function.Consumer;
+
+import bjc.utils.exceptions.InvalidDirectionException;
+import bjc.utils.funcdata.FunctionalList;
+import bjc.utils.funcdata.IList;
+
+import org.apache.commons.lang3.text.WordUtils;
+
+/**
+ * A set of cardinal directions
+ *
+ * The particular axis assigned to the coordinates are based off of x being
+ * the bottom left axis on a conventional 3D plot
+ *
+ * @author ben
+ *
+ */
+public enum Direction {
+ /**
+ * Negative z-axis
+ */
+ DOWN,
+ /**
+ * Positive y-axis
+ */
+ EAST,
+ /**
+ * Positive x-axis
+ */
+ NORTH,
+ /**
+ * Negative x-axis
+ */
+ SOUTH,
+ /**
+ * Positive z-axis
+ */
+ UP,
+ /**
+ * Negative y-axis
+ */
+ WEST;
+
+ /**
+ * The source of randomness for picking random directions
+ */
+ private static final Random RNG = new Random();
+
+ /**
+ * Get a list of all the cardinal directions
+ *
+ * @return A list of all the cardinal directions
+ */
+ public static IList<Direction> cardinals() {
+ return new FunctionalList<>(NORTH, SOUTH, EAST, WEST);
+ }
+
+ /**
+ * Perform the specified action once with each of the cardinal
+ * directions
+ *
+ * @param act
+ * The action to perform for each cardinal direction
+ */
+ public static void forCardinalDirections(Consumer<Direction> act) {
+ cardinals().forEach(act);
+ }
+
+ /**
+ * Perform a specified action for a random number of cardinals.
+ *
+ * @param nCardinals
+ * The number of cardinal directions to act on. Must be
+ * greater than 0 and less then 5
+ * @param act
+ * The action to perform for each of the cardinals
+ */
+ public static void forRandomCardinals(int nCardinals,
+ Consumer<Direction> act) {
+ if (nCardinals <= 0 || nCardinals > 4) {
+ throw new IllegalArgumentException(
+ "Tried to do things with incorrect number of cardinal directions. Tried with "
+ + nCardinals);
+ }
+
+ IList<Direction> cards = cardinals();
+
+ for (int i = 0; i <= 4 - nCardinals; i++) {
+ Direction rDir = cards.randItem(RNG::nextInt);
+
+ cards.removeMatching(rDir);
+ }
+
+ cards.forEach(act);
+ }
+
+ /**
+ * Create a value of the enumeration from a string
+ *
+ * @param value
+ * The string to turn into a value
+ * @return The direction corresponding to the given value
+ */
+ public static Direction properValueOf(String value) {
+ return valueOf(value.toUpperCase());
+ }
+
+ /**
+ * Test if this direction is a cardinal direction
+ *
+ * @return If the direction is cardinal or not
+ */
+ public boolean isCardinal() {
+ switch (this) {
+ case EAST:
+ case NORTH:
+ case SOUTH:
+ case WEST:
+ return true;
+ case DOWN:
+ case UP:
+ return false;
+ default:
+ throw new InvalidDirectionException(
+ "WAT. Somehow ended up with an invalid direction "
+ + this);
+ }
+ }
+
+ /**
+ * Get the direction that opposes the current one
+ *
+ * @return The direction that is in the opposite direction of the
+ * current one
+ */
+ public Direction opposing() {
+ switch (this) {
+ case NORTH:
+ return SOUTH;
+ case EAST:
+ return WEST;
+ case SOUTH:
+ return NORTH;
+ case WEST:
+ return WEST;
+ case UP:
+ return DOWN;
+ case DOWN:
+ return UP;
+ default:
+ throw new IllegalStateException(
+ "Enumeration got into a invalid state. WAT");
+ }
+ }
+
+ /**
+ * Get the direction that is clockwise on the compass from this one.
+ *
+ * Only works on cardinals.
+ *
+ * @return The cardinal clockwise from this one
+ */
+ public Direction rotateClockwise() {
+ switch (this) {
+ case NORTH:
+ return EAST;
+ case EAST:
+ return SOUTH;
+ case SOUTH:
+ return WEST;
+ case WEST:
+ return NORTH;
+ case UP:
+ case DOWN:
+ default:
+ throw new InvalidDirectionException(
+ "Can't rotate non-cardinal direction clockwise: "
+ + this);
+
+ }
+ }
+
+ /**
+ * Get the direction that is counter-clockwise on the compass from this
+ * one.
+ *
+ * Only works on cardinals.
+ *
+ * @return The cardinal counter-clockwise from this one
+ */
+ public Direction rotateCounterClockwise() {
+ switch (this) {
+ case NORTH:
+ return WEST;
+ case EAST:
+ return NORTH;
+ case SOUTH:
+ return EAST;
+ case WEST:
+ return SOUTH;
+ case UP:
+ case DOWN:
+ default:
+ throw new InvalidDirectionException(
+ "Can't rotate non-cardinal direction counterclockwise: "
+ + this);
+
+ }
+ }
+
+ @Override
+ public String toString() {
+ /*
+ * Make sure the word is properly capitalized for english
+ */
+ return WordUtils.capitalize(super.toString().toLowerCase());
+ }
+}