From 54eba4aa354b572eafa1daef87e31c3c56623f30 Mon Sep 17 00:00:00 2001 From: Niklas Birk Date: Mon, 12 Apr 2021 16:12:01 +0200 Subject: [PATCH] add new problem "Labyrinthine puzzle" from game Labyrinthine Chapter I --- src/search/LabyrinthineNode.java | 124 +++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/search/LabyrinthineNode.java diff --git a/src/search/LabyrinthineNode.java b/src/search/LabyrinthineNode.java new file mode 100644 index 0000000..a560e22 --- /dev/null +++ b/src/search/LabyrinthineNode.java @@ -0,0 +1,124 @@ +package search; + +import java.util.*; + +public class LabyrinthineNode extends Node +{ + public LabyrinthineNode(final boolean[][] state) + { + super(state); + } + + private LabyrinthineNode(final boolean[][] value, final Node parent, final int heuristicCosts) + { + super(value, parent, heuristicCosts); + } + + @Override + public boolean isTargetReached(final Node target) + { + return valueEquals(target); + } + + @Override + public List> generateSuccessors() + { + final var successors = new ArrayList>(); + final var offPositions = detectOffPositions(); + + for (final var pos : offPositions) + { + final var newState = copyOfState(); + + toggleStateAtPos(newState, new IntPair(pos.x(), pos.y())); + toggleStateAtPos(newState, new IntPair(pos.x(), pos.y() + 1)); + toggleStateAtPos(newState, new IntPair(pos.x(), pos.y() - 1)); + toggleStateAtPos(newState, new IntPair(pos.x() + 1, pos.y())); + toggleStateAtPos(newState, new IntPair(pos.x() - 1, pos.y())); + + final var successor = new LabyrinthineNode(newState, this, super.heuristicCosts + 1); + + if (!successor.valueEquals(this) && !successor.valueEquals(super.getParent())) + { + successors.add(successor); + } + } + + return successors; + } + + @Override + public String toString() + { + final var builder = new StringBuilder(); + + for (final var row : super.value) + { + builder.append(Arrays.toString(row)).append("\n"); + } + + return builder.toString(); + } + + private boolean valueEquals(final Node node) + { + if (node == null) + { + return false; + } + + for (var row = 0; row < super.value.length; row++) + { + for (var col = 0; col < super.value[row].length; col++) + { + if (super.value[row][col] != node.value[row][col]) + { + return false; + } + } + } + + return true; + } + + private List detectOffPositions() + { + final var positions = new ArrayList(); + + for (var row = 0; row < super.value.length; row++) + { + for (var col = 0; col < super.value[row].length; col++) + { + if (!super.value[row][col]) + { + positions.add(new IntPair(col, row)); + } + } + } + + return positions; + } + + private boolean[][] copyOfState() + { + final var copy = new boolean[super.value.length][super.value[0].length]; + + for (var y = 0; y < copy.length; y++) + { + System.arraycopy(super.value[y], 0, copy[y], 0, copy.length); + } + + return copy; + } + + private void toggleStateAtPos(boolean[][] newState, IntPair pos) + { + try + { + newState[pos.y()][pos.x()] = !newState[pos.y()][pos.x()]; + } + catch (final ArrayIndexOutOfBoundsException ignored) + { + } + } +} \ No newline at end of file