add Save Text support and rework package
- move maze within package maze
This commit is contained in:
2
.idea/laby.iml
generated
2
.idea/laby.iml
generated
@@ -24,6 +24,6 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="artgaphics-0.1.0" level="project" />
|
||||
<orderEntry type="library" name="artgaphics-0.2.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
9
.idea/libraries/artgaphics_0_2_0.xml
generated
Normal file
9
.idea/libraries/artgaphics_0_2_0.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="libraryTable">
|
||||
<library name="artgaphics-0.2.0">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/libs/artgaphics-0.2.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,76 +0,0 @@
|
||||
package org.artisanlogiciel.games;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MazeParamsFixed implements MazeParams
|
||||
{
|
||||
long seed;
|
||||
int width;
|
||||
int height;
|
||||
int maxdepth;
|
||||
File labdir;
|
||||
String name;
|
||||
|
||||
public MazeParamsFixed()
|
||||
{
|
||||
}
|
||||
|
||||
public MazeParamsFixed(MazeParams params)
|
||||
{
|
||||
setParams(params.getSaveDir(),params.getWidth(),params.getHeight(),params.getMaxDepth());
|
||||
}
|
||||
|
||||
public void setParams(File saveDir, int W, int H, int MD)
|
||||
{
|
||||
labdir = saveDir;
|
||||
width=W;
|
||||
height=H;
|
||||
maxdepth=MD;
|
||||
}
|
||||
|
||||
public MazeParamsFixed(File saveDir, int W, int H, int MD, long seed)
|
||||
{
|
||||
name = null;
|
||||
setParams(saveDir,W,H,MD);
|
||||
this.seed=seed;
|
||||
}
|
||||
|
||||
public long getSeed()
|
||||
{
|
||||
return seed;
|
||||
}
|
||||
|
||||
public int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getMaxDepth()
|
||||
{
|
||||
return maxdepth;
|
||||
}
|
||||
|
||||
public void setName(String n)
|
||||
{
|
||||
name = n;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
name = "lab" + width + "x" + height;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public File getSaveDir()
|
||||
{
|
||||
return labdir;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.artisanlogiciel.games;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* MazeResolutionListener used as interface between resolver and (mostly) GUI
|
||||
**/
|
||||
public interface MazeResolutionListener
|
||||
{
|
||||
|
||||
public boolean notifySearch(DirectionPosition pPosition);
|
||||
|
||||
public void notifySearchError(String error);
|
||||
|
||||
public void notifyCompletion(LinkedList<DirectionPosition> solvedPath);
|
||||
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
/*
|
||||
2x2 Tile to represent a labyrinth position
|
||||
|
||||
2x2 Tile to represent a labyrinth position with some walls
|
||||
|
||||
this is 2x2 downright most part of 3x3 centered tile.
|
||||
|
||||
center right
|
||||
down downright
|
||||
|
||||
ab
|
||||
cd
|
||||
|
||||
a is 'H' or '.' or ' '
|
||||
bcd is 'H' or ' '
|
||||
bcd is within 'H' or ' '
|
||||
|
||||
*/
|
||||
public class Brick
|
||||
@@ -1,12 +1,15 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
class LabyMap implements WallsProvider
|
||||
/**
|
||||
* model with Bricks, based on walls
|
||||
*/
|
||||
public class LabyMap implements WallsProvider
|
||||
{
|
||||
|
||||
Brick[][] tileMap;
|
||||
LinkedList<Position> exits = new LinkedList<Position>();
|
||||
LinkedList<Position> exits;
|
||||
|
||||
public LabyMap(Brick[][] tileMap, LinkedList<Position> exits)
|
||||
{
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
@@ -30,10 +29,6 @@ public class LabyModel implements WallsProvider {
|
||||
public final static short POSITIVE = 8;
|
||||
public final static short NEGATIVE = 16;
|
||||
|
||||
// can it be both OPEN and CLOSED ?
|
||||
private final static short OPEN = 32; // can be reused once generation is
|
||||
// completed
|
||||
private final static short CLOSED = 64; // can be reused once generation is
|
||||
// completed
|
||||
public final static short LEFT = Brick.LEFT << FLAGLENGTH | DIRECTION | HORIZONTAL | NEGATIVE;
|
||||
public final static short DOWN = Brick.DOWN << FLAGLENGTH | DIRECTION | VERTICAL | POSITIVE;
|
||||
@@ -44,6 +39,11 @@ public class LabyModel implements WallsProvider {
|
||||
public final static short ENTRY = Brick.ENTRY << FLAGLENGTH;
|
||||
// flag when a wall should be open to access this for exit
|
||||
private final static short GOAL = Brick.GOAL << FLAGLENGTH;
|
||||
|
||||
// can it be both OPEN and CLOSED ?
|
||||
private final static short OPEN = 32; // can be reused once generation is
|
||||
// completed
|
||||
private final static short CLOSED = 64; // can be reused once generation is
|
||||
// flag when solution is on this path.
|
||||
public final static short SOLVED = 64 << FLAGLENGTH;
|
||||
// free flag
|
||||
@@ -51,7 +51,7 @@ public class LabyModel implements WallsProvider {
|
||||
// remains 2 free bits ( keep one out for sign )
|
||||
|
||||
// orders matters see getReverseDirection
|
||||
private static final short[] AllDirections = {LEFT, DOWN, RIGHT, UP};
|
||||
public static final short[] AllDirections = {LEFT, DOWN, RIGHT, UP};
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
@@ -100,8 +100,18 @@ public class LabyModel implements WallsProvider {
|
||||
/**
|
||||
* construct LabyModel from an InputStream, yet only "raw" is supported
|
||||
**/
|
||||
public LabyModel(String pFormat, InputStream pIn) throws IOException {
|
||||
parseInputStream(pFormat, pIn);
|
||||
public LabyModel(int width, int heigh, short [][] t) {
|
||||
random = null;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public LabyModel(LabyModel other ) {
|
||||
random = null;
|
||||
this.width = other.width;
|
||||
this.height = other.height;
|
||||
this.t = other.t;
|
||||
}
|
||||
|
||||
public void setMazeListener(MazeCreationListener listener) {
|
||||
@@ -539,153 +549,6 @@ public class LabyModel implements WallsProvider {
|
||||
return pointingdirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
private final void closePosition(int x, int y) {
|
||||
t[x][y] &= ~OPEN;
|
||||
@@ -877,59 +740,13 @@ public class LabyModel implements WallsProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public void streamOut(String pFormat, OutputStream pOut) throws IOException {
|
||||
if ((pFormat == null) || (pFormat.equals("raw"))) {
|
||||
// first raw format, not smart.
|
||||
DataOutputStream dataOut = new DataOutputStream(pOut);
|
||||
// should dump this to stream.
|
||||
dataOut.write(new byte[]{(byte) 'L', (byte) 'A', (byte) 'B', (byte) '0'});
|
||||
dataOut.writeInt(getWidth());
|
||||
dataOut.writeInt(getHeight());
|
||||
dataOut.flush();
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int x = 0; x < getWidth(); x++) {
|
||||
dataOut.writeShort(t[x][y]);
|
||||
}
|
||||
}
|
||||
dataOut.flush();
|
||||
} else {
|
||||
throw new IOException("Format " + pFormat + " Not yet implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
private void streamIn(String pFormat, InputStream pIn) throws IOException {
|
||||
throw new IOException("Use correct constructor.");
|
||||
}
|
||||
|
||||
private void parseInputStream(String pFormat, InputStream pIn) throws IOException {
|
||||
if ((pFormat == null) || (pFormat.equals("raw"))) {
|
||||
// maxdepth is unset then unmodified
|
||||
byte[] header = new byte[4];
|
||||
DataInputStream in = new DataInputStream(pIn);
|
||||
in.read(header);
|
||||
int rwidth = in.readInt();
|
||||
int rheight = in.readInt();
|
||||
if ((rwidth > 0) && (rheight > 0)) {
|
||||
width = rwidth;
|
||||
height = rheight;
|
||||
random = null;
|
||||
// SHOULD CHECK max width and max height...
|
||||
// CLEAR == 0 and array is initialized with 0s
|
||||
t = new short[width][height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
t[x][y] = in.readShort();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Invalid header for width and height");
|
||||
}
|
||||
// should be at end of stream ? Not necessary can stream multiple
|
||||
// labs ( or tiling ).
|
||||
} else {
|
||||
throw new IOException("Format " + pFormat + " Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* is there no wall in that direction ?
|
||||
**/
|
||||
public boolean canMoveInDirection(int x, int y, short direction) {
|
||||
// tried to replace by but does not work ( can't go back ...).
|
||||
// return ! hasWallInDirection(x,y, (short) (direction << FLAGLENGTH));
|
||||
return ((getWalls(x, y) & direction ) == 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +1,31 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import org.artisanlogiciel.games.maze.solve.SolvingModel;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main
|
||||
{
|
||||
public MazeParamEditor editor()
|
||||
{
|
||||
MazeParamEditor editor = new MazeParamEditor(null);
|
||||
System.out.println("enter width height and maxdepth");
|
||||
public class Main {
|
||||
public MazeParamEditor editor() {
|
||||
MazeParamEditor editor = new MazeParamEditor(null);
|
||||
System.out.println("enter width height and maxdepth");
|
||||
Scanner console = new Scanner(System.in);
|
||||
editor.read(console);
|
||||
return editor;
|
||||
editor.read(console);
|
||||
return editor;
|
||||
}
|
||||
|
||||
public LabyMap generate2(MazeParamEditor params)
|
||||
{
|
||||
public LabyMap generate2(MazeParamEditor params) {
|
||||
params.setSeed(1024L);
|
||||
LabyModel model = new LabyModel(params);
|
||||
SolvingModel model = new SolvingModel(params);
|
||||
model.generateWithEntry(0, 0);
|
||||
|
||||
final int width = params.getWidth();
|
||||
final int height = params.getHeight();
|
||||
final int width = params.getWidth();
|
||||
final int height = params.getHeight();
|
||||
LinkedList<Position> exits = new LinkedList<Position>();
|
||||
model.addEntryOrExit(-1, 0);
|
||||
model.addEntryOrExit(width, height - 1);
|
||||
System.out.println(model.toLabyMap().toString());
|
||||
if (!model.check())
|
||||
{
|
||||
if (!model.check()) {
|
||||
System.out.println("Check failed");
|
||||
}
|
||||
model.debugOut();
|
||||
@@ -36,10 +34,9 @@ public class Main
|
||||
return labyMap;
|
||||
}
|
||||
|
||||
public static void main(String pArgs[])
|
||||
{
|
||||
public static void main(String pArgs[]) {
|
||||
Main m = new Main();
|
||||
MazeParamEditor editor = m.editor();
|
||||
MazeParamEditor editor = m.editor();
|
||||
LabyMap map = m.generate2(editor);
|
||||
System.out.println(map.toShortString());
|
||||
System.out.println(map.toString());
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
/**
|
||||
* MazeCreationListener
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Scanner;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
63
java/org/artisanlogiciel/games/maze/MazeParamsFixed.java
Normal file
63
java/org/artisanlogiciel/games/maze/MazeParamsFixed.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MazeParamsFixed implements MazeParams {
|
||||
long seed;
|
||||
int width;
|
||||
int height;
|
||||
int maxdepth;
|
||||
File labdir;
|
||||
String name;
|
||||
|
||||
public MazeParamsFixed() {
|
||||
}
|
||||
|
||||
public MazeParamsFixed(MazeParams params) {
|
||||
setParams(params.getSaveDir(), params.getWidth(), params.getHeight(), params.getMaxDepth());
|
||||
}
|
||||
|
||||
public void setParams(File saveDir, int W, int H, int MD) {
|
||||
labdir = saveDir;
|
||||
width = W;
|
||||
height = H;
|
||||
maxdepth = MD;
|
||||
}
|
||||
|
||||
public MazeParamsFixed(File saveDir, int W, int H, int MD, long seed) {
|
||||
name = null;
|
||||
setParams(saveDir, W, H, MD);
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getMaxDepth() {
|
||||
return maxdepth;
|
||||
}
|
||||
|
||||
public void setName(String n) {
|
||||
name = n;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
name = "lab" + width + "x" + height;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public File getSaveDir() {
|
||||
return labdir;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
/** position of a cell with maze */
|
||||
public class Position
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze;
|
||||
|
||||
/**
|
||||
* WallsProvider provide a Walls representation
|
||||
@@ -18,8 +18,10 @@ public interface WallsProvider
|
||||
* (8)(4)(2)(1)
|
||||
* ^ > v <
|
||||
* U R D L
|
||||
* p i o e g w f h n t
|
||||
* t
|
||||
* p i o e
|
||||
* g w f
|
||||
* h n t
|
||||
* t
|
||||
**/
|
||||
public short getWalls(int x, int y);
|
||||
short getWalls(int x, int y);
|
||||
}
|
||||
@@ -27,9 +27,12 @@ import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import org.artisanlogiciel.games.*;
|
||||
import org.artisanlogiciel.games.maze.*;
|
||||
import org.artisanlogiciel.games.maze.persist.MazePersistRaw;
|
||||
import org.artisanlogiciel.games.maze.solve.DirectionPosition;
|
||||
import org.artisanlogiciel.games.maze.solve.MazeResolutionListener;
|
||||
import org.artisanlogiciel.games.maze.solve.SolvingModel;
|
||||
import org.artisanlogiciel.games.stl.Maze3dParams;
|
||||
import org.artisanlogiciel.games.stl.Wall3d;
|
||||
import org.artisanlogiciel.games.stl.Wall3dStream;
|
||||
import org.artisanlogiciel.util.UTF8Control;
|
||||
|
||||
@@ -143,8 +146,12 @@ public class Display extends JFrame {
|
||||
}
|
||||
|
||||
void resolve() {
|
||||
|
||||
SolvingModel solving = new SolvingModel(model);
|
||||
// should transform current model to be a SolvingModel
|
||||
model = solving;
|
||||
model.reset();
|
||||
model.resolve(model.getWidth() - 1, model.getHeight() - 1, maze);
|
||||
solving.resolve(solving.getWidth() - 1, solving.getHeight() - 1, maze);
|
||||
}
|
||||
|
||||
void goNorth() {
|
||||
@@ -311,6 +318,21 @@ public class Display extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
void saveText() {
|
||||
File outfile = getFileForExtension("txt");
|
||||
writeSentence("Saving to " + outfile + " ...");
|
||||
try {
|
||||
DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile));
|
||||
out.write(model.toLabyMap().toString().getBytes());
|
||||
out.flush();
|
||||
out.close();
|
||||
writeSentence("... Done.");
|
||||
} catch (IOException io) {
|
||||
io.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addStatus(String pStatus)
|
||||
{
|
||||
statusField.setText(pStatus);
|
||||
@@ -414,6 +436,16 @@ public class Display extends JFrame {
|
||||
}
|
||||
};
|
||||
saveStlButton.addActionListener(saveStlAction);
|
||||
final JButton saveTextButton = new JButton(labels.getString("save") + " txt");
|
||||
Action saveTextAction = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
//
|
||||
addStatus("save txt");
|
||||
setMazeName(saveName.getText());
|
||||
saveText();
|
||||
}
|
||||
};
|
||||
saveTextButton.addActionListener(saveTextAction);
|
||||
|
||||
stlsettings = new Maze3dSettings(new Maze3dParams());
|
||||
|
||||
@@ -425,6 +457,7 @@ public class Display extends JFrame {
|
||||
saveMenu.add(stlsettings);
|
||||
saveMenu.add(saveStlButton);
|
||||
saveMenu.add(saveImcButton);
|
||||
saveMenu.add(saveTextButton);
|
||||
|
||||
return saveMenu;
|
||||
|
||||
@@ -601,7 +634,7 @@ public class Display extends JFrame {
|
||||
FileInputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(infile);
|
||||
model = new LabyModel("raw", inputStream);
|
||||
model = new MazePersistRaw().parseInputStream("raw",inputStream);
|
||||
} catch (IOException io) {
|
||||
io.printStackTrace(System.err);
|
||||
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
|
||||
@@ -851,55 +884,43 @@ public class Display extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
private void proceed()
|
||||
{
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
checkExit();
|
||||
}
|
||||
void goNorth() {
|
||||
resetResolution();
|
||||
if ((map.getWalls(sX, sY) & Brick.UP) == 0) {
|
||||
if (map.canMoveInDirection(sX, sY,Brick.UP)) {
|
||||
sY = sY - 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void goSouth() {
|
||||
resetResolution();
|
||||
if ((map.getWalls(sX, sY) & Brick.DOWN) == 0) {
|
||||
if (map.canMoveInDirection(sX, sY,Brick.DOWN)) {
|
||||
sY = sY + 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void goEast() {
|
||||
resetResolution();
|
||||
if ((map.getWalls(sX, sY) & Brick.RIGHT) == 0) {
|
||||
if (map.canMoveInDirection(sX, sY, Brick.RIGHT)) {
|
||||
sX = sX + 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
proceed();
|
||||
}
|
||||
}
|
||||
|
||||
void goWest() {
|
||||
resetResolution();
|
||||
if ((map.getWalls(sX, sY) & Brick.LEFT) == 0) {
|
||||
if (map.canMoveInDirection(sX, sY, Brick.LEFT)) {
|
||||
sX = sX - 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
proceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1113,7 +1134,8 @@ public class Display extends JFrame {
|
||||
addStatus("Saving to " + outfile + " ...");
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(outfile);
|
||||
model.streamOut("raw", out);
|
||||
MazePersistRaw persist = new MazePersistRaw(model);
|
||||
persist.streamOut("raw", out);
|
||||
out.flush();
|
||||
out.close();
|
||||
addStatus("... Done.");
|
||||
@@ -1135,7 +1157,7 @@ public class Display extends JFrame {
|
||||
|
||||
if ((pArgs.length > 0) && (pArgs[0].length() > 0)) {
|
||||
try {
|
||||
model = new LabyModel("raw", new FileInputStream(pArgs[0]));
|
||||
model = new MazePersistRaw().parseInputStream("raw",new FileInputStream(pArgs[0]));
|
||||
} catch (IOException io) {
|
||||
io.printStackTrace(System.err);
|
||||
System.exit(1);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.artisanlogiciel.games.maze.gui;
|
||||
|
||||
import org.artisanlogiciel.games.MazeParams;
|
||||
import org.artisanlogiciel.games.stl.Maze3dParams;
|
||||
import org.artisanlogiciel.games.stl.Wall3d;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.artisanlogiciel.games.maze.gui;
|
||||
|
||||
import org.artisanlogiciel.games.MazeParams;
|
||||
import org.artisanlogiciel.games.MazeParamsFixed;
|
||||
import org.artisanlogiciel.games.maze.MazeParams;
|
||||
import org.artisanlogiciel.games.maze.MazeParamsFixed;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.artisanlogiciel.games.maze.persist;
|
||||
|
||||
import org.artisanlogiciel.games.maze.LabyModel;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class MazePersistRaw
|
||||
{
|
||||
private LabyModel model;
|
||||
|
||||
public MazePersistRaw(LabyModel model)
|
||||
{
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public MazePersistRaw()
|
||||
{
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
|
||||
public void streamOut(String pFormat, OutputStream pOut) throws IOException {
|
||||
if ((pFormat == null) || (pFormat.equals("raw"))) {
|
||||
// first raw format, not smart.
|
||||
DataOutputStream dataOut = new DataOutputStream(pOut);
|
||||
// should dump this to stream.
|
||||
dataOut.write(new byte[]{(byte) 'L', (byte) 'A', (byte) 'B', (byte) '0'});
|
||||
dataOut.writeInt(model.getWidth());
|
||||
dataOut.writeInt(model.getHeight());
|
||||
dataOut.flush();
|
||||
for (int y = 0; y < model.getHeight(); y++) {
|
||||
for (int x = 0; x < model.getWidth(); x++) {
|
||||
dataOut.writeShort(model.getPath(x,y));
|
||||
}
|
||||
}
|
||||
dataOut.flush();
|
||||
} else {
|
||||
throw new IOException("Format " + pFormat + " Not yet implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public LabyModel parseInputStream(String pFormat, InputStream pIn) throws IOException {
|
||||
if ((pFormat == null) || (pFormat.equals("raw"))) {
|
||||
// maxdepth is unset then unmodified
|
||||
byte[] header = new byte[4];
|
||||
DataInputStream in = new DataInputStream(pIn);
|
||||
in.read(header);
|
||||
int rwidth = in.readInt();
|
||||
int rheight = in.readInt();
|
||||
if ((rwidth > 0) && (rheight > 0)) {
|
||||
int width = rwidth;
|
||||
int height = rheight;
|
||||
// SHOULD CHECK max width and max height...
|
||||
// CLEAR == 0 and array is initialized with 0s
|
||||
short[][] t = new short[width][height];
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
t[x][y] = in.readShort();
|
||||
}
|
||||
}
|
||||
model= new LabyModel(width, height, t);
|
||||
return model;
|
||||
} else {
|
||||
throw new IOException("Invalid header for width and height");
|
||||
}
|
||||
// should be at end of stream ? Not necessary can stream multiple
|
||||
// labs ( or tiling ).
|
||||
} else {
|
||||
throw new IOException("Format " + pFormat + " Not yet implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
package org.artisanlogiciel.games;
|
||||
package org.artisanlogiciel.games.maze.solve;
|
||||
|
||||
import org.artisanlogiciel.games.maze.LabyModel;
|
||||
import org.artisanlogiciel.games.maze.Position;
|
||||
|
||||
/**
|
||||
* DirectionPosition
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.artisanlogiciel.games.maze.solve;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* MazeResolutionListener used as interface between resolver and (mostly) GUI
|
||||
**/
|
||||
public interface MazeResolutionListener
|
||||
{
|
||||
|
||||
boolean notifySearch(DirectionPosition pPosition);
|
||||
|
||||
void notifySearchError(String error);
|
||||
|
||||
void notifyCompletion(LinkedList<DirectionPosition> solvedPath);
|
||||
|
||||
}
|
||||
171
java/org/artisanlogiciel/games/maze/solve/SolvingModel.java
Normal file
171
java/org/artisanlogiciel/games/maze/solve/SolvingModel.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,5 @@
|
||||
package org.artisanlogiciel.games.stl;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.artisanlogiciel.games.Brick;
|
||||
import org.artisanlogiciel.games.LabyModel;
|
||||
import org.artisanlogiciel.games.WallsProvider;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wall3d to create walls in 3d for stl conversion South, West North East...
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.artisanlogiciel.games.stl;
|
||||
|
||||
import org.artisanlogiciel.games.Brick;
|
||||
import org.artisanlogiciel.games.LabyModel;
|
||||
import org.artisanlogiciel.games.maze.Brick;
|
||||
import org.artisanlogiciel.games.maze.LabyModel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
Reference in New Issue
Block a user