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>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<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>
|
</component>
|
||||||
</module>
|
</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
|
ab
|
||||||
cd
|
cd
|
||||||
|
|
||||||
a is 'H' or '.' or ' '
|
a is 'H' or '.' or ' '
|
||||||
bcd is 'H' or ' '
|
bcd is within 'H' or ' '
|
||||||
|
|
||||||
*/
|
*/
|
||||||
public class Brick
|
public class Brick
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
class LabyMap implements WallsProvider
|
/**
|
||||||
|
* model with Bricks, based on walls
|
||||||
|
*/
|
||||||
|
public class LabyMap implements WallsProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
Brick[][] tileMap;
|
Brick[][] tileMap;
|
||||||
LinkedList<Position> exits = new LinkedList<Position>();
|
LinkedList<Position> exits;
|
||||||
|
|
||||||
public LabyMap(Brick[][] tileMap, 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.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -30,10 +29,6 @@ public class LabyModel implements WallsProvider {
|
|||||||
public final static short POSITIVE = 8;
|
public final static short POSITIVE = 8;
|
||||||
public final static short NEGATIVE = 16;
|
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
|
// completed
|
||||||
public final static short LEFT = Brick.LEFT << FLAGLENGTH | DIRECTION | HORIZONTAL | NEGATIVE;
|
public final static short LEFT = Brick.LEFT << FLAGLENGTH | DIRECTION | HORIZONTAL | NEGATIVE;
|
||||||
public final static short DOWN = Brick.DOWN << FLAGLENGTH | DIRECTION | VERTICAL | POSITIVE;
|
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;
|
public final static short ENTRY = Brick.ENTRY << FLAGLENGTH;
|
||||||
// flag when a wall should be open to access this for exit
|
// flag when a wall should be open to access this for exit
|
||||||
private final static short GOAL = Brick.GOAL << FLAGLENGTH;
|
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.
|
// flag when solution is on this path.
|
||||||
public final static short SOLVED = 64 << FLAGLENGTH;
|
public final static short SOLVED = 64 << FLAGLENGTH;
|
||||||
// free flag
|
// free flag
|
||||||
@@ -51,7 +51,7 @@ public class LabyModel implements WallsProvider {
|
|||||||
// remains 2 free bits ( keep one out for sign )
|
// remains 2 free bits ( keep one out for sign )
|
||||||
|
|
||||||
// orders matters see getReverseDirection
|
// 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 width;
|
||||||
private int height;
|
private int height;
|
||||||
@@ -100,8 +100,18 @@ public class LabyModel implements WallsProvider {
|
|||||||
/**
|
/**
|
||||||
* construct LabyModel from an InputStream, yet only "raw" is supported
|
* construct LabyModel from an InputStream, yet only "raw" is supported
|
||||||
**/
|
**/
|
||||||
public LabyModel(String pFormat, InputStream pIn) throws IOException {
|
public LabyModel(int width, int heigh, short [][] t) {
|
||||||
parseInputStream(pFormat, pIn);
|
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) {
|
public void setMazeListener(MazeCreationListener listener) {
|
||||||
@@ -539,153 +549,6 @@ public class LabyModel implements WallsProvider {
|
|||||||
return pointingdirection;
|
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) {
|
private final void closePosition(int x, int y) {
|
||||||
t[x][y] &= ~OPEN;
|
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"))) {
|
* is there no wall in that direction ?
|
||||||
// first raw format, not smart.
|
**/
|
||||||
DataOutputStream dataOut = new DataOutputStream(pOut);
|
public boolean canMoveInDirection(int x, int y, short direction) {
|
||||||
// should dump this to stream.
|
// tried to replace by but does not work ( can't go back ...).
|
||||||
dataOut.write(new byte[]{(byte) 'L', (byte) 'A', (byte) 'B', (byte) '0'});
|
// return ! hasWallInDirection(x,y, (short) (direction << FLAGLENGTH));
|
||||||
dataOut.writeInt(getWidth());
|
return ((getWalls(x, y) & direction ) == 0);
|
||||||
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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
|
import org.artisanlogiciel.games.maze.solve.SolvingModel;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class Main
|
public class Main {
|
||||||
{
|
public MazeParamEditor editor() {
|
||||||
public MazeParamEditor editor()
|
|
||||||
{
|
|
||||||
MazeParamEditor editor = new MazeParamEditor(null);
|
MazeParamEditor editor = new MazeParamEditor(null);
|
||||||
System.out.println("enter width height and maxdepth");
|
System.out.println("enter width height and maxdepth");
|
||||||
Scanner console = new Scanner(System.in);
|
Scanner console = new Scanner(System.in);
|
||||||
@@ -14,10 +14,9 @@ public class Main
|
|||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabyMap generate2(MazeParamEditor params)
|
public LabyMap generate2(MazeParamEditor params) {
|
||||||
{
|
|
||||||
params.setSeed(1024L);
|
params.setSeed(1024L);
|
||||||
LabyModel model = new LabyModel(params);
|
SolvingModel model = new SolvingModel(params);
|
||||||
model.generateWithEntry(0, 0);
|
model.generateWithEntry(0, 0);
|
||||||
|
|
||||||
final int width = params.getWidth();
|
final int width = params.getWidth();
|
||||||
@@ -26,8 +25,7 @@ public class Main
|
|||||||
model.addEntryOrExit(-1, 0);
|
model.addEntryOrExit(-1, 0);
|
||||||
model.addEntryOrExit(width, height - 1);
|
model.addEntryOrExit(width, height - 1);
|
||||||
System.out.println(model.toLabyMap().toString());
|
System.out.println(model.toLabyMap().toString());
|
||||||
if (!model.check())
|
if (!model.check()) {
|
||||||
{
|
|
||||||
System.out.println("Check failed");
|
System.out.println("Check failed");
|
||||||
}
|
}
|
||||||
model.debugOut();
|
model.debugOut();
|
||||||
@@ -36,8 +34,7 @@ public class Main
|
|||||||
return labyMap;
|
return labyMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String pArgs[])
|
public static void main(String pArgs[]) {
|
||||||
{
|
|
||||||
Main m = new Main();
|
Main m = new Main();
|
||||||
MazeParamEditor editor = m.editor();
|
MazeParamEditor editor = m.editor();
|
||||||
LabyMap map = m.generate2(editor);
|
LabyMap map = m.generate2(editor);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MazeCreationListener
|
* MazeCreationListener
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
import java.io.File;
|
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 */
|
/** position of a cell with maze */
|
||||||
public class Position
|
public class Position
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.artisanlogiciel.games;
|
package org.artisanlogiciel.games.maze;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WallsProvider provide a Walls representation
|
* WallsProvider provide a Walls representation
|
||||||
@@ -18,8 +18,10 @@ public interface WallsProvider
|
|||||||
* (8)(4)(2)(1)
|
* (8)(4)(2)(1)
|
||||||
* ^ > v <
|
* ^ > v <
|
||||||
* U R D L
|
* U R D L
|
||||||
* p i o e g w f h n t
|
* p i o e
|
||||||
|
* g w f
|
||||||
|
* h n t
|
||||||
* 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.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
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.Maze3dParams;
|
||||||
import org.artisanlogiciel.games.stl.Wall3d;
|
|
||||||
import org.artisanlogiciel.games.stl.Wall3dStream;
|
import org.artisanlogiciel.games.stl.Wall3dStream;
|
||||||
import org.artisanlogiciel.util.UTF8Control;
|
import org.artisanlogiciel.util.UTF8Control;
|
||||||
|
|
||||||
@@ -143,8 +146,12 @@ public class Display extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void resolve() {
|
void resolve() {
|
||||||
|
|
||||||
|
SolvingModel solving = new SolvingModel(model);
|
||||||
|
// should transform current model to be a SolvingModel
|
||||||
|
model = solving;
|
||||||
model.reset();
|
model.reset();
|
||||||
model.resolve(model.getWidth() - 1, model.getHeight() - 1, maze);
|
solving.resolve(solving.getWidth() - 1, solving.getHeight() - 1, maze);
|
||||||
}
|
}
|
||||||
|
|
||||||
void goNorth() {
|
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)
|
void addStatus(String pStatus)
|
||||||
{
|
{
|
||||||
statusField.setText(pStatus);
|
statusField.setText(pStatus);
|
||||||
@@ -414,6 +436,16 @@ public class Display extends JFrame {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
saveStlButton.addActionListener(saveStlAction);
|
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());
|
stlsettings = new Maze3dSettings(new Maze3dParams());
|
||||||
|
|
||||||
@@ -425,6 +457,7 @@ public class Display extends JFrame {
|
|||||||
saveMenu.add(stlsettings);
|
saveMenu.add(stlsettings);
|
||||||
saveMenu.add(saveStlButton);
|
saveMenu.add(saveStlButton);
|
||||||
saveMenu.add(saveImcButton);
|
saveMenu.add(saveImcButton);
|
||||||
|
saveMenu.add(saveTextButton);
|
||||||
|
|
||||||
return saveMenu;
|
return saveMenu;
|
||||||
|
|
||||||
@@ -601,7 +634,7 @@ public class Display extends JFrame {
|
|||||||
FileInputStream inputStream = null;
|
FileInputStream inputStream = null;
|
||||||
try {
|
try {
|
||||||
inputStream = new FileInputStream(infile);
|
inputStream = new FileInputStream(infile);
|
||||||
model = new LabyModel("raw", inputStream);
|
model = new MazePersistRaw().parseInputStream("raw",inputStream);
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
io.printStackTrace(System.err);
|
io.printStackTrace(System.err);
|
||||||
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
|
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
|
||||||
@@ -851,55 +884,43 @@ public class Display extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void goNorth() {
|
private void proceed()
|
||||||
resetResolution();
|
{
|
||||||
if ((map.getWalls(sX, sY) & Brick.UP) == 0) {
|
|
||||||
sY = sY - 1;
|
|
||||||
// should redraw ...
|
// should redraw ...
|
||||||
invalidate();
|
invalidate();
|
||||||
repaint();
|
repaint();
|
||||||
|
|
||||||
checkExit();
|
checkExit();
|
||||||
}
|
}
|
||||||
|
void goNorth() {
|
||||||
|
resetResolution();
|
||||||
|
if (map.canMoveInDirection(sX, sY,Brick.UP)) {
|
||||||
|
sY = sY - 1;
|
||||||
|
proceed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void goSouth() {
|
void goSouth() {
|
||||||
resetResolution();
|
resetResolution();
|
||||||
if ((map.getWalls(sX, sY) & Brick.DOWN) == 0) {
|
if (map.canMoveInDirection(sX, sY,Brick.DOWN)) {
|
||||||
sY = sY + 1;
|
sY = sY + 1;
|
||||||
// should redraw ...
|
proceed();
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
checkExit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void goEast() {
|
void goEast() {
|
||||||
resetResolution();
|
resetResolution();
|
||||||
if ((map.getWalls(sX, sY) & Brick.RIGHT) == 0) {
|
if (map.canMoveInDirection(sX, sY, Brick.RIGHT)) {
|
||||||
sX = sX + 1;
|
sX = sX + 1;
|
||||||
// should redraw ...
|
proceed();
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
checkExit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void goWest() {
|
void goWest() {
|
||||||
resetResolution();
|
resetResolution();
|
||||||
if ((map.getWalls(sX, sY) & Brick.LEFT) == 0) {
|
if (map.canMoveInDirection(sX, sY, Brick.LEFT)) {
|
||||||
sX = sX - 1;
|
sX = sX - 1;
|
||||||
// should redraw ...
|
proceed();
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
checkExit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1113,7 +1134,8 @@ public class Display extends JFrame {
|
|||||||
addStatus("Saving to " + outfile + " ...");
|
addStatus("Saving to " + outfile + " ...");
|
||||||
try {
|
try {
|
||||||
FileOutputStream out = new FileOutputStream(outfile);
|
FileOutputStream out = new FileOutputStream(outfile);
|
||||||
model.streamOut("raw", out);
|
MazePersistRaw persist = new MazePersistRaw(model);
|
||||||
|
persist.streamOut("raw", out);
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
addStatus("... Done.");
|
addStatus("... Done.");
|
||||||
@@ -1135,7 +1157,7 @@ public class Display extends JFrame {
|
|||||||
|
|
||||||
if ((pArgs.length > 0) && (pArgs[0].length() > 0)) {
|
if ((pArgs.length > 0) && (pArgs[0].length() > 0)) {
|
||||||
try {
|
try {
|
||||||
model = new LabyModel("raw", new FileInputStream(pArgs[0]));
|
model = new MazePersistRaw().parseInputStream("raw",new FileInputStream(pArgs[0]));
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
io.printStackTrace(System.err);
|
io.printStackTrace(System.err);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.artisanlogiciel.games.maze.gui;
|
package org.artisanlogiciel.games.maze.gui;
|
||||||
|
|
||||||
import org.artisanlogiciel.games.MazeParams;
|
|
||||||
import org.artisanlogiciel.games.stl.Maze3dParams;
|
import org.artisanlogiciel.games.stl.Maze3dParams;
|
||||||
import org.artisanlogiciel.games.stl.Wall3d;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.artisanlogiciel.games.maze.gui;
|
package org.artisanlogiciel.games.maze.gui;
|
||||||
|
|
||||||
import org.artisanlogiciel.games.MazeParams;
|
import org.artisanlogiciel.games.maze.MazeParams;
|
||||||
import org.artisanlogiciel.games.MazeParamsFixed;
|
import org.artisanlogiciel.games.maze.MazeParamsFixed;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.ChangeEvent;
|
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
|
* 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;
|
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...
|
* Wall3d to create walls in 3d for stl conversion South, West North East...
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.artisanlogiciel.games.stl;
|
package org.artisanlogiciel.games.stl;
|
||||||
|
|
||||||
import org.artisanlogiciel.games.Brick;
|
import org.artisanlogiciel.games.maze.Brick;
|
||||||
import org.artisanlogiciel.games.LabyModel;
|
import org.artisanlogiciel.games.maze.LabyModel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|||||||
Reference in New Issue
Block a user