add path view

limit resolve depth ( to avoid infinite ).
to complete : horrible
This commit is contained in:
philippe lhardy
2017-11-29 23:09:32 +01:00
parent ce485f2263
commit 401c7e15d0
2 changed files with 181 additions and 72 deletions

View File

@@ -553,6 +553,50 @@ public class Display extends JFrame
g.drawLine(x, y, x, y + (int) height); g.drawLine(x, y, x, y + (int) height);
} }
public void drawPath(Graphics g, int pX, int pY, short path)
{
int x = offsetX + (int) (pX * width);
int y = offsetY + (int) (pY * height);
int xm = x+ (int) (width / 2);
int ym = y+ (int) (height / 2);
if ( (path & LabyModel.HORIZONTAL) == LabyModel.HORIZONTAL)
{
g.drawLine(x, ym, x + (int) width, ym);
if ( (path & LabyModel.POSITIVE) == LabyModel.POSITIVE )
{
g.drawLine(x, ym + (int) (height / 4), x + (int) width, ym);
}
if ( (path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE )
{
g.drawLine(x, ym , x + (int) width, ym - (int) (height / 4));
}
}
if ((path & LabyModel.VERTICAL) == LabyModel.VERTICAL)
{
g.drawLine(xm, y, xm , y + (int) height);
if ( (path & LabyModel.POSITIVE) == LabyModel.POSITIVE )
{
g.drawLine(xm - (int) (width / 4), y , xm, y + (int) height);
}
if ( (path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE )
{
g.drawLine(xm, y , xm + (int) (width /4), y + (int) (height));
}
}
/*
if ((path & LabyModel.HORIZONTAL) ==LabyModel.HORIZONTAL)
{
y=y+ (int) (height / 2);
g.drawLine(x + (int) width, y, x + (int) width, y + (int) height);
}
if ( (pX == 0 ) && ((path & LabyModel.VERTICAL) == LabyModel.VERTICAL))
{
x=x+ (int) (width / 2);
g.drawLine(x, y, x, y + (int) height);
}
*/
}
public void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY) public void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY)
{ {
double radius = (height > width) ? width : height; double radius = (height > width) ? width : height;
@@ -748,6 +792,7 @@ public class Display extends JFrame
int x = 0; int x = 0;
int y = 0; int y = 0;
short walls = 0; short walls = 0;
short path = 0;
// try to display only visible part... // try to display only visible part...
// should compute pX, pY, mX, mY based on clip... // should compute pX, pY, mX, mY based on clip...
@@ -808,6 +853,9 @@ public class Display extends JFrame
} }
} }
int aX = pX;
int aY = pY;
g.setColor(Color.black); g.setColor(Color.black);
// draw all walls within clip bounds horiz first then lines // draw all walls within clip bounds horiz first then lines
@@ -819,7 +867,31 @@ public class Display extends JFrame
cp.drawWalls(g, pX, pY, walls); cp.drawWalls(g, pX, pY, walls);
} }
} }
}
pX = aX;
pY = aY;
// draw all path within clip bounds horiz first then lines
for (; pY < mY; pY++)
{
for (pX = 0; pX < mX; pX++)
{
path = map.getPath(pX,pY);
if ( ( path & LabyModel.SOLVED ) == LabyModel.SOLVED )
{
g.setColor(Color.green);
}
else
{
g.setColor(Color.blue);
}
if ( path != 0 )
{
cp.drawPath(g,pX,pY,path);
}
}
}
}
public boolean notifySearch(Position pPosition) public boolean notifySearch(Position pPosition)

View File

@@ -28,13 +28,14 @@ public class LabyModel implements WallsProvider
private final static short FLAGLENGTH = 7; private final static short FLAGLENGTH = 7;
private final static short CLEAR = 0; // mandatory 0 since array creation is private final static short CLEAR = 0; // mandatory 0 since array creation is
// initialized with 0. // initialized with 0.
private final static short HORIZONTAL = 1; public final static short HORIZONTAL = 1;
private final static short VERTICAL = 2; public final static short VERTICAL = 2;
private final static short DIRECTION = 4; // could we get rid of that to public final static short DIRECTION = 4; // could we get rid of that to
// free one bit for other purpose // free one bit for other purpose
// ? // ?
private final static short POSITIVE = 8; public final static short POSITIVE = 8;
private final static short NEGATIVE = 16; public final static short NEGATIVE = 16;
private final static short OPEN = 32; // can be reused once generation is private final static short OPEN = 32; // can be reused once generation is
// completed // completed
private final static short CLOSED = 64; // can be reused once generation is private final static short CLOSED = 64; // can be reused once generation is
@@ -52,7 +53,7 @@ public class LabyModel implements WallsProvider
// wall should // wall should
// be open to // be open to
// access this. // access this.
private final static short SOLVED = 64 << FLAGLENGTH; // flag when solution public final static short SOLVED = 64 << FLAGLENGTH; // flag when solution
// is on this path. // is on this path.
private final static short FREE = 128 << FLAGLENGTH; // free flag private final static short FREE = 128 << FLAGLENGTH; // free flag
// remains 2 free bits ( keep one out for sign ) // remains 2 free bits ( keep one out for sign )
@@ -545,89 +546,100 @@ public class LabyModel implements WallsProvider
/** /**
* resolve this labrynth using internal representation * resolve this labrynth using internal representation
* initial (x,y) is exit, will return list of positions from start to end.
**/ **/
public LinkedList<Position> resolve(int x, int y, MazeResolutionListener rlistener) public LinkedList<Position> resolve(int x, int y, MazeResolutionListener rlistener)
{ {
long safeguard = width * height;
int newx = x; int newx = x;
int newy = y; int newy = y;
// list of positions from start to end
LinkedList<Position> backpath = new LinkedList<Position>(); LinkedList<Position> backpath = new LinkedList<Position>();
while (!((newx == 0) && (newy == 0))) while (!((newx == 0) && (newy == 0)))
{ {
// position that point to (x,y).
Position found = null; Position found = null;
if (( x == newx ) && ( y == newy ))
{
System.out.println("[ERROR] path contains same consecutive point" + new Position(newx, newy).toString());
}
x = newx; x = newx;
y = newy; y = newy;
backpath.addFirst(new Position(x, y)); backpath.addFirst(new Position(x, y));
// should find from all direction one that point to this. // should find from all adjacent cells (directions) one that point to this.
ArrayList<Short> freeDirection = new ArrayList<Short>(); {
ArrayList<Short> freeDirection = new ArrayList<Short>();
for (int didx = 0; didx < 4; didx++) // 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]; int delta = 0;
short reversedirection = AllDirections[(didx + 2) % 4]; short direction = AllDirections[didx];
short pointingdirection = DIRECTION; short reversedirection = AllDirections[(didx + 2) % 4];
short pointingdirection = DIRECTION;
if ((direction & POSITIVE) == POSITIVE) if ((direction & POSITIVE) == POSITIVE)
{ {
delta = 1; delta = 1;
pointingdirection |= NEGATIVE; pointingdirection |= NEGATIVE;
} }
else else
{ {
delta = -1; delta = -1;
pointingdirection |= POSITIVE; pointingdirection |= POSITIVE;
} }
if ((direction & HORIZONTAL) == HORIZONTAL) if ((direction & HORIZONTAL) == HORIZONTAL)
{ {
newx = x + delta; newx = x + delta;
newy = y; newy = y;
pointingdirection |= HORIZONTAL; pointingdirection |= HORIZONTAL;
} }
else else
{ {
newy = y + delta; newy = y + delta;
newx = x; newx = x;
pointingdirection |= VERTICAL; pointingdirection |= VERTICAL;
} }
// internal GUARD. // internal GUARD.
if ((reversedirection & pointingdirection) != pointingdirection) if ((reversedirection & pointingdirection) != pointingdirection)
{ {
System.out.println("Internal ERROR. Please check AllDirections order " System.out.println("Internal ERROR. Please check AllDirections order "
+ (reversedirection & pointingdirection) + " " + pointingdirection); + (reversedirection & pointingdirection) + " " + pointingdirection);
return backpath; return backpath;
} }
if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height))
{ {
if ((t[newx][newy] & reversedirection) == reversedirection) if ((t[newx][newy] & reversedirection) == reversedirection)
{ {
if (found != null) if (found != null)
{ {
// could be a unique parent of two paths... // could be a unique parent of two paths...
// but search from other entry/exits than generated // but search from other entry/exits than generated
// from // from
// ie entry(0,0) exit(width-1,height-1) not yet // ie entry(0,0) exit(width-1,height-1) not yet
// implemented. // implemented.
if (rlistener != null) if (rlistener != null)
{ {
rlistener.notifySearchError("Model Error : two parents " + found.toString() + " " rlistener.notifySearchError("Model Error : two parents " + found.toString() + " "
+ new Position(newx, newy).toString()); + new Position(newx, newy).toString());
} }
return backpath; return backpath;
} }
found = new Position(newx, newy); found = new Position(newx, newy);
if (rlistener != null) if (rlistener != null)
{ {
rlistener.notifySearch(found); rlistener.notifySearch(found);
} }
break; break;
} }
} }
} }
}
if (found == null) if (found == null)
{ {
rlistener.notifySearchError("No path found !"); rlistener.notifySearchError("No path found !");
@@ -636,7 +648,22 @@ public class LabyModel implements WallsProvider
// System.out.println(found); // System.out.println(found);
newx = found.getX(); newx = found.getX();
newy = found.getY(); newy = found.getY();
t[newx][newy] |= SOLVED; if ( ( t[newx][newy] & SOLVED ) == SOLVED )
{
System.out.println("[INFO] position already solved" + new Position(newx, newy).toString() + " *length:" + backpath.size());
}
else
{
t[newx][newy] |= 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) if (rlistener != null)
{ {
@@ -813,6 +840,16 @@ public class LabyModel implements WallsProvider
return walls; return walls;
} }
public short getPath(int x, int y)
{
short path = 0;
if (( x < width ) && ( y < height ))
{
path = t[x][y];
}
return path;
}
/** /**
* is there a wall in that direction ? * is there a wall in that direction ?
**/ **/