puzzlesolver: fix solution being reset when clicking the puzzle quickly
This commit is contained in:
@@ -142,8 +142,8 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
{
|
{
|
||||||
boolean foundPosition = false;
|
boolean foundPosition = false;
|
||||||
|
|
||||||
// Find the current state by looking at the current step and then the next 3 steps
|
// Find the current state by looking at the current step and then the next 5 steps
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
int j = solver.getPosition() + i;
|
int j = solver.getPosition() + i;
|
||||||
|
|
||||||
@@ -152,10 +152,10 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer currentState = solver.getStep(j);
|
PuzzleState currentState = solver.getStep(j);
|
||||||
|
|
||||||
// If this is false, player has moved the empty tile
|
// 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;
|
foundPosition = true;
|
||||||
solver.setPosition(j);
|
solver.setPosition(j);
|
||||||
@@ -168,10 +168,10 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If looking at the next steps didn't find the current state,
|
// 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)
|
if (!foundPosition)
|
||||||
{
|
{
|
||||||
for (int i = 1; i < 4; i++)
|
for (int i = 1; i < 6; i++)
|
||||||
{
|
{
|
||||||
int j = solver.getPosition() - i;
|
int j = solver.getPosition() - i;
|
||||||
|
|
||||||
@@ -180,9 +180,9 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
break;
|
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;
|
foundPosition = true;
|
||||||
shouldCache = true;
|
shouldCache = true;
|
||||||
@@ -218,15 +218,15 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
// Display the next 4 steps
|
// Display the next 4 steps
|
||||||
for (int j = 1; j < 5; j++)
|
for (int j = 1; j < 5; j++)
|
||||||
{
|
{
|
||||||
Integer futureMove = solver.getStep(solver.getPosition() + j);
|
PuzzleState futureMove = solver.getStep(solver.getPosition() + j);
|
||||||
|
|
||||||
if (futureMove == null)
|
if (futureMove == null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int blankX = futureMove % DIMENSION;
|
int blankX = futureMove.getEmptyPiece() % DIMENSION;
|
||||||
int blankY = futureMove / DIMENSION;
|
int blankY = futureMove.getEmptyPiece() / DIMENSION;
|
||||||
|
|
||||||
int markerSize = DOT_MARKER_SIZE - j * 3;
|
int markerSize = DOT_MARKER_SIZE - j * 3;
|
||||||
|
|
||||||
@@ -242,23 +242,23 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the current blank tile position
|
// Find the current blank tile position
|
||||||
Integer currentMove = solver.getStep(solver.getPosition());
|
PuzzleState currentMove = solver.getStep(solver.getPosition());
|
||||||
|
|
||||||
int lastBlankX = currentMove % DIMENSION;
|
int lastBlankX = currentMove.getEmptyPiece() % DIMENSION;
|
||||||
int lastBlankY = currentMove / DIMENSION;
|
int lastBlankY = currentMove.getEmptyPiece() / DIMENSION;
|
||||||
|
|
||||||
// Display the next 3 steps
|
// Display the next 3 steps
|
||||||
for (int j = 1; j < 4; j++)
|
for (int j = 1; j < 4; j++)
|
||||||
{
|
{
|
||||||
Integer futureMove = solver.getStep(solver.getPosition() + j);
|
PuzzleState futureMove = solver.getStep(solver.getPosition() + j);
|
||||||
|
|
||||||
if (futureMove == null)
|
if (futureMove == null)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int blankX = futureMove % DIMENSION;
|
int blankX = futureMove.getEmptyPiece() % DIMENSION;
|
||||||
int blankY = futureMove / DIMENSION;
|
int blankY = futureMove.getEmptyPiece() / DIMENSION;
|
||||||
|
|
||||||
int xDelta = blankX - lastBlankX;
|
int xDelta = blankX - lastBlankX;
|
||||||
int yDelta = blankY - lastBlankY;
|
int yDelta = blankY - lastBlankY;
|
||||||
@@ -353,27 +353,7 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
itemIds[items.length] = BLANK_TILE_VALUE;
|
itemIds[items.length] = BLANK_TILE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemIds;
|
return convertToSolverFormat(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -413,6 +393,25 @@ public class PuzzleSolverOverlay extends Overlay
|
|||||||
return convertedItems;
|
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()
|
private BufferedImage getDownArrow()
|
||||||
{
|
{
|
||||||
if (downArrow == null)
|
if (downArrow == null)
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
package net.runelite.client.plugins.puzzlesolver.solver;
|
package net.runelite.client.plugins.puzzlesolver.solver;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.Pathfinder;
|
import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.Pathfinder;
|
||||||
|
|
||||||
public class PuzzleSolver implements Runnable
|
public class PuzzleSolver implements Runnable
|
||||||
@@ -36,7 +35,7 @@ public class PuzzleSolver implements Runnable
|
|||||||
private Pathfinder pathfinder;
|
private Pathfinder pathfinder;
|
||||||
private PuzzleState startState;
|
private PuzzleState startState;
|
||||||
|
|
||||||
private List<Integer> solution;
|
private List<PuzzleState> solution;
|
||||||
private int position;
|
private int position;
|
||||||
private boolean failed = false;
|
private boolean failed = false;
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ public class PuzzleSolver implements Runnable
|
|||||||
this.startState = startState;
|
this.startState = startState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getStep(int stepIdx)
|
public PuzzleState getStep(int stepIdx)
|
||||||
{
|
{
|
||||||
if (stepIdx < 0 || stepIdx >= solution.size())
|
if (stepIdx < 0 || stepIdx >= solution.size())
|
||||||
{
|
{
|
||||||
@@ -84,17 +83,7 @@ public class PuzzleSolver implements Runnable
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
List<PuzzleState> solution = pathfinder.computePath(startState);
|
solution = pathfinder.computePath(startState);
|
||||||
|
failed = solution == null;
|
||||||
if (solution != null)
|
|
||||||
{
|
|
||||||
this.solution = solution.stream()
|
|
||||||
.map(PuzzleState::getEmptyPiece)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,11 @@ public class PuzzleState
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasPieces(int[] pieces)
|
||||||
|
{
|
||||||
|
return Arrays.equals(pieces, this.pieces);
|
||||||
|
}
|
||||||
|
|
||||||
public int getPiece(int x, int y)
|
public int getPiece(int x, int y)
|
||||||
{
|
{
|
||||||
return pieces[y * DIMENSION + x];
|
return pieces[y * DIMENSION + x];
|
||||||
|
|||||||
@@ -25,15 +25,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.puzzlesolver;
|
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.PuzzleSolver;
|
||||||
import net.runelite.client.plugins.puzzlesolver.solver.PuzzleState;
|
import net.runelite.client.plugins.puzzlesolver.solver.PuzzleState;
|
||||||
import net.runelite.client.plugins.puzzlesolver.solver.heuristics.ManhattanDistance;
|
import net.runelite.client.plugins.puzzlesolver.solver.heuristics.ManhattanDistance;
|
||||||
import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.IDAStar;
|
import net.runelite.client.plugins.puzzlesolver.solver.pathfinding.IDAStar;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static net.runelite.client.plugins.puzzlesolver.solver.PuzzleSolver.DIMENSION;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class PuzzleSolverTest
|
public class PuzzleSolverTest
|
||||||
@@ -97,27 +94,8 @@ public class PuzzleSolverTest
|
|||||||
solver.run();
|
solver.run();
|
||||||
|
|
||||||
assertTrue(solver.hasSolution());
|
assertTrue(solver.hasSolution());
|
||||||
|
assertFalse(solver.hasFailed());
|
||||||
for (int i = 0; i < solver.getStepCount(); i++)
|
assertTrue(solver.getStep(solver.getStepCount() - 1).hasPieces(FINISHED_STATE));
|
||||||
{
|
|
||||||
int futureMove = solver.getStep(i);
|
|
||||||
|
|
||||||
List<PuzzleState> 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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user