add Save Text support and rework package

- move maze within package maze
This commit is contained in:
philippe lhardy
2020-10-17 21:08:16 +02:00
parent c3410838e1
commit c69d068caf
24 changed files with 590 additions and 385 deletions

View File

@@ -0,0 +1,171 @@
package org.artisanlogiciel.games.maze.solve;
import org.artisanlogiciel.games.maze.LabyModel;
import org.artisanlogiciel.games.maze.MazeParams;
import org.artisanlogiciel.games.maze.Position;
import java.util.LinkedList;
public class SolvingModel
extends LabyModel
{
public SolvingModel(MazeParams params) {
super(params);
}
public SolvingModel(LabyModel model) {
super(model);
}
/**
* resolve this labrynth using internal representation
* initial (x,y) is exit, will return list of positions from start (0,0) to end (x,y)
**/
public LinkedList<DirectionPosition> resolve(int x, int y, MazeResolutionListener rlistener) {
int width = getWidth();
int height = getHeight();
long safeguard = width * height;
int newx = 0;
int newy = 0;
resetResolving();
// list of alternate paths
LinkedList<LinkedList<DirectionPosition>> altpath = new LinkedList<>();
// list of positions from start to end
LinkedList<DirectionPosition> backpath = new LinkedList<DirectionPosition>();
// position that point to (x,y).
DirectionPosition found = new DirectionPosition((short) 0, new Position(x, y));
// entry
Position entry = new Position(0, 0);
while (!found.getPosition().equals(entry)) {
Position last = found.getPosition();
backpath.addFirst(found);
found = null;
// should find from all adjacent cells (directions) one that point to this.
{
// didx is index of four cell adjacent to this (x,y)
for (int didx = 0; didx < 4; didx++) {
int delta = 0;
short direction = AllDirections[didx];
short reversedirection = getReverseDirection(didx);
short pointingdirection = DIRECTION;
if (isFlagSet(direction, POSITIVE)) {
delta = 1;
pointingdirection |= NEGATIVE;
} else {
delta = -1;
pointingdirection |= POSITIVE;
}
if (isFlagSet(direction, HORIZONTAL)) {
newx = last.getX() + delta;
newy = last.getY();
pointingdirection |= HORIZONTAL;
} else {
newy = last.getY() + delta;
newx = last.getX();
pointingdirection |= VERTICAL;
}
// internal GUARD.
if (!isFlagSet(reversedirection, pointingdirection)) {
System.out.println("[FATAL] Internal ERROR. Please check AllDirections order "
+ (reversedirection & pointingdirection) + " " + pointingdirection);
return backpath;
}
Position p = new Position(newx, newy);
if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) {
if (isFlagSet(getCell(p), reversedirection)) {
if (found != null) {
// there is already a potential solution in adjacent cell of last.
System.out.println("alternate " + p + " from " + last + "/" + safeguard);
// could be a unique parent of two paths...
// but search from other entry/exits than generated
// from
// ie entry(0,0) exit(width-1,height-1) not yet
// implemented.
{
if (!isFlagSet(getCell(p), SOLVED)) {
LinkedList<DirectionPosition> cp = new LinkedList<DirectionPosition>(backpath);
DirectionPosition altfound = new DirectionPosition(reversedirection, p);
cp.addFirst(altfound);
altpath.addLast(cp);
rlistener.notifySearchError("record alternate path " + p.toString());
} else {
// this was already solved, might be a loop.
if (rlistener != null) {
rlistener.notifySearchError("Loop " + last.toString() + " has two parents " + found.toString() + " "
+ p.toString());
}
// continue;
}
}
} else {
if (!isFlagSet(getCell(p), SOLVED)) {
// this is first potential solution in adjacent cell of last.
System.out.println("check " + p + " from " + last + "/" + safeguard);
found = new DirectionPosition(reversedirection, p);
if (rlistener != null) {
rlistener.notifySearch(found);
}
} else {
// was already solved.
System.out.println("already solved " + p + " from " + last + "/" + safeguard);
}
}
// support multiple pathes
} else {
System.out.println("not reachable " + p + " from " + last + "/" + safeguard);
}
} else {
System.out.println("p outofbounds " + p + "/" + safeguard);
}
}
if (found == null) {
if (!altpath.isEmpty()) {
// new possible backpath
backpath = altpath.removeFirst();
found = backpath.removeFirst();
if (rlistener != null) {
rlistener.notifySearchError("try alternate path " + found.toString());
rlistener.notifySearch(found);
}
}
}
}
if (found == null) {
if (!altpath.isEmpty()) {
rlistener.notifySearchError("No path found BUT ALTPATH !");
}
rlistener.notifySearchError("No path found !");
break;
}
// System.out.println(found);
if (isFlagSet(getCell(found.getPosition()), SOLVED)) {
System.out.println("[INFO] position already solved" + found.toString() + " *length:" + backpath.size());
} else {
updateCell(found.getPosition(), SOLVED);
}
safeguard--;
if (safeguard < 0) {
rlistener.notifySearchError("Path too long ( or long overflow ) for width*height:" + (width * height) + " length:" + backpath.size());
break;
}
}
if (rlistener != null) {
rlistener.notifyCompletion(backpath);
}
return backpath;
}
}