From 3396c7ac45009fdb1c8ca45f9d6c226b43cc5be0 Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 24 Feb 2018 00:38:41 +0100 Subject: [PATCH] puzzlesolver: fix solution being reset when clicking the puzzle quickly --- .../puzzlesolver/PuzzleSolverOverlay.java | 75 +++++++++---------- .../puzzlesolver/solver/PuzzleSolver.java | 19 +---- .../puzzlesolver/solver/PuzzleState.java | 5 ++ .../puzzlesolver/PuzzleSolverTest.java | 28 +------ 4 files changed, 49 insertions(+), 78 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java index fffb774e8a..b28ae9917c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverOverlay.java @@ -142,8 +142,8 @@ public class PuzzleSolverOverlay extends Overlay { boolean foundPosition = false; - // Find the current state by looking at the current step and then the next 3 steps - for (int i = 0; i < 4; i++) + // Find the current state by looking at the current step and then the next 5 steps + for (int i = 0; i < 6; i++) { int j = solver.getPosition() + i; @@ -152,10 +152,10 @@ public class PuzzleSolverOverlay extends Overlay break; } - Integer currentState = solver.getStep(j); + PuzzleState currentState = solver.getStep(j); // If this is false, player has moved the empty tile - if (currentState != null && itemIds[currentState] == BLANK_TILE_VALUE) + if (currentState != null && currentState.hasPieces(itemIds)) { foundPosition = true; solver.setPosition(j); @@ -168,10 +168,10 @@ public class PuzzleSolverOverlay extends Overlay } // If looking at the next steps didn't find the current state, - // see if we can find the current state in the 3 previous steps + // see if we can find the current state in the 5 previous steps if (!foundPosition) { - for (int i = 1; i < 4; i++) + for (int i = 1; i < 6; i++) { int j = solver.getPosition() - i; @@ -180,9 +180,9 @@ public class PuzzleSolverOverlay extends Overlay break; } - Integer currentState = solver.getStep(j); + PuzzleState currentState = solver.getStep(j); - if (currentState != null && itemIds[currentState] == BLANK_TILE_VALUE) + if (currentState != null && currentState.hasPieces(itemIds)) { foundPosition = true; shouldCache = true; @@ -218,15 +218,15 @@ public class PuzzleSolverOverlay extends Overlay // Display the next 4 steps for (int j = 1; j < 5; j++) { - Integer futureMove = solver.getStep(solver.getPosition() + j); + PuzzleState futureMove = solver.getStep(solver.getPosition() + j); if (futureMove == null) { break; } - int blankX = futureMove % DIMENSION; - int blankY = futureMove / DIMENSION; + int blankX = futureMove.getEmptyPiece() % DIMENSION; + int blankY = futureMove.getEmptyPiece() / DIMENSION; int markerSize = DOT_MARKER_SIZE - j * 3; @@ -242,23 +242,23 @@ public class PuzzleSolverOverlay extends Overlay else { // Find the current blank tile position - Integer currentMove = solver.getStep(solver.getPosition()); + PuzzleState currentMove = solver.getStep(solver.getPosition()); - int lastBlankX = currentMove % DIMENSION; - int lastBlankY = currentMove / DIMENSION; + int lastBlankX = currentMove.getEmptyPiece() % DIMENSION; + int lastBlankY = currentMove.getEmptyPiece() / DIMENSION; // Display the next 3 steps for (int j = 1; j < 4; j++) { - Integer futureMove = solver.getStep(solver.getPosition() + j); + PuzzleState futureMove = solver.getStep(solver.getPosition() + j); if (futureMove == null) { break; } - int blankX = futureMove % DIMENSION; - int blankY = futureMove / DIMENSION; + int blankX = futureMove.getEmptyPiece() % DIMENSION; + int blankY = futureMove.getEmptyPiece() / DIMENSION; int xDelta = blankX - lastBlankX; int yDelta = blankY - lastBlankY; @@ -353,27 +353,7 @@ public class PuzzleSolverOverlay extends Overlay itemIds[items.length] = BLANK_TILE_VALUE; } - return itemIds; - } - - private void cacheItems(int[] items) - { - cachedItems = new int[items.length]; - System.arraycopy(items, 0, cachedItems, 0, cachedItems.length); - } - - private void solve(int[] items) - { - if (solverFuture != null) - { - solverFuture.cancel(true); - } - - int[] puzzleItems = convertToSolverFormat(items); - PuzzleState puzzleState = new PuzzleState(puzzleItems); - - solver = new PuzzleSolver(new IDAStar(new ManhattanDistance()), puzzleState); - solverFuture = executorService.submit(solver); + return convertToSolverFormat(itemIds); } /** @@ -413,6 +393,25 @@ public class PuzzleSolverOverlay extends Overlay return convertedItems; } + private void cacheItems(int[] items) + { + cachedItems = new int[items.length]; + System.arraycopy(items, 0, cachedItems, 0, cachedItems.length); + } + + private void solve(int[] items) + { + if (solverFuture != null) + { + solverFuture.cancel(true); + } + + PuzzleState puzzleState = new PuzzleState(items); + + solver = new PuzzleSolver(new IDAStar(new ManhattanDistance()), puzzleState); + solverFuture = executorService.submit(solver); + } + private BufferedImage getDownArrow() { if (downArrow == null) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleSolver.java index 2b0bbfcee8..cf4b0cc1c2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleSolver.java @@ -26,7 +26,6 @@ package net.runelite.client.plugins.puzzlesolver.solver; import java.util.List; -import java.util.stream.Collectors; import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.Pathfinder; public class PuzzleSolver implements Runnable @@ -36,7 +35,7 @@ public class PuzzleSolver implements Runnable private Pathfinder pathfinder; private PuzzleState startState; - private List solution; + private List solution; private int position; private boolean failed = false; @@ -46,7 +45,7 @@ public class PuzzleSolver implements Runnable this.startState = startState; } - public Integer getStep(int stepIdx) + public PuzzleState getStep(int stepIdx) { if (stepIdx < 0 || stepIdx >= solution.size()) { @@ -84,17 +83,7 @@ public class PuzzleSolver implements Runnable @Override public void run() { - List solution = pathfinder.computePath(startState); - - if (solution != null) - { - this.solution = solution.stream() - .map(PuzzleState::getEmptyPiece) - .collect(Collectors.toList()); - } - else - { - failed = true; - } + solution = pathfinder.computePath(startState); + failed = solution == null; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleState.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleState.java index 80f0415626..36db17893f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/solver/PuzzleState.java @@ -153,6 +153,11 @@ public class PuzzleState return parent; } + public boolean hasPieces(int[] pieces) + { + return Arrays.equals(pieces, this.pieces); + } + public int getPiece(int x, int y) { return pieces[y * DIMENSION + x]; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverTest.java index 12cdc00103..af14ee8ebb 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/puzzlesolver/PuzzleSolverTest.java @@ -25,15 +25,12 @@ */ package net.runelite.client.plugins.puzzlesolver; -import java.util.List; import net.runelite.client.plugins.puzzlesolver.solver.PuzzleSolver; import net.runelite.client.plugins.puzzlesolver.solver.PuzzleState; import net.runelite.client.plugins.puzzlesolver.solver.heuristics.ManhattanDistance; import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.IDAStar; import org.junit.Test; -import static net.runelite.client.plugins.puzzlesolver.solver.PuzzleSolver.DIMENSION; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class PuzzleSolverTest @@ -97,27 +94,8 @@ public class PuzzleSolverTest solver.run(); assertTrue(solver.hasSolution()); - - for (int i = 0; i < solver.getStepCount(); i++) - { - int futureMove = solver.getStep(i); - - List moves = state.computeMoves(); - - for (PuzzleState move : moves) - { - if (move.getEmptyPiece() == futureMove) - { - state = move; - break; - } - } - } - - for (int i = 0; i < FINISHED_STATE.length; i++) - { - assertEquals(state.getPiece(i % DIMENSION, i / DIMENSION), FINISHED_STATE[i]); - } + assertFalse(solver.hasFailed()); + assertTrue(solver.getStep(solver.getStepCount() - 1).hasPieces(FINISHED_STATE)); } } }