diff --git a/.idea/laby.iml b/.idea/laby.iml
index 216b054..4b248d8 100644
--- a/.idea/laby.iml
+++ b/.idea/laby.iml
@@ -24,6 +24,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/libraries/artgaphics_0_2_0.xml b/.idea/libraries/artgaphics_0_2_0.xml
new file mode 100644
index 0000000..6ed4394
--- /dev/null
+++ b/.idea/libraries/artgaphics_0_2_0.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/java/org/artisanlogiciel/games/MazeParamsFixed.java b/java/org/artisanlogiciel/games/MazeParamsFixed.java
deleted file mode 100644
index 6f9e505..0000000
--- a/java/org/artisanlogiciel/games/MazeParamsFixed.java
+++ /dev/null
@@ -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;
- }
-}
diff --git a/java/org/artisanlogiciel/games/MazeResolutionListener.java b/java/org/artisanlogiciel/games/MazeResolutionListener.java
deleted file mode 100644
index 9c12371..0000000
--- a/java/org/artisanlogiciel/games/MazeResolutionListener.java
+++ /dev/null
@@ -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 solvedPath);
-
-}
diff --git a/java/org/artisanlogiciel/games/Brick.java b/java/org/artisanlogiciel/games/maze/Brick.java
similarity index 91%
rename from java/org/artisanlogiciel/games/Brick.java
rename to java/org/artisanlogiciel/games/maze/Brick.java
index 9b238a2..df980d1 100644
--- a/java/org/artisanlogiciel/games/Brick.java
+++ b/java/org/artisanlogiciel/games/maze/Brick.java
@@ -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
diff --git a/java/org/artisanlogiciel/games/LabyMap.java b/java/org/artisanlogiciel/games/maze/LabyMap.java
similarity index 93%
rename from java/org/artisanlogiciel/games/LabyMap.java
rename to java/org/artisanlogiciel/games/maze/LabyMap.java
index 324b779..26543d1 100644
--- a/java/org/artisanlogiciel/games/LabyMap.java
+++ b/java/org/artisanlogiciel/games/maze/LabyMap.java
@@ -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 exits = new LinkedList();
+ LinkedList exits;
public LabyMap(Brick[][] tileMap, LinkedList exits)
{
diff --git a/java/org/artisanlogiciel/games/LabyModel.java b/java/org/artisanlogiciel/games/maze/LabyModel.java
similarity index 70%
rename from java/org/artisanlogiciel/games/LabyModel.java
rename to java/org/artisanlogiciel/games/maze/LabyModel.java
index 56e22b9..0a08322 100644
--- a/java/org/artisanlogiciel/games/LabyModel.java
+++ b/java/org/artisanlogiciel/games/maze/LabyModel.java
@@ -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 resolve(int x, int y, MazeResolutionListener rlistener) {
- long safeguard = width * height;
- int newx = 0;
- int newy = 0;
-
- resetResolving();
-
- // list of alternate paths
- LinkedList> altpath = new LinkedList<>();
-
- // list of positions from start to end
- LinkedList backpath = new LinkedList();
- // 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 cp = new LinkedList(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);
}
}
diff --git a/java/org/artisanlogiciel/games/Main.java b/java/org/artisanlogiciel/games/maze/Main.java
similarity index 55%
rename from java/org/artisanlogiciel/games/Main.java
rename to java/org/artisanlogiciel/games/maze/Main.java
index 4b19244..ac9d70a 100644
--- a/java/org/artisanlogiciel/games/Main.java
+++ b/java/org/artisanlogiciel/games/maze/Main.java
@@ -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 exits = new LinkedList();
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());
diff --git a/java/org/artisanlogiciel/games/MazeCreationListener.java b/java/org/artisanlogiciel/games/maze/MazeCreationListener.java
similarity index 80%
rename from java/org/artisanlogiciel/games/MazeCreationListener.java
rename to java/org/artisanlogiciel/games/maze/MazeCreationListener.java
index 633ecac..d4df454 100644
--- a/java/org/artisanlogiciel/games/MazeCreationListener.java
+++ b/java/org/artisanlogiciel/games/maze/MazeCreationListener.java
@@ -1,4 +1,4 @@
-package org.artisanlogiciel.games;
+package org.artisanlogiciel.games.maze;
/**
* MazeCreationListener
diff --git a/java/org/artisanlogiciel/games/MazeParamEditor.java b/java/org/artisanlogiciel/games/maze/MazeParamEditor.java
similarity index 96%
rename from java/org/artisanlogiciel/games/MazeParamEditor.java
rename to java/org/artisanlogiciel/games/maze/MazeParamEditor.java
index 003723b..35f6dc8 100644
--- a/java/org/artisanlogiciel/games/MazeParamEditor.java
+++ b/java/org/artisanlogiciel/games/maze/MazeParamEditor.java
@@ -1,4 +1,4 @@
-package org.artisanlogiciel.games;
+package org.artisanlogiciel.games.maze;
import java.io.File;
import java.util.Scanner;
diff --git a/java/org/artisanlogiciel/games/MazeParams.java b/java/org/artisanlogiciel/games/maze/MazeParams.java
similarity index 92%
rename from java/org/artisanlogiciel/games/MazeParams.java
rename to java/org/artisanlogiciel/games/maze/MazeParams.java
index e2020a8..e0ded6f 100644
--- a/java/org/artisanlogiciel/games/MazeParams.java
+++ b/java/org/artisanlogiciel/games/maze/MazeParams.java
@@ -1,4 +1,4 @@
-package org.artisanlogiciel.games;
+package org.artisanlogiciel.games.maze;
import java.io.File;
diff --git a/java/org/artisanlogiciel/games/maze/MazeParamsFixed.java b/java/org/artisanlogiciel/games/maze/MazeParamsFixed.java
new file mode 100644
index 0000000..6f8668e
--- /dev/null
+++ b/java/org/artisanlogiciel/games/maze/MazeParamsFixed.java
@@ -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;
+ }
+}
diff --git a/java/org/artisanlogiciel/games/Position.java b/java/org/artisanlogiciel/games/maze/Position.java
similarity index 95%
rename from java/org/artisanlogiciel/games/Position.java
rename to java/org/artisanlogiciel/games/maze/Position.java
index da2a162..11d0801 100644
--- a/java/org/artisanlogiciel/games/Position.java
+++ b/java/org/artisanlogiciel/games/maze/Position.java
@@ -1,4 +1,4 @@
-package org.artisanlogiciel.games;
+package org.artisanlogiciel.games.maze;
/** position of a cell with maze */
public class Position
diff --git a/java/org/artisanlogiciel/games/WallsProvider.java b/java/org/artisanlogiciel/games/maze/WallsProvider.java
similarity index 67%
rename from java/org/artisanlogiciel/games/WallsProvider.java
rename to java/org/artisanlogiciel/games/maze/WallsProvider.java
index 6c96c10..0159a74 100644
--- a/java/org/artisanlogiciel/games/WallsProvider.java
+++ b/java/org/artisanlogiciel/games/maze/WallsProvider.java
@@ -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);
}
diff --git a/java/org/artisanlogiciel/games/maze/gui/Display.java b/java/org/artisanlogiciel/games/maze/gui/Display.java
index 79893e5..a214b36 100644
--- a/java/org/artisanlogiciel/games/maze/gui/Display.java
+++ b/java/org/artisanlogiciel/games/maze/gui/Display.java
@@ -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);
diff --git a/java/org/artisanlogiciel/games/maze/gui/Maze3dSettings.java b/java/org/artisanlogiciel/games/maze/gui/Maze3dSettings.java
index 601e396..c8c595d 100644
--- a/java/org/artisanlogiciel/games/maze/gui/Maze3dSettings.java
+++ b/java/org/artisanlogiciel/games/maze/gui/Maze3dSettings.java
@@ -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.*;
diff --git a/java/org/artisanlogiciel/games/maze/gui/MazeSettings.java b/java/org/artisanlogiciel/games/maze/gui/MazeSettings.java
index f7e4a4e..421c9bb 100644
--- a/java/org/artisanlogiciel/games/maze/gui/MazeSettings.java
+++ b/java/org/artisanlogiciel/games/maze/gui/MazeSettings.java
@@ -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;
diff --git a/java/org/artisanlogiciel/games/maze/persist/MazePersistRaw.java b/java/org/artisanlogiciel/games/maze/persist/MazePersistRaw.java
new file mode 100644
index 0000000..eef055f
--- /dev/null
+++ b/java/org/artisanlogiciel/games/maze/persist/MazePersistRaw.java
@@ -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.");
+ }
+
+ }
+
+}
diff --git a/java/org/artisanlogiciel/games/DirectionPosition.java b/java/org/artisanlogiciel/games/maze/solve/DirectionPosition.java
similarity index 92%
rename from java/org/artisanlogiciel/games/DirectionPosition.java
rename to java/org/artisanlogiciel/games/maze/solve/DirectionPosition.java
index f11f88a..6be3447 100644
--- a/java/org/artisanlogiciel/games/DirectionPosition.java
+++ b/java/org/artisanlogiciel/games/maze/solve/DirectionPosition.java
@@ -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
diff --git a/java/org/artisanlogiciel/games/maze/solve/MazeResolutionListener.java b/java/org/artisanlogiciel/games/maze/solve/MazeResolutionListener.java
new file mode 100644
index 0000000..80abad4
--- /dev/null
+++ b/java/org/artisanlogiciel/games/maze/solve/MazeResolutionListener.java
@@ -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 solvedPath);
+
+}
diff --git a/java/org/artisanlogiciel/games/maze/solve/SolvingModel.java b/java/org/artisanlogiciel/games/maze/solve/SolvingModel.java
new file mode 100644
index 0000000..765e1f2
--- /dev/null
+++ b/java/org/artisanlogiciel/games/maze/solve/SolvingModel.java
@@ -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 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> altpath = new LinkedList<>();
+
+ // list of positions from start to end
+ LinkedList backpath = new LinkedList();
+ // 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 cp = new LinkedList(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;
+ }
+
+}
diff --git a/java/org/artisanlogiciel/games/stl/Wall3d.java b/java/org/artisanlogiciel/games/stl/Wall3d.java
index 7f77f3d..aadbb21 100644
--- a/java/org/artisanlogiciel/games/stl/Wall3d.java
+++ b/java/org/artisanlogiciel/games/stl/Wall3d.java
@@ -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...
*
diff --git a/java/org/artisanlogiciel/games/stl/Wall3dStream.java b/java/org/artisanlogiciel/games/stl/Wall3dStream.java
index f2ed4d6..0e2df1a 100644
--- a/java/org/artisanlogiciel/games/stl/Wall3dStream.java
+++ b/java/org/artisanlogiciel/games/stl/Wall3dStream.java
@@ -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;