From 488840ca6d7e5161bcda9c457d5d4eb48306ca76 Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Mon, 20 Feb 2023 12:08:07 -0600 Subject: [PATCH 1/7] Starting the transition process --- .../switches/ColoredSwitchGraphFactory.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java index 6966789d..95fbdd9b 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java @@ -6,6 +6,7 @@ import org.jgrapht.Graph; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleDirectedGraph; +import org.jgrapht.graph.SimpleDirectedWeightedGraph; import java.io.IOException; import java.io.InputStream; @@ -51,6 +52,27 @@ private static Graph buildGraph(List makeGraph2(@NotNull SwitchColor[] startingColors) + throws IllegalStateException { + return buildGraph2(createFromFile(), startingColors); + } + + private static Graph buildGraph2(List nodeList, + SwitchColor[] startingColors) { + Graph output = new SimpleDirectedWeightedGraph<>(DefaultEdge.class); + + for (ColoredSwitchNode node : nodeList) + output.addVertex(node); + + for (ColoredSwitchNode node : nodeList) { + for (byte connection : node.getOutgoingConnections()) { + output.addEdge(node, nodeList.get(connection)); + } + } + + return output; + } + private static ColoredSwitchNode buildNode(String[] record, Regex connectionFinder) { ColoredSwitchNode node = new ColoredSwitchNode(Byte.parseByte(record[0])); From d74cf012964929c023ab2ee7a229bc84da4390e9 Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:02:42 -0600 Subject: [PATCH 2/7] This is theoretically correct No manual or automatic testing has occurred yet --- .../switches/ColoredSwitchGraphFactory.java | 36 +++++++++++++------ .../c/colored/switches/ColoredSwitchNode.java | 7 ++-- .../c/colored/switches/ColoredSwitches.java | 24 +++++++------ 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java index 95fbdd9b..967e27bc 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java @@ -6,15 +6,17 @@ import org.jgrapht.Graph; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleDirectedGraph; -import org.jgrapht.graph.SimpleDirectedWeightedGraph; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; +import static bomb.modules.c.colored.switches.ColoredSwitches.canFollowPath; + @SuppressWarnings("ConstantConditions") public class ColoredSwitchGraphFactory { private static final byte OUTGOING_STATE = 1, COLOR_CONDITIONS = 2, SWITCH_TO_FLIP = 3; @@ -52,25 +54,35 @@ private static Graph buildGraph(List makeGraph2(@NotNull SwitchColor[] startingColors) + public static @NotNull Graph makeGraphFromSwitchColors(@NotNull SwitchColor[] startingColors) throws IllegalStateException { return buildGraph2(createFromFile(), startingColors); } private static Graph buildGraph2(List nodeList, SwitchColor[] startingColors) { - Graph output = new SimpleDirectedWeightedGraph<>(DefaultEdge.class); + Graph createdGraph = new SimpleDirectedGraph<>(DefaultEdge.class); - for (ColoredSwitchNode node : nodeList) - output.addVertex(node); + nodeList.forEach(createdGraph::addVertex); for (ColoredSwitchNode node : nodeList) { for (byte connection : node.getOutgoingConnections()) { - output.addEdge(node, nodeList.get(connection)); + if (isPlausibleEdge(startingColors, node, connection)) { + createdGraph.addEdge(node, nodeList.get(connection)); + } } } - return output; + return createdGraph; + } + + private static boolean isPlausibleEdge(SwitchColor[] startingColors, ColoredSwitchNode node, + int connectionValue) { + SwitchColor switchColor = startingColors[connectionValue]; + var edges = node.getEdgeData((byte) connectionValue) + .getValue0(); + + return canFollowPath(edges, switchColor); } private static ColoredSwitchNode buildNode(String[] record, Regex connectionFinder) { @@ -82,7 +94,7 @@ private static ColoredSwitchNode buildNode(String[] record, Regex connectionFind connectionFinder.hasMatch(); byte outgoingConnection = Byte.parseByte(connectionFinder.captureGroup(OUTGOING_STATE)); - SwitchColor[] colorConditions = createConditions(connectionFinder.captureGroup(COLOR_CONDITIONS)); + EnumSet colorConditions = createConditions(connectionFinder.captureGroup(COLOR_CONDITIONS)); byte switchToFlip = Byte.parseByte(connectionFinder.captureGroup(SWITCH_TO_FLIP)); node.addConnection(outgoingConnection, colorConditions, switchToFlip); @@ -91,10 +103,12 @@ private static ColoredSwitchNode buildNode(String[] record, Regex connectionFind return node; } - private static SwitchColor[] createConditions(String ordinals) { - return Arrays.stream(ordinals.split("")) + private static EnumSet createConditions(String ordinals) { + return EnumSet.copyOf( + Arrays.stream(ordinals.split("")) .mapToInt(Integer::parseInt) .mapToObj(SwitchColor::getByIndex) - .toArray(SwitchColor[]::new); + .toList() + ); } } diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchNode.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchNode.java index 6d13df6f..970c8adf 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchNode.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchNode.java @@ -2,6 +2,7 @@ import org.javatuples.Pair; +import java.util.EnumSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -10,7 +11,7 @@ public class ColoredSwitchNode { private static final int SIZE_LIMIT = 3; private final byte state; - private final Map> outgoingConnections; + private final Map, Byte>> outgoingConnections; public ColoredSwitchNode(byte state) { this.state = state; @@ -21,7 +22,7 @@ public byte getState() { return state; } - public void addConnection(byte outgoingState, SwitchColor[] colorRestrictions, byte switchToFlip) { + public void addConnection(byte outgoingState, EnumSet colorRestrictions, byte switchToFlip) { outgoingConnections.put(outgoingState, new Pair<>(colorRestrictions, switchToFlip)); } @@ -29,7 +30,7 @@ public Set getOutgoingConnections() { return outgoingConnections.keySet(); } - public Pair getEdgeData(byte targetState) { + public Pair, Byte> getEdgeData(byte targetState) { return outgoingConnections.get(targetState); } diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java index a3d371f2..9c6565bb 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java @@ -10,6 +10,7 @@ import org.jgrapht.graph.DefaultEdge; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import java.util.function.BiFunction; @@ -44,7 +45,7 @@ private static byte makePreemptiveMove(byte currentState, List outputLis ColoredSwitchNode currentNode = getNodeByState(currentState); for (Byte connection : currentNode.getOutgoingConnections()) { - Pair edgeData = currentNode.getEdgeData(connection); + Pair, Byte> edgeData = currentNode.getEdgeData(connection); if (isBlackPath(edgeData.getValue0())) { outputList.add(String.valueOf(edgeData.getValue1())); @@ -90,21 +91,22 @@ private static List createSwitchToFlipList(List path) List output = new ArrayList<>(); for (int i = 0; i < path.size() - 1; i++) { - Pair edgeData = path.get(i).getEdgeData(path.get(i + 1).getState()); + Pair, Byte> edgeData = path.get(i).getEdgeData(path.get(i + 1).getState()); output.add(String.valueOf(edgeData.getValue1())); } return output; } - private static boolean canFollowPath(SwitchColor[] connectionConditions, SwitchColor switchColor) { + static boolean canFollowPath(EnumSet connectionConditions, SwitchColor switchColor) { if (isBlackPath(connectionConditions)) return true; - for (SwitchColor possibleConnection : connectionConditions) { - if (switchColor == possibleConnection) - return true; - } - return false; + return connectionConditions.contains(switchColor); +// for (SwitchColor possibleConnection : connectionConditions) { +// if (switchColor == possibleConnection) +// return true; +// } +// return false; } private static void validateSwitchColors(SwitchColor[] startingColors) { @@ -114,8 +116,8 @@ private static void validateSwitchColors(SwitchColor[] startingColors) { } } - private static boolean isBlackPath(SwitchColor[] connectionConditions) { - return connectionConditions.length == 1 && connectionConditions[0] == NEUTRAL; + private static boolean isBlackPath(EnumSet connectionConditions) { + return connectionConditions.size() == 1 && connectionConditions.contains(NEUTRAL); } private static void validateByte(byte state) throws IllegalArgumentException { @@ -139,7 +141,7 @@ public static void reset() { //Weight from target to desired state double hX = Math.abs(desiredState - targetVertex.getState()); - Pair edgeData = sourceVertex.getEdgeData(targetVertex.getState()); + Pair, Byte> edgeData = sourceVertex.getEdgeData(targetVertex.getState()); if (edgeData == null) return WRONG_PATH_VALUE; SwitchColor switchToFlip = startingColors[edgeData.getValue1()]; From f9709a97c21f2f5f939e036e9ce9bcabb57dbc87 Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Mon, 20 Feb 2023 13:11:36 -0600 Subject: [PATCH 3/7] Created a preemptive graph that only checks for black moves Maybe, it'll work, don't know, I'll test later --- .../java/bomb/modules/c/colored/switches/ColoredSwitches.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java index 9c6565bb..6a06c709 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java @@ -20,6 +20,7 @@ public final class ColoredSwitches extends Switches { private static final double WRONG_PATH_VALUE; private static final Graph INTERNAL_GRAPH; + private static final Graph PREEMPTIVE_MOVE_GRAPH; private static final BiFunction> HEURISTIC_FUNCTION; private static byte secondaryStartLocation = -1; @@ -27,6 +28,8 @@ public final class ColoredSwitches extends Switches { static { WRONG_PATH_VALUE = Double.MAX_VALUE; INTERNAL_GRAPH = ColoredSwitchGraphFactory.makeGraph(); + PREEMPTIVE_MOVE_GRAPH = ColoredSwitchGraphFactory + .makeGraphFromSwitchColors(new SwitchColor[]{NEUTRAL, NEUTRAL, NEUTRAL, NEUTRAL, NEUTRAL}); } public static @NotNull List producePreemptiveMoveList(byte startingState) throws IllegalArgumentException { From f5007db08bbb8c3302d2fa07110c2a807ef4c64a Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:02:31 -0600 Subject: [PATCH 4/7] Changed the underlying algorithm from A* to Dijkstra's Might create more tests, but this is looking good so far --- Progress.md | 2 +- .../switches/ColoredSwitchGraphFactory.java | 62 ++++------ .../c/colored/switches/ColoredSwitches.java | 117 +++++++----------- .../colored/switches/ColoredSwitchesTest.java | 29 +++++ 4 files changed, 96 insertions(+), 114 deletions(-) diff --git a/Progress.md b/Progress.md index 7046b1f6..d9bec77b 100644 --- a/Progress.md +++ b/Progress.md @@ -8,7 +8,7 @@ - Boolean Venn Diagram - Chess - Chord Qualities -- Colored Switches (Not technically part of the bomb, but was a fun ~~recursion~~ graph problem using A*) +- Colored Switches (Not technically part of the bomb, but was a fun ~~recursion~~ graph problem using ~~A*~~ Dijkstra's) - Emoji Math - Fast Math - Forget Me Not diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java index 967e27bc..b10d180e 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitchGraphFactory.java @@ -22,52 +22,33 @@ public class ColoredSwitchGraphFactory { private static final byte OUTGOING_STATE = 1, COLOR_CONDITIONS = 2, SWITCH_TO_FLIP = 3; private static final String FILENAME = "graph.csv"; - public static @NotNull Graph makeGraph() throws IllegalStateException { - return buildGraph(createFromFile()); - } - - private static List createFromFile() throws IllegalStateException { + static List createFromFile() throws IllegalStateException { List output = new ArrayList<>(32); - Regex connectionFinder = new Regex("\\[(\\d{1,2})\\((\\d{1,3})\\)([1-5])]"); + Regex connectionRegex = new Regex("\\[(\\d{1,2})\\((\\d{1,3})\\)([1-5])]"); InputStream in = ColoredSwitchGraphFactory.class.getResourceAsStream(FILENAME); try (CSVReader csvReader = new CSVReader(new InputStreamReader(in))) { - csvReader.forEach(record -> output.add(buildNode(record, connectionFinder))); + csvReader.forEach(record -> output.add(buildNode(record, connectionRegex))); return output; } catch (IOException e) { throw new IllegalStateException(e); } } - private static Graph buildGraph(List nodeList) { - Graph output = new SimpleDirectedGraph<>(DefaultEdge.class); - - for (ColoredSwitchNode node : nodeList) - output.addVertex(node); - - for (ColoredSwitchNode node : nodeList) { - for (byte connection : node.getOutgoingConnections()) { - output.addEdge(node, nodeList.get(connection)); - } - } - - return output; - } - - public static @NotNull Graph makeGraphFromSwitchColors(@NotNull SwitchColor[] startingColors) - throws IllegalStateException { - return buildGraph2(createFromFile(), startingColors); + static @NotNull Graph makeGraphFromSwitchColors( + @NotNull SwitchColor[] startingColors) throws IllegalStateException { + return buildGraph(createFromFile(), startingColors); } - private static Graph buildGraph2(List nodeList, - SwitchColor[] startingColors) { + private static Graph buildGraph(List nodeList, + SwitchColor[] startingSwitchColors) { Graph createdGraph = new SimpleDirectedGraph<>(DefaultEdge.class); nodeList.forEach(createdGraph::addVertex); for (ColoredSwitchNode node : nodeList) { for (byte connection : node.getOutgoingConnections()) { - if (isPlausibleEdge(startingColors, node, connection)) { + if (isTraversableEdge(startingSwitchColors, node, nodeList.get(connection))) { createdGraph.addEdge(node, nodeList.get(connection)); } } @@ -76,28 +57,27 @@ private static Graph buildGraph2(List colorConditions = createConditions(connectionFinder.captureGroup(COLOR_CONDITIONS)); - byte switchToFlip = Byte.parseByte(connectionFinder.captureGroup(SWITCH_TO_FLIP)); + byte outgoingConnection = Byte.parseByte(connectionRegex.captureGroup(OUTGOING_STATE)); + EnumSet edgeColors = createConditions(connectionRegex.captureGroup(COLOR_CONDITIONS)); + byte switchToFlip = Byte.parseByte(connectionRegex.captureGroup(SWITCH_TO_FLIP)); - node.addConnection(outgoingConnection, colorConditions, switchToFlip); + node.addConnection(outgoingConnection, edgeColors, switchToFlip); } return node; diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java index 6a06c709..e2370e4c 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java @@ -4,67 +4,68 @@ import bomb.modules.s.switches.Switches; import org.javatuples.Pair; import org.jetbrains.annotations.NotNull; -import org.jgrapht.Graph; -import org.jgrapht.alg.interfaces.AStarAdmissibleHeuristic; -import org.jgrapht.alg.shortestpath.AStarShortestPath; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.DefaultEdge; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import java.util.function.BiFunction; - +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static bomb.modules.c.colored.switches.ColoredSwitchGraphFactory.createFromFile; import static bomb.modules.c.colored.switches.SwitchColor.NEUTRAL; +import static java.util.function.UnaryOperator.identity; @DisplayComponent(resource = "colored_switches.fxml", buttonLinkerName = "Colored Switches") public final class ColoredSwitches extends Switches { - private static final double WRONG_PATH_VALUE; - private static final Graph INTERNAL_GRAPH; - private static final Graph PREEMPTIVE_MOVE_GRAPH; - private static final BiFunction> HEURISTIC_FUNCTION; + private static final Map NUMBER_TO_STATE_MAP; private static byte secondaryStartLocation = -1; static { - WRONG_PATH_VALUE = Double.MAX_VALUE; - INTERNAL_GRAPH = ColoredSwitchGraphFactory.makeGraph(); - PREEMPTIVE_MOVE_GRAPH = ColoredSwitchGraphFactory - .makeGraphFromSwitchColors(new SwitchColor[]{NEUTRAL, NEUTRAL, NEUTRAL, NEUTRAL, NEUTRAL}); + NUMBER_TO_STATE_MAP = createFromFile() + .stream() + .collect(Collectors.toMap(ColoredSwitchNode::getState, identity())); } public static @NotNull List producePreemptiveMoveList(byte startingState) throws IllegalArgumentException { validateByte(startingState); List outputList = new ArrayList<>(); - secondaryStartLocation = makePreemptiveMove(startingState, outputList); - for (int i = 0; i < 2; i++) - secondaryStartLocation = makePreemptiveMove(secondaryStartLocation, outputList); + secondaryStartLocation = makePreemptiveMove(startingState, outputList); + secondaryStartLocation = makePreemptiveMove(secondaryStartLocation, outputList); + secondaryStartLocation = makePreemptiveMove(secondaryStartLocation, outputList); return outputList; } private static byte makePreemptiveMove(byte currentState, List outputList) throws IllegalStateException { - ColoredSwitchNode currentNode = getNodeByState(currentState); + ColoredSwitchNode currentNode = NUMBER_TO_STATE_MAP.get(currentState); - for (Byte connection : currentNode.getOutgoingConnections()) { - Pair, Byte> edgeData = currentNode.getEdgeData(connection); + Predicate filterToBlackPath = connectionState -> { + Pair, Byte> edgeData = currentNode.getEdgeData(connectionState); + return isBlackPath(edgeData.getValue0()); + }; - if (isBlackPath(edgeData.getValue0())) { - outputList.add(String.valueOf(edgeData.getValue1())); - return connection; - } - } + Consumer appendBlackPath = connectionState -> { + Pair, Byte> edgeData = currentNode.getEdgeData(connectionState); + outputList.add(String.valueOf(edgeData.getValue1())); + }; - throw new IllegalStateException("This should be an unreachable state"); - } + Optional first = currentNode.getOutgoingConnections() + .stream() + .filter(filterToBlackPath) + .findFirst(); - private static ColoredSwitchNode getNodeByState(byte startingState) throws IllegalStateException { - for (ColoredSwitchNode coloredSwitchNode : INTERNAL_GRAPH.vertexSet()) { - if (coloredSwitchNode.getState() == startingState) - return coloredSwitchNode; - } - throw new IllegalStateException(); + first.ifPresent(appendBlackPath); + + return first.orElseThrow(() -> new IllegalStateException("No black paths found")); } public static @NotNull List produceFinalMoveList(@NotNull SwitchColor[] startingColors, byte desiredState) @@ -77,39 +78,31 @@ private static ColoredSwitchNode getNodeByState(byte startingState) throws Illeg if (!isFirstStepDone()) throw new IllegalStateException("Must flip 3 switches before producing the final list"); - AStarShortestPath aStarShortestPath = new AStarShortestPath<>( - INTERNAL_GRAPH, - HEURISTIC_FUNCTION.apply(startingColors, desiredState) + DijkstraShortestPath shortestPath = new DijkstraShortestPath<>( + ColoredSwitchGraphFactory.makeGraphFromSwitchColors(startingColors) ); - ColoredSwitchNode startNode = getNodeByState(secondaryStartLocation); - ColoredSwitchNode destination = getNodeByState(desiredState); + ColoredSwitchNode startNode = NUMBER_TO_STATE_MAP.get(secondaryStartLocation); + ColoredSwitchNode destination = NUMBER_TO_STATE_MAP.get(desiredState); - List nodeList = aStarShortestPath.getPath(startNode, destination).getVertexList(); + List nodeList2 = shortestPath.getPath(startNode, destination) + .getVertexList(); - return createSwitchToFlipList(nodeList); + return createSwitchToFlipList(nodeList2); } private static List createSwitchToFlipList(List path) { - List output = new ArrayList<>(); - - for (int i = 0; i < path.size() - 1; i++) { - Pair, Byte> edgeData = path.get(i).getEdgeData(path.get(i + 1).getState()); - output.add(String.valueOf(edgeData.getValue1())); - } - - return output; + return IntStream.range(0, path.size() - 1) + .mapToObj(i -> path.get(i).getEdgeData(path.get(i + 1).getState())) + .map(Pair::getValue1) + .map(String::valueOf) + .toList(); } static boolean canFollowPath(EnumSet connectionConditions, SwitchColor switchColor) { if (isBlackPath(connectionConditions)) return true; return connectionConditions.contains(switchColor); -// for (SwitchColor possibleConnection : connectionConditions) { -// if (switchColor == possibleConnection) -// return true; -// } -// return false; } private static void validateSwitchColors(SwitchColor[] startingColors) { @@ -135,24 +128,4 @@ public static boolean isFirstStepDone() { public static void reset() { secondaryStartLocation = -1; } - - static { - HEURISTIC_FUNCTION = (startingColors, desiredState) -> - ((sourceVertex, targetVertex) -> { - //Weight from source to target - double gX = Math.abs(sourceVertex.getState() - targetVertex.getState()); - //Weight from target to desired state - double hX = Math.abs(desiredState - targetVertex.getState()); - - Pair, Byte> edgeData = sourceVertex.getEdgeData(targetVertex.getState()); - if (edgeData == null) - return WRONG_PATH_VALUE; - SwitchColor switchToFlip = startingColors[edgeData.getValue1()]; - - if (!canFollowPath(edgeData.getValue0(), switchToFlip)) - return WRONG_PATH_VALUE; - - return gX + hX; - }); - } } diff --git a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java index cb87a521..e4963cfb 100644 --- a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java +++ b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java @@ -11,6 +11,7 @@ import static bomb.modules.c.colored.switches.SwitchColor.CYAN; import static bomb.modules.c.colored.switches.SwitchColor.GREEN; import static bomb.modules.c.colored.switches.SwitchColor.NEUTRAL; +import static bomb.modules.c.colored.switches.SwitchColor.ORANGE; import static bomb.modules.c.colored.switches.SwitchColor.RED; import static org.testng.Assert.assertEquals; @@ -62,4 +63,32 @@ public void validPreemptiveMoveTest(int startingState, String[] expectedResults) assertEquals(converted, ColoredSwitches.producePreemptiveMoveList((byte) startingState)); } + + @DataProvider + public Object[][] fullMoveListTestProvider() { + return new Object[][] { + { + 28, new String[]{"5", "5", "5"}, new SwitchColor[]{GREEN, BLUE, ORANGE, RED, RED}, + 2, new String[]{"4", "3", "5", "1", "2"} + }, + { + 21, new String[]{"5", "4", "5"}, new SwitchColor[]{GREEN, RED, GREEN, BLUE, BLUE}, + 1, new String[]{"4", "5", "4", "3", "5", "4", "2", "1", "2"} + } + }; + } + + @Test(dataProvider = "fullMoveListTestProvider") + public void fullMoveListTest(int startingState, String[] preemptiveMoveList, SwitchColor[] startingColors, + int desiredState, String[] expectedShortestPath) { + assertEquals( + ColoredSwitches.producePreemptiveMoveList((byte) startingState), + Arrays.asList(preemptiveMoveList) + ); + + assertEquals( + ColoredSwitches.produceFinalMoveList(startingColors, (byte) desiredState), + Arrays.asList(expectedShortestPath) + ); + } } From 1ea67a690c75eb1d01e4cbf45bc57e6e76b46ed2 Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:19:30 -0600 Subject: [PATCH 5/7] Added one more test --- .../bomb/modules/c/colored/switches/ColoredSwitchesTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java index e4963cfb..9e4592ac 100644 --- a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java +++ b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java @@ -74,6 +74,10 @@ public Object[][] fullMoveListTestProvider() { { 21, new String[]{"5", "4", "5"}, new SwitchColor[]{GREEN, RED, GREEN, BLUE, BLUE}, 1, new String[]{"4", "5", "4", "3", "5", "4", "2", "1", "2"} + }, + { + 20, new String[]{"4", "5", "4"}, new SwitchColor[]{ORANGE, ORANGE, CYAN, ORANGE, CYAN}, + 6, new String[]{"5", "3", "5", "2", "4", "5", "2", "1", "3"} } }; } From dcfff6317310740f8b414e9e09d8c5ff16e4a54c Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:32:20 -0600 Subject: [PATCH 6/7] Fixed UI to fit the full path of a Colored Switch route --- .../modules/c/colored/switches/colored_switches.fxml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/resources/bomb/modules/c/colored/switches/colored_switches.fxml b/src/main/resources/bomb/modules/c/colored/switches/colored_switches.fxml index 42bbe402..a5176986 100644 --- a/src/main/resources/bomb/modules/c/colored/switches/colored_switches.fxml +++ b/src/main/resources/bomb/modules/c/colored/switches/colored_switches.fxml @@ -15,7 +15,7 @@ @@ -114,8 +114,10 @@ - - + + @@ -130,7 +132,7 @@ - From b8a6e61c535a0300e9dc8007680a7b88cb029ff3 Mon Sep 17 00:00:00 2001 From: "Mr. J" <45538844+Ultraviolet-Ninja@users.noreply.github.com> Date: Thu, 23 Feb 2023 13:44:33 -0600 Subject: [PATCH 7/7] Final test edits --- .../modules/c/colored/switches/ColoredSwitches.java | 10 +++++----- .../c/colored/switches/ColoredSwitchesTest.java | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java index e2370e4c..9ddf69ac 100644 --- a/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java +++ b/src/main/java/bomb/modules/c/colored/switches/ColoredSwitches.java @@ -8,6 +8,7 @@ import org.jgrapht.graph.DefaultEdge; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -85,10 +86,10 @@ private static byte makePreemptiveMove(byte currentState, List outputLis ColoredSwitchNode startNode = NUMBER_TO_STATE_MAP.get(secondaryStartLocation); ColoredSwitchNode destination = NUMBER_TO_STATE_MAP.get(desiredState); - List nodeList2 = shortestPath.getPath(startNode, destination) + List nodeList = shortestPath.getPath(startNode, destination) .getVertexList(); - return createSwitchToFlipList(nodeList2); + return createSwitchToFlipList(nodeList); } private static List createSwitchToFlipList(List path) { @@ -106,9 +107,8 @@ static boolean canFollowPath(EnumSet connectionConditions, SwitchCo } private static void validateSwitchColors(SwitchColor[] startingColors) { - for (SwitchColor switchColor : startingColors) { - if (switchColor == NEUTRAL) - throw new IllegalArgumentException("All switches must have a color"); + if (EnumSet.copyOf(Arrays.asList(startingColors)).contains(NEUTRAL)) { + throw new IllegalArgumentException("All switches must have a color. No neutral/black switches allowed"); } } diff --git a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java index 9e4592ac..67ab7143 100644 --- a/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java +++ b/src/test/java/bomb/modules/c/colored/switches/ColoredSwitchesTest.java @@ -14,6 +14,7 @@ import static bomb.modules.c.colored.switches.SwitchColor.ORANGE; import static bomb.modules.c.colored.switches.SwitchColor.RED; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; public class ColoredSwitchesTest { @BeforeMethod @@ -37,6 +38,7 @@ public void preemptiveMoveTest(byte startingState) { @DataProvider public Object[][] finalMoveListExceptionTestProvider() { return new Object[][]{ + {new SwitchColor[]{RED, CYAN, GREEN, BLUE}, -1}, {new SwitchColor[]{RED, CYAN, GREEN, BLUE}, 0}, {new SwitchColor[]{RED, CYAN, GREEN, BLUE, RED}, 0}, {new SwitchColor[]{RED, CYAN, GREEN, BLUE, NEUTRAL}, 0} @@ -90,6 +92,8 @@ public void fullMoveListTest(int startingState, String[] preemptiveMoveList, Swi Arrays.asList(preemptiveMoveList) ); + assertTrue(ColoredSwitches.isFirstStepDone()); + assertEquals( ColoredSwitches.produceFinalMoveList(startingColors, (byte) desiredState), Arrays.asList(expectedShortestPath)