first .osm format import
- import osm convert it to Drawing and use it as resolved path. - Not ready , first test over lab/valbonne_oct_2020.osm
This commit is contained in:
@@ -557,7 +557,7 @@ public class LabyModel implements WallsProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* One step in Maze generation process
|
* One step in Maze generation process
|
||||||
* get last element in open list and explore one random direction with it.
|
* get last element in open list and explore one random free direction with it.
|
||||||
*
|
*
|
||||||
* @returns whether process closed current node.
|
* @returns whether process closed current node.
|
||||||
**/
|
**/
|
||||||
@@ -601,6 +601,7 @@ public class LabyModel implements WallsProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) {
|
if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) {
|
||||||
|
// CLEAR is 0 : no tag at all.
|
||||||
if ((t[newx][newy]) == CLEAR) {
|
if ((t[newx][newy]) == CLEAR) {
|
||||||
freeDirection.add(Short.valueOf(direction));
|
freeDirection.add(Short.valueOf(direction));
|
||||||
}
|
}
|
||||||
@@ -610,6 +611,7 @@ public class LabyModel implements WallsProvider {
|
|||||||
if (!freeDirection.isEmpty()) {
|
if (!freeDirection.isEmpty()) {
|
||||||
// control random using our own pseudorandom
|
// control random using our own pseudorandom
|
||||||
short direction = 0;
|
short direction = 0;
|
||||||
|
// System.out.println("" + freeDirection.size() + "\n" );
|
||||||
if (freeDirection.size() > 1) {
|
if (freeDirection.size() > 1) {
|
||||||
direction = freeDirection.get(random.nextInt(freeDirection.size()));
|
direction = freeDirection.get(random.nextInt(freeDirection.size()));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,20 +2,14 @@ package org.artisanlogiciel.games.maze.gui;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.FlowLayout;
|
import java.awt.FlowLayout;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ComponentAdapter;
|
import java.awt.event.ComponentAdapter;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.InputEvent;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.MouseMotionListener;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -27,11 +21,11 @@ import javax.swing.event.ChangeListener;
|
|||||||
|
|
||||||
import org.artisanlogiciel.games.maze.*;
|
import org.artisanlogiciel.games.maze.*;
|
||||||
import org.artisanlogiciel.games.maze.persist.MazePersistRaw;
|
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.maze.solve.SolvingModel;
|
||||||
import org.artisanlogiciel.games.stl.Maze3dParams;
|
import org.artisanlogiciel.games.stl.Maze3dParams;
|
||||||
import org.artisanlogiciel.games.stl.Wall3dStream;
|
import org.artisanlogiciel.games.stl.Wall3dStream;
|
||||||
|
import org.artisanlogiciel.osm.OsmReader;
|
||||||
|
import org.artisanlogiciel.osm.convert.OsmToDrawing;
|
||||||
import org.artisanlogiciel.util.UTF8Control;
|
import org.artisanlogiciel.util.UTF8Control;
|
||||||
|
|
||||||
import org.artisanlogiciel.graphics.Drawing;
|
import org.artisanlogiciel.graphics.Drawing;
|
||||||
@@ -41,7 +35,9 @@ import org.artisanlogiciel.graphics.SvgWriter;
|
|||||||
/**
|
/**
|
||||||
* Display is Main JFrame for this tool
|
* Display is Main JFrame for this tool
|
||||||
**/
|
**/
|
||||||
public class Display extends JFrame {
|
public class Display extends JFrame
|
||||||
|
implements StatusListener
|
||||||
|
{
|
||||||
// to please eclipse, not supposed to be serialized
|
// to please eclipse, not supposed to be serialized
|
||||||
private static final long serialVersionUID = 8500214871372184418L;
|
private static final long serialVersionUID = 8500214871372184418L;
|
||||||
|
|
||||||
@@ -92,7 +88,7 @@ public class Display extends JFrame {
|
|||||||
|
|
||||||
private MazeComponent createMazeComponent(LabyModel model, int W, int H) {
|
private MazeComponent createMazeComponent(LabyModel model, int W, int H) {
|
||||||
MazeCellParameters cp = new MazeCellParameters(model.getWidth(), model.getHeight(), W, H, 3, 3);
|
MazeCellParameters cp = new MazeCellParameters(model.getWidth(), model.getHeight(), W, H, 3, 3);
|
||||||
MazeComponent comp = new MazeComponent(model, cp);
|
MazeComponent comp = new MazeComponent(model, cp, this);
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +328,7 @@ public class Display extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addStatus(String pStatus)
|
public void addStatus(String pStatus)
|
||||||
{
|
{
|
||||||
if ( statusEnable ) {
|
if ( statusEnable ) {
|
||||||
statusField.setText(pStatus);
|
statusField.setText(pStatus);
|
||||||
@@ -400,6 +396,27 @@ public class Display extends JFrame {
|
|||||||
loadImcButton.addActionListener(loadImcAction);
|
loadImcButton.addActionListener(loadImcAction);
|
||||||
|
|
||||||
loadMenu.add(loadImcButton);
|
loadMenu.add(loadImcButton);
|
||||||
|
|
||||||
|
Action loadOsmAction = new AbstractAction() {
|
||||||
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
//
|
||||||
|
addStatus("load Osm");
|
||||||
|
|
||||||
|
String filename = loadName.getText();
|
||||||
|
|
||||||
|
if ((filename.length() > 0)) {
|
||||||
|
setMazeName(filename);
|
||||||
|
loadOsm(false);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
JButton loadOsmButton = new JButton(labels.getString("load" ) + " Osm");
|
||||||
|
loadOsmButton.addActionListener(loadOsmAction);
|
||||||
|
|
||||||
|
loadMenu.add(loadOsmButton);
|
||||||
|
|
||||||
return loadMenu;
|
return loadMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,6 +692,40 @@ public class Display extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadOsm(boolean add) {
|
||||||
|
if ( maze != null ) {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
File infile = new File(params.getSaveDir(), params.getName() + ".osm");
|
||||||
|
FileInputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
// TODO really use InputStream and not pathname
|
||||||
|
OsmToDrawing converter = new OsmToDrawing(43.6399000, 7.0058300, 10000,10000);
|
||||||
|
OsmReader reader = new OsmReader(infile.getCanonicalPath());
|
||||||
|
reader.read();
|
||||||
|
Drawing drawing = converter.getDrawing(reader.getWays());
|
||||||
|
statusEnable = false;
|
||||||
|
maze.addDrawing(drawing,add);
|
||||||
|
statusEnable = true;
|
||||||
|
} catch (IOException io) {
|
||||||
|
io.printStackTrace(System.err);
|
||||||
|
statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath());
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
// cleanup
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (Exception any) {
|
||||||
|
// don't care really
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadImc(boolean add) {
|
private void loadImc(boolean add) {
|
||||||
if ( maze != null ) {
|
if ( maze != null ) {
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@@ -720,497 +771,6 @@ public class Display extends JFrame {
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MazeCellParameters {
|
|
||||||
double width = 10; // width of one cell
|
|
||||||
double height = 10; // height of one cell
|
|
||||||
int offsetX = 5; // x offset of upper corner left
|
|
||||||
int offsetY = 5; // y offset of upper corner left
|
|
||||||
|
|
||||||
int mapWidth = 0;
|
|
||||||
int mapHeight = 0;
|
|
||||||
|
|
||||||
public MazeCellParameters(int mapw, int maph, int W, int H, int x, int y) {
|
|
||||||
double w = (W - x) / mapw;
|
|
||||||
double h = (H - y) / maph;
|
|
||||||
mapWidth = mapw;
|
|
||||||
mapHeight = maph;
|
|
||||||
if (w < 5)
|
|
||||||
w = 5;
|
|
||||||
if (h < 5)
|
|
||||||
h = 5;
|
|
||||||
setCellSize(w, h);
|
|
||||||
offsetX = x;
|
|
||||||
offsetY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetMazeWidthHeight(int mapw, int maph) {
|
|
||||||
mapWidth = mapw;
|
|
||||||
mapHeight = maph;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void adaptTo(double W, double H) {
|
|
||||||
double w = (W - offsetX) / mapWidth;
|
|
||||||
double h = (H - offsetY) / mapHeight;
|
|
||||||
mapWidth = mapWidth;
|
|
||||||
mapHeight = mapHeight;
|
|
||||||
if (w < 5)
|
|
||||||
w = 5;
|
|
||||||
if (h < 5)
|
|
||||||
h = 5;
|
|
||||||
setCellSize(w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCellSize(double w, double h) {
|
|
||||||
width = w;
|
|
||||||
height = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getWidth() {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOffsetX() {
|
|
||||||
return offsetX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOffsetY() {
|
|
||||||
return offsetY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dimension getDimension() {
|
|
||||||
return new Dimension(offsetX + (int) (mapWidth * width),
|
|
||||||
offsetY + (int) (mapHeight * height));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawWalls(Graphics g, int pX, int pY, short walls) {
|
|
||||||
int x = offsetX + (int) (pX * width);
|
|
||||||
int y = offsetY + (int) (pY * height);
|
|
||||||
if ((pY == 0) && ((walls & Brick.UP) == Brick.UP))
|
|
||||||
g.drawLine(x, y, x + (int) width, y);
|
|
||||||
if ((walls & Brick.DOWN) == Brick.DOWN)
|
|
||||||
g.drawLine(x, y + (int) height, x + (int) width, y + (int) height);
|
|
||||||
if ((walls & Brick.RIGHT) == Brick.RIGHT)
|
|
||||||
g.drawLine(x + (int) width, y, x + (int) width, y + (int) height);
|
|
||||||
if ((pX == 0) && ((walls & Brick.LEFT) == Brick.LEFT))
|
|
||||||
g.drawLine(x, y, x, y + (int) height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawPath(Graphics g, DirectionPosition dp, int pX, int pY, int mX, int mY) {
|
|
||||||
if (dp != null) {
|
|
||||||
Position dot = dp.getPosition();
|
|
||||||
if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) {
|
|
||||||
int x = offsetX + (int) (dot.getX() * width);
|
|
||||||
int y = offsetY + (int) (dot.getY() * height);
|
|
||||||
short path = dp.getDirection();
|
|
||||||
int xm = x + (int) (width / 2);
|
|
||||||
int ym = y + (int) (height / 2);
|
|
||||||
if ((path & LabyModel.HORIZONTAL) == LabyModel.HORIZONTAL) {
|
|
||||||
if ((path & LabyModel.POSITIVE) == LabyModel.POSITIVE) {
|
|
||||||
g.drawLine(xm, ym, x + (int) width, ym);
|
|
||||||
g.drawLine(xm, ym + (int) (height / 4), x + (int) width, ym);
|
|
||||||
}
|
|
||||||
// LEFT /_
|
|
||||||
if ((path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE) {
|
|
||||||
g.drawLine(x, ym, xm, ym);
|
|
||||||
g.drawLine(x, ym, xm, ym - (int) (height / 4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((path & LabyModel.VERTICAL) == LabyModel.VERTICAL) {
|
|
||||||
if ((path & LabyModel.POSITIVE) == LabyModel.POSITIVE) {
|
|
||||||
g.drawLine(xm, ym, xm, y + (int) height);
|
|
||||||
g.drawLine(xm - (int) (width / 4), ym, xm, y + (int) height);
|
|
||||||
}
|
|
||||||
// UP |\
|
|
||||||
if ((path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE) {
|
|
||||||
g.drawLine(xm, ym, xm, y);
|
|
||||||
g.drawLine(xm + (int) (width / 4), ym, xm, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY) {
|
|
||||||
double radius = (height > width) ? width : height;
|
|
||||||
int a = (int) (radius / 4);
|
|
||||||
if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) {
|
|
||||||
int x = offsetX + (int) (dot.getX() * width);
|
|
||||||
int y = offsetY + (int) (dot.getY() * height);
|
|
||||||
int r2 = (int) ((radius * 3) / 4);
|
|
||||||
g.drawOval(x + 1, y + 1, r2, r2);
|
|
||||||
// g.drawLine(x+a,y+a,x+width-a,y+height-a);
|
|
||||||
// g.drawLine(x+a,y+height-a,x+width-a,y+a);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
int x = offsetX + (int) (pX * width);
|
|
||||||
int y = offsetY + (int) (pY * height);
|
|
||||||
g.drawLine(x + 1, y + 1, x + (int) width - 1, y + (int) height - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MazeComponent
|
|
||||||
extends JComponent
|
|
||||||
implements MazeCreationListener,
|
|
||||||
MazeResolutionListener,
|
|
||||||
MouseMotionListener {
|
|
||||||
private static final long serialVersionUID = 3163272907991176390L;
|
|
||||||
|
|
||||||
// WallsProvider map;
|
|
||||||
LabyModel map;
|
|
||||||
final MazeCellParameters cp;
|
|
||||||
Position current = null;
|
|
||||||
LinkedList<DirectionPosition> solvedPath = null;
|
|
||||||
LinkedList<DirectionPosition> drawingPath = null;
|
|
||||||
final Object lockChange = new Object();
|
|
||||||
// current postion of human resolving
|
|
||||||
int sX = 0;
|
|
||||||
int sY = 0;
|
|
||||||
// goal exit
|
|
||||||
int gX = -1;
|
|
||||||
int gY = -1;
|
|
||||||
|
|
||||||
Date lastDrag = null;
|
|
||||||
// FIXME HARCDODED delay after which a draging to draw a continous line is ended, a new line will then start.
|
|
||||||
long dragTimeout = 200;
|
|
||||||
|
|
||||||
// not set by default for debug, will show any path
|
|
||||||
boolean showAll = false;
|
|
||||||
|
|
||||||
// for a given (x,y) pixel return cell position.
|
|
||||||
// if rightmost position of view not (0,0) this is not working.
|
|
||||||
Position getPosition(int x, int y) {
|
|
||||||
int pX = (int) ((double) (x - cp.getOffsetX()) / cp.getWidth());
|
|
||||||
int pY = (int) ((double) (y - cp.getOffsetY()) / cp.getHeight());
|
|
||||||
return new Position(pX, pY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(MouseEvent e) {
|
|
||||||
boolean add = ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0);
|
|
||||||
Position newPosition = getPosition(e.getX(), e.getY());
|
|
||||||
Date now = new Date(System.currentTimeMillis());
|
|
||||||
if (lastDrag == null )
|
|
||||||
{
|
|
||||||
resetDrawingPath();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( now.getTime() - lastDrag.getTime() > dragTimeout )
|
|
||||||
{
|
|
||||||
resetDrawingPath();
|
|
||||||
addStatus("move timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastDrag = now;
|
|
||||||
addPosition(newPosition,add);
|
|
||||||
changed(null, null, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetDrawingPath()
|
|
||||||
{
|
|
||||||
drawingPath = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addDrawing(Drawing drawing, boolean add)
|
|
||||||
{
|
|
||||||
for (DrawingLine line : drawing.getInternLines())
|
|
||||||
{
|
|
||||||
addDrawingLine(line, add);
|
|
||||||
}
|
|
||||||
changed(null, null, map);
|
|
||||||
}
|
|
||||||
public void addDrawingLine(DrawingLine line, boolean add)
|
|
||||||
{
|
|
||||||
resetDrawingPath();
|
|
||||||
ArrayList<Point> points = line.getPoints();
|
|
||||||
for (Point p : points)
|
|
||||||
{
|
|
||||||
addPosition(new Position(p.x,p.y), add);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPosition(Position newPosition, boolean add ) {
|
|
||||||
// should find the cell ...
|
|
||||||
DirectionPosition last = null;
|
|
||||||
short path = 0;
|
|
||||||
if (drawingPath == null) {
|
|
||||||
drawingPath = new LinkedList<>();
|
|
||||||
last = new DirectionPosition((short) 0, newPosition);
|
|
||||||
if ( statusEnable) {
|
|
||||||
addStatus("Mouse dragged Cell " + newPosition + " Button " + add);
|
|
||||||
}
|
|
||||||
drawingPath.addLast(last);
|
|
||||||
} else {
|
|
||||||
// setShowAll(true);
|
|
||||||
DirectionPosition first = drawingPath.getLast();
|
|
||||||
last = first;
|
|
||||||
// construct as many move form last to new position as needed.
|
|
||||||
while (!last.getPosition().equals(newPosition)) {
|
|
||||||
path = LabyModel.getDirection(last.getPosition(), newPosition);
|
|
||||||
last.setDirection(path);
|
|
||||||
// button 1 : add direction; button 2 : rep lace with direction.
|
|
||||||
if (add) {
|
|
||||||
map.addDirection(last.getPosition().getX(), last.getPosition().getY(), path);
|
|
||||||
} else {
|
|
||||||
map.setDirection(last.getPosition().getX(), last.getPosition().getY(), path);
|
|
||||||
}
|
|
||||||
last = last.moveToAdjacentDirection();
|
|
||||||
drawingPath.addLast(last);
|
|
||||||
}
|
|
||||||
if (statusEnable) {
|
|
||||||
addStatus("Mouse dragged from Cell " + first.getPosition() + "To" + newPosition + " Button " + add);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseMoved(MouseEvent e) {
|
|
||||||
// addStatus("Mouse moved (" + e.getX() + ',' + e.getY() + ')');
|
|
||||||
Position newPosition = getPosition(e.getX(), e.getY());
|
|
||||||
if ((newPosition.getX() >= 0) && (newPosition.getY() >= 0)) {
|
|
||||||
requestFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShowAll(boolean showall) {
|
|
||||||
this.showAll = showall;
|
|
||||||
addStatus(showAll ? "show all" : "X");
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkExit() {
|
|
||||||
if ((sX == gX) && (sY == gY)) {
|
|
||||||
addStatus("Exit found by human !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void proceed()
|
|
||||||
{
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
checkExit();
|
|
||||||
}
|
|
||||||
void goNorth() {
|
|
||||||
resetResolution();
|
|
||||||
if (map.canMoveInDirection(sX, sY,Brick.UP)) {
|
|
||||||
sY = sY - 1;
|
|
||||||
proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void goSouth() {
|
|
||||||
resetResolution();
|
|
||||||
if (map.canMoveInDirection(sX, sY,Brick.DOWN)) {
|
|
||||||
sY = sY + 1;
|
|
||||||
proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void goEast() {
|
|
||||||
resetResolution();
|
|
||||||
if (map.canMoveInDirection(sX, sY, Brick.RIGHT)) {
|
|
||||||
sX = sX + 1;
|
|
||||||
proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void goWest() {
|
|
||||||
resetResolution();
|
|
||||||
if (map.canMoveInDirection(sX, sY, Brick.LEFT)) {
|
|
||||||
sX = sX - 1;
|
|
||||||
proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* width, height of one cell,
|
|
||||||
* offsetX, offsetY of upper left corner
|
|
||||||
**/
|
|
||||||
// public MazeComponent(WallsProvider map, MazeCellParameters cp)
|
|
||||||
public MazeComponent(LabyModel map, MazeCellParameters cp) {
|
|
||||||
super();
|
|
||||||
this.cp = cp;
|
|
||||||
this.map = map;
|
|
||||||
setPreferredSize(cp.getDimension());
|
|
||||||
gX = map.getWidth() - 1;
|
|
||||||
gY = map.getHeight() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void resetWallsProvider(WallsProvider map)
|
|
||||||
public void resetWallsProvider(LabyModel map) {
|
|
||||||
this.map = map;
|
|
||||||
solvedPath = null;
|
|
||||||
// could be kept
|
|
||||||
drawingPath = null;
|
|
||||||
sX = 0;
|
|
||||||
sY = 0;
|
|
||||||
cp.resetMazeWidthHeight(map.getWidth(), map.getHeight());
|
|
||||||
setPreferredSize(cp.getDimension());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWallSize(int size) {
|
|
||||||
cp.setCellSize((double) size, (double) size);
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAutoSize() {
|
|
||||||
Rectangle r = getBounds();
|
|
||||||
cp.adaptTo((int) r.getWidth(), (int) r.getHeight());
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
return 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changed(Position cl, Position cr, WallsProvider map) {
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
Object waiter = new Object();
|
|
||||||
synchronized (waiter) {
|
|
||||||
try {
|
|
||||||
waiter.wait(10);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
System.err.println("Interrupted !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
short walls = 0;
|
|
||||||
short path = 0;
|
|
||||||
|
|
||||||
// try to display only visible part...
|
|
||||||
// should compute pX, pY, mX, mY based on clip...
|
|
||||||
// Shape s=g.getClip();
|
|
||||||
Rectangle r = g.getClipBounds();
|
|
||||||
|
|
||||||
int mX = (int) ((double) r.getWidth() / cp.getWidth());
|
|
||||||
int mY = (int) ((double) r.getHeight() / cp.getHeight());
|
|
||||||
int pX = (int) ((double) (r.getX() - cp.getOffsetX()) / cp.getWidth());
|
|
||||||
int pY = (int) ((double) (r.getY() - cp.getOffsetY()) / cp.getHeight());
|
|
||||||
|
|
||||||
if (pX < 0)
|
|
||||||
pX = 0;
|
|
||||||
if (pY < 0)
|
|
||||||
pY = 0;
|
|
||||||
if (pX >= map.getWidth())
|
|
||||||
return;
|
|
||||||
if (pY >= map.getHeight())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mX = mX + pX;
|
|
||||||
mY = mY + pY;
|
|
||||||
|
|
||||||
if (mX > map.getWidth()) {
|
|
||||||
mX = map.getWidth();
|
|
||||||
}
|
|
||||||
if (mY > map.getHeight()) {
|
|
||||||
mY = map.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((sX == gX) && (sY == gY)) {
|
|
||||||
g.setColor(Color.red);
|
|
||||||
} else {
|
|
||||||
g.setColor(Color.green);
|
|
||||||
cp.drawDot(g, new Position(gX, gY), pX, pY, mX, mY);
|
|
||||||
g.setColor(Color.blue);
|
|
||||||
}
|
|
||||||
cp.drawDot(g, new Position(sX, sY), pX, pY, mX, mY);
|
|
||||||
|
|
||||||
synchronized (lockChange) {
|
|
||||||
g.setColor(Color.red);
|
|
||||||
if (current != null) {
|
|
||||||
cp.drawDot(g, current, pX, pY, mX, mY);
|
|
||||||
}
|
|
||||||
if (solvedPath != null) {
|
|
||||||
for (DirectionPosition resolved : solvedPath) {
|
|
||||||
// cp.drawDot(g, resolved.getPosition(), pX, pY, mX, mY);
|
|
||||||
cp.drawPath(g, resolved, pX, pY, mX, mY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int aX = pX;
|
|
||||||
int aY = pY;
|
|
||||||
|
|
||||||
g.setColor(Color.black);
|
|
||||||
|
|
||||||
// draw all walls within clip bounds horiz first then lines
|
|
||||||
for (; pY < mY; pY++) {
|
|
||||||
for (pX = 0; pX < mX; pX++) {
|
|
||||||
walls = map.getWalls(pX, pY);
|
|
||||||
cp.drawWalls(g, pX, pY, walls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.showAll) {
|
|
||||||
addStatus("*");
|
|
||||||
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) {
|
|
||||||
DirectionPosition dp = new DirectionPosition(path, new Position(pX, pY));
|
|
||||||
cp.drawPath(g, dp, pX, pY, pX + 1, pY + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean notifySearch(DirectionPosition pPosition) {
|
|
||||||
synchronized (lockChange) {
|
|
||||||
current = pPosition.getPosition();
|
|
||||||
}
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifySearchError(String error) {
|
|
||||||
System.err.println(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyCompletion(LinkedList<DirectionPosition> solvedPath) {
|
|
||||||
LinkedList<DirectionPosition> newPath = new LinkedList<>(solvedPath);
|
|
||||||
addStatus("resolution completed");
|
|
||||||
synchronized (lockChange) {
|
|
||||||
this.solvedPath = newPath;
|
|
||||||
}
|
|
||||||
// should redraw ...
|
|
||||||
invalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetResolution() {
|
|
||||||
solvedPath = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setupDisplay(LabyModel model, int W, int H, MazeParams params) {
|
private static void setupDisplay(LabyModel model, int W, int H, MazeParams params) {
|
||||||
Display display = new Display(model, W, H, params);
|
Display display = new Display(model, W, H, params);
|
||||||
}
|
}
|
||||||
|
|||||||
142
java/org/artisanlogiciel/games/maze/gui/MazeCellParameters.java
Normal file
142
java/org/artisanlogiciel/games/maze/gui/MazeCellParameters.java
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package org.artisanlogiciel.games.maze.gui;
|
||||||
|
|
||||||
|
import org.artisanlogiciel.games.maze.Brick;
|
||||||
|
import org.artisanlogiciel.games.maze.LabyModel;
|
||||||
|
import org.artisanlogiciel.games.maze.Position;
|
||||||
|
import org.artisanlogiciel.games.maze.solve.DirectionPosition;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
public class MazeCellParameters {
|
||||||
|
double width = 10; // width of one cell
|
||||||
|
double height = 10; // height of one cell
|
||||||
|
int offsetX = 5; // x offset of upper corner left
|
||||||
|
int offsetY = 5; // y offset of upper corner left
|
||||||
|
|
||||||
|
int mapWidth = 0;
|
||||||
|
int mapHeight = 0;
|
||||||
|
|
||||||
|
public MazeCellParameters(int mapw, int maph, int W, int H, int x, int y) {
|
||||||
|
double w = (W - x) / mapw;
|
||||||
|
double h = (H - y) / maph;
|
||||||
|
mapWidth = mapw;
|
||||||
|
mapHeight = maph;
|
||||||
|
if (w < 5)
|
||||||
|
w = 5;
|
||||||
|
if (h < 5)
|
||||||
|
h = 5;
|
||||||
|
setCellSize(w, h);
|
||||||
|
offsetX = x;
|
||||||
|
offsetY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetMazeWidthHeight(int mapw, int maph) {
|
||||||
|
mapWidth = mapw;
|
||||||
|
mapHeight = maph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void adaptTo(double W, double H) {
|
||||||
|
double w = (W - offsetX) / mapWidth;
|
||||||
|
double h = (H - offsetY) / mapHeight;
|
||||||
|
mapWidth = mapWidth;
|
||||||
|
mapHeight = mapHeight;
|
||||||
|
if (w < 5)
|
||||||
|
w = 5;
|
||||||
|
if (h < 5)
|
||||||
|
h = 5;
|
||||||
|
setCellSize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellSize(double w, double h) {
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffsetX() {
|
||||||
|
return offsetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffsetY() {
|
||||||
|
return offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dimension getDimension() {
|
||||||
|
return new Dimension(offsetX + (int) (mapWidth * width),
|
||||||
|
offsetY + (int) (mapHeight * height));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawWalls(Graphics g, int pX, int pY, short walls) {
|
||||||
|
int x = offsetX + (int) (pX * width);
|
||||||
|
int y = offsetY + (int) (pY * height);
|
||||||
|
if ((pY == 0) && ((walls & Brick.UP) == Brick.UP))
|
||||||
|
g.drawLine(x, y, x + (int) width, y);
|
||||||
|
if ((walls & Brick.DOWN) == Brick.DOWN)
|
||||||
|
g.drawLine(x, y + (int) height, x + (int) width, y + (int) height);
|
||||||
|
if ((walls & Brick.RIGHT) == Brick.RIGHT)
|
||||||
|
g.drawLine(x + (int) width, y, x + (int) width, y + (int) height);
|
||||||
|
if ((pX == 0) && ((walls & Brick.LEFT) == Brick.LEFT))
|
||||||
|
g.drawLine(x, y, x, y + (int) height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawPath(Graphics g, DirectionPosition dp, int pX, int pY, int mX, int mY) {
|
||||||
|
if (dp != null) {
|
||||||
|
Position dot = dp.getPosition();
|
||||||
|
if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) {
|
||||||
|
int x = offsetX + (int) (dot.getX() * width);
|
||||||
|
int y = offsetY + (int) (dot.getY() * height);
|
||||||
|
short path = dp.getDirection();
|
||||||
|
int xm = x + (int) (width / 2);
|
||||||
|
int ym = y + (int) (height / 2);
|
||||||
|
if ((path & LabyModel.HORIZONTAL) == LabyModel.HORIZONTAL) {
|
||||||
|
if ((path & LabyModel.POSITIVE) == LabyModel.POSITIVE) {
|
||||||
|
g.drawLine(xm, ym, x + (int) width, ym);
|
||||||
|
g.drawLine(xm, ym + (int) (height / 4), x + (int) width, ym);
|
||||||
|
}
|
||||||
|
// LEFT /_
|
||||||
|
if ((path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE) {
|
||||||
|
g.drawLine(x, ym, xm, ym);
|
||||||
|
g.drawLine(x, ym, xm, ym - (int) (height / 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((path & LabyModel.VERTICAL) == LabyModel.VERTICAL) {
|
||||||
|
if ((path & LabyModel.POSITIVE) == LabyModel.POSITIVE) {
|
||||||
|
g.drawLine(xm, ym, xm, y + (int) height);
|
||||||
|
g.drawLine(xm - (int) (width / 4), ym, xm, y + (int) height);
|
||||||
|
}
|
||||||
|
// UP |\
|
||||||
|
if ((path & LabyModel.NEGATIVE) == LabyModel.NEGATIVE) {
|
||||||
|
g.drawLine(xm, ym, xm, y);
|
||||||
|
g.drawLine(xm + (int) (width / 4), ym, xm, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawDot(Graphics g, Position dot, int pX, int pY, int mX, int mY) {
|
||||||
|
double radius = (height > width) ? width : height;
|
||||||
|
int a = (int) (radius / 4);
|
||||||
|
if ((dot.getX() >= pX) && (dot.getY() >= pY) && (dot.getX() < mX) && (dot.getY() < mY)) {
|
||||||
|
int x = offsetX + (int) (dot.getX() * width);
|
||||||
|
int y = offsetY + (int) (dot.getY() * height);
|
||||||
|
int r2 = (int) ((radius * 3) / 4);
|
||||||
|
g.drawOval(x + 1, y + 1, r2, r2);
|
||||||
|
// g.drawLine(x+a,y+a,x+width-a,y+height-a);
|
||||||
|
// g.drawLine(x+a,y+height-a,x+width-a,y+a);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int x = offsetX + (int) (pX * width);
|
||||||
|
int y = offsetY + (int) (pY * height);
|
||||||
|
g.drawLine(x + 1, y + 1, x + (int) width - 1, y + (int) height - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
367
java/org/artisanlogiciel/games/maze/gui/MazeComponent.java
Normal file
367
java/org/artisanlogiciel/games/maze/gui/MazeComponent.java
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
package org.artisanlogiciel.games.maze.gui;
|
||||||
|
|
||||||
|
import org.artisanlogiciel.games.maze.*;
|
||||||
|
import org.artisanlogiciel.games.maze.solve.DirectionPosition;
|
||||||
|
import org.artisanlogiciel.games.maze.solve.MazeResolutionListener;
|
||||||
|
import org.artisanlogiciel.graphics.Drawing;
|
||||||
|
import org.artisanlogiciel.graphics.DrawingLine;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseMotionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class MazeComponent
|
||||||
|
extends JComponent
|
||||||
|
implements MazeCreationListener,
|
||||||
|
MazeResolutionListener,
|
||||||
|
MouseMotionListener {
|
||||||
|
private static final long serialVersionUID = 3163272907991176390L;
|
||||||
|
|
||||||
|
// WallsProvider map;
|
||||||
|
LabyModel map;
|
||||||
|
final MazeCellParameters cp;
|
||||||
|
Position current = null;
|
||||||
|
LinkedList<DirectionPosition> solvedPath = null;
|
||||||
|
LinkedList<DirectionPosition> drawingPath = null;
|
||||||
|
final Object lockChange = new Object();
|
||||||
|
// current postion of human resolving
|
||||||
|
int sX = 0;
|
||||||
|
int sY = 0;
|
||||||
|
// goal exit
|
||||||
|
int gX = -1;
|
||||||
|
int gY = -1;
|
||||||
|
|
||||||
|
Date lastDrag = null;
|
||||||
|
// FIXME HARCDODED delay after which a draging to draw a continous line is ended, a new line will then start.
|
||||||
|
long dragTimeout = 200;
|
||||||
|
|
||||||
|
// not set by default for debug, will show any path
|
||||||
|
boolean showAll = false;
|
||||||
|
|
||||||
|
StatusListener statusListener;
|
||||||
|
|
||||||
|
// for a given (x,y) pixel return cell position.
|
||||||
|
// if rightmost position of view not (0,0) this is not working.
|
||||||
|
Position getPosition(int x, int y) {
|
||||||
|
int pX = (int) ((double) (x - cp.getOffsetX()) / cp.getWidth());
|
||||||
|
int pY = (int) ((double) (y - cp.getOffsetY()) / cp.getHeight());
|
||||||
|
return new Position(pX, pY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
boolean add = ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0);
|
||||||
|
Position newPosition = getPosition(e.getX(), e.getY());
|
||||||
|
Date now = new Date(System.currentTimeMillis());
|
||||||
|
if (lastDrag == null) {
|
||||||
|
resetDrawingPath();
|
||||||
|
} else {
|
||||||
|
if (now.getTime() - lastDrag.getTime() > dragTimeout) {
|
||||||
|
resetDrawingPath();
|
||||||
|
statusListener.addStatus("move timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastDrag = now;
|
||||||
|
addPosition(newPosition, add);
|
||||||
|
changed(null, null, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetDrawingPath() {
|
||||||
|
drawingPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDrawing(Drawing drawing, boolean add) {
|
||||||
|
for (DrawingLine line : drawing.getInternLines()) {
|
||||||
|
addDrawingLine(line, add);
|
||||||
|
}
|
||||||
|
changed(null, null, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDrawingLine(DrawingLine line, boolean add) {
|
||||||
|
resetDrawingPath();
|
||||||
|
ArrayList<Point> points = line.getPoints();
|
||||||
|
for (Point p : points) {
|
||||||
|
addPosition(new Position(p.x, p.y), add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPosition(Position newPosition, boolean add) {
|
||||||
|
// should find the cell ...
|
||||||
|
DirectionPosition last = null;
|
||||||
|
short path = 0;
|
||||||
|
if (drawingPath == null) {
|
||||||
|
drawingPath = new LinkedList<>();
|
||||||
|
last = new DirectionPosition((short) 0, newPosition);
|
||||||
|
statusListener.addStatus("Mouse dragged Cell " + newPosition + " Button " + add);
|
||||||
|
drawingPath.addLast(last);
|
||||||
|
} else {
|
||||||
|
// setShowAll(true);
|
||||||
|
DirectionPosition first = drawingPath.getLast();
|
||||||
|
last = first;
|
||||||
|
// construct as many move form last to new position as needed.
|
||||||
|
while (!last.getPosition().equals(newPosition)) {
|
||||||
|
path = LabyModel.getDirection(last.getPosition(), newPosition);
|
||||||
|
last.setDirection(path);
|
||||||
|
// button 1 : add direction; button 2 : rep lace with direction.
|
||||||
|
if (add) {
|
||||||
|
map.addDirection(last.getPosition().getX(), last.getPosition().getY(), path);
|
||||||
|
} else {
|
||||||
|
map.setDirection(last.getPosition().getX(), last.getPosition().getY(), path);
|
||||||
|
}
|
||||||
|
last = last.moveToAdjacentDirection();
|
||||||
|
drawingPath.addLast(last);
|
||||||
|
}
|
||||||
|
statusListener.addStatus("Mouse dragged from Cell " + first.getPosition() + "To" + newPosition + " Button " + add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
// addStatus("Mouse moved (" + e.getX() + ',' + e.getY() + ')');
|
||||||
|
Position newPosition = getPosition(e.getX(), e.getY());
|
||||||
|
if ((newPosition.getX() >= 0) && (newPosition.getY() >= 0)) {
|
||||||
|
requestFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowAll(boolean showall) {
|
||||||
|
this.showAll = showall;
|
||||||
|
statusListener.addStatus(showAll ? "show all" : "X");
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkExit() {
|
||||||
|
if ((sX == gX) && (sY == gY)) {
|
||||||
|
statusListener.addStatus("Exit found by human !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void proceed() {
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
checkExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void goNorth() {
|
||||||
|
resetResolution();
|
||||||
|
if (map.canMoveInDirection(sX, sY, Brick.UP)) {
|
||||||
|
sY = sY - 1;
|
||||||
|
proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void goSouth() {
|
||||||
|
resetResolution();
|
||||||
|
if (map.canMoveInDirection(sX, sY, Brick.DOWN)) {
|
||||||
|
sY = sY + 1;
|
||||||
|
proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void goEast() {
|
||||||
|
resetResolution();
|
||||||
|
if (map.canMoveInDirection(sX, sY, Brick.RIGHT)) {
|
||||||
|
sX = sX + 1;
|
||||||
|
proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void goWest() {
|
||||||
|
resetResolution();
|
||||||
|
if (map.canMoveInDirection(sX, sY, Brick.LEFT)) {
|
||||||
|
sX = sX - 1;
|
||||||
|
proceed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* width, height of one cell,
|
||||||
|
* offsetX, offsetY of upper left corner
|
||||||
|
**/
|
||||||
|
// public MazeComponent(WallsProvider map, MazeCellParameters cp)
|
||||||
|
public MazeComponent(LabyModel map, MazeCellParameters cp, StatusListener statusListener) {
|
||||||
|
super();
|
||||||
|
this.cp = cp;
|
||||||
|
this.map = map;
|
||||||
|
setPreferredSize(cp.getDimension());
|
||||||
|
gX = map.getWidth() - 1;
|
||||||
|
gY = map.getHeight() - 1;
|
||||||
|
this.statusListener = statusListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void resetWallsProvider(WallsProvider map)
|
||||||
|
public void resetWallsProvider(LabyModel map) {
|
||||||
|
this.map = map;
|
||||||
|
solvedPath = null;
|
||||||
|
// could be kept
|
||||||
|
drawingPath = null;
|
||||||
|
sX = 0;
|
||||||
|
sY = 0;
|
||||||
|
cp.resetMazeWidthHeight(map.getWidth(), map.getHeight());
|
||||||
|
setPreferredSize(cp.getDimension());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWallSize(int size) {
|
||||||
|
cp.setCellSize((double) size, (double) size);
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAutoSize() {
|
||||||
|
Rectangle r = getBounds();
|
||||||
|
cp.adaptTo((int) r.getWidth(), (int) r.getHeight());
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
return 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changed(Position cl, Position cr, WallsProvider map) {
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
/* what was this ?
|
||||||
|
|
||||||
|
Object waiter = new Object();
|
||||||
|
synchronized (waiter) {
|
||||||
|
try {
|
||||||
|
waiter.wait(10);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.err.println("Interrupted !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
short walls = 0;
|
||||||
|
short path = 0;
|
||||||
|
|
||||||
|
// try to display only visible part...
|
||||||
|
// should compute pX, pY, mX, mY based on clip...
|
||||||
|
// Shape s=g.getClip();
|
||||||
|
Rectangle r = g.getClipBounds();
|
||||||
|
|
||||||
|
int mX = (int) ((double) r.getWidth() / cp.getWidth());
|
||||||
|
int mY = (int) ((double) r.getHeight() / cp.getHeight());
|
||||||
|
int pX = (int) ((double) (r.getX() - cp.getOffsetX()) / cp.getWidth());
|
||||||
|
int pY = (int) ((double) (r.getY() - cp.getOffsetY()) / cp.getHeight());
|
||||||
|
|
||||||
|
if (pX < 0)
|
||||||
|
pX = 0;
|
||||||
|
if (pY < 0)
|
||||||
|
pY = 0;
|
||||||
|
if (pX >= map.getWidth())
|
||||||
|
return;
|
||||||
|
if (pY >= map.getHeight())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mX = mX + pX;
|
||||||
|
mY = mY + pY;
|
||||||
|
|
||||||
|
if (mX > map.getWidth()) {
|
||||||
|
mX = map.getWidth();
|
||||||
|
}
|
||||||
|
if (mY > map.getHeight()) {
|
||||||
|
mY = map.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sX == gX) && (sY == gY)) {
|
||||||
|
g.setColor(Color.red);
|
||||||
|
} else {
|
||||||
|
g.setColor(Color.green);
|
||||||
|
cp.drawDot(g, new Position(gX, gY), pX, pY, mX, mY);
|
||||||
|
g.setColor(Color.blue);
|
||||||
|
}
|
||||||
|
cp.drawDot(g, new Position(sX, sY), pX, pY, mX, mY);
|
||||||
|
|
||||||
|
synchronized (lockChange) {
|
||||||
|
g.setColor(Color.red);
|
||||||
|
if (current != null) {
|
||||||
|
cp.drawDot(g, current, pX, pY, mX, mY);
|
||||||
|
}
|
||||||
|
if (solvedPath != null) {
|
||||||
|
for (DirectionPosition resolved : solvedPath) {
|
||||||
|
// cp.drawDot(g, resolved.getPosition(), pX, pY, mX, mY);
|
||||||
|
cp.drawPath(g, resolved, pX, pY, mX, mY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int aX = pX;
|
||||||
|
int aY = pY;
|
||||||
|
|
||||||
|
g.setColor(Color.black);
|
||||||
|
|
||||||
|
// draw all walls within clip bounds horiz first then lines
|
||||||
|
for (; pY < mY; pY++) {
|
||||||
|
for (pX = 0; pX < mX; pX++) {
|
||||||
|
walls = map.getWalls(pX, pY);
|
||||||
|
cp.drawWalls(g, pX, pY, walls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.showAll) {
|
||||||
|
statusListener.addStatus("*");
|
||||||
|
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) {
|
||||||
|
DirectionPosition dp = new DirectionPosition(path, new Position(pX, pY));
|
||||||
|
cp.drawPath(g, dp, pX, pY, pX + 1, pY + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean notifySearch(DirectionPosition pPosition) {
|
||||||
|
synchronized (lockChange) {
|
||||||
|
current = pPosition.getPosition();
|
||||||
|
}
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifySearchError(String error) {
|
||||||
|
System.err.println(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyCompletion(LinkedList<DirectionPosition> solvedPath) {
|
||||||
|
LinkedList<DirectionPosition> newPath = new LinkedList<>(solvedPath);
|
||||||
|
statusListener.addStatus("resolution completed");
|
||||||
|
synchronized (lockChange) {
|
||||||
|
this.solvedPath = newPath;
|
||||||
|
}
|
||||||
|
// should redraw ...
|
||||||
|
invalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetResolution() {
|
||||||
|
solvedPath = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.artisanlogiciel.games.maze.gui;
|
||||||
|
|
||||||
|
public interface StatusListener {
|
||||||
|
|
||||||
|
void addStatus(String pStatus);
|
||||||
|
|
||||||
|
}
|
||||||
2
java/org/artisanlogiciel/games/minetest/Node.java
Normal file
2
java/org/artisanlogiciel/games/minetest/Node.java
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
package org.artisanlogiciel.games.minetest;public class Node {
|
||||||
|
}
|
||||||
34
java/org/artisanlogiciel/osm/Node.java
Normal file
34
java/org/artisanlogiciel/osm/Node.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package org.artisanlogiciel.osm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://wiki.openstreetmap.org/wiki/Node
|
||||||
|
*/
|
||||||
|
public class Node {
|
||||||
|
NodeRef ref;
|
||||||
|
double lat;
|
||||||
|
double lon;
|
||||||
|
|
||||||
|
public NodeRef getRef() {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node(NodeRef ref, double lat, double lon) {
|
||||||
|
this.ref = ref;
|
||||||
|
ref.setNode(this);
|
||||||
|
this.lat = lat;
|
||||||
|
this.lon = lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLat() {
|
||||||
|
return lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getLon() {
|
||||||
|
return lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "(id=" + ref.id + " lon=" + lon + " lat=" + lat + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
37
java/org/artisanlogiciel/osm/NodeRef.java
Normal file
37
java/org/artisanlogiciel/osm/NodeRef.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package org.artisanlogiciel.osm;
|
||||||
|
|
||||||
|
public class NodeRef {
|
||||||
|
long id;
|
||||||
|
Node node;
|
||||||
|
|
||||||
|
public NodeRef(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNode(Node node) {
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getNode()
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return node != null ? node.toString(): "nd:" + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Long.hashCode(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( o instanceof NodeRef ) {
|
||||||
|
return ((NodeRef) o).id == id;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
109
java/org/artisanlogiciel/osm/OsmReader.java
Normal file
109
java/org/artisanlogiciel/osm/OsmReader.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package org.artisanlogiciel.osm;
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OsmReader {
|
||||||
|
|
||||||
|
private String sample;
|
||||||
|
|
||||||
|
private HashMap<NodeRef,Node> refs;
|
||||||
|
private List<Way> ways;
|
||||||
|
|
||||||
|
public OsmReader(String sample) {
|
||||||
|
this.sample = sample;
|
||||||
|
refs = new HashMap<>();
|
||||||
|
ways = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Way> getWays() {
|
||||||
|
return ways;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read()
|
||||||
|
{
|
||||||
|
/* TODO get minlat and minlon **/
|
||||||
|
DocumentBuilderFactory factory =
|
||||||
|
DocumentBuilderFactory.newInstance();
|
||||||
|
try {
|
||||||
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(new FileInputStream(sample));
|
||||||
|
Element root = doc.getDocumentElement();
|
||||||
|
System.out.println(root);
|
||||||
|
NodeList nList = doc.getElementsByTagName("node");
|
||||||
|
for (int temp = 0; temp < nList.getLength(); temp++) {
|
||||||
|
org.w3c.dom.Node nNode = nList.item(temp);
|
||||||
|
if (nNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
|
||||||
|
Element e = (Element) nNode;
|
||||||
|
long id = Long.valueOf(e.getAttribute("id"));
|
||||||
|
double lat = Double.valueOf(e.getAttribute("lat"));
|
||||||
|
double lon = Double.valueOf(e.getAttribute("lon"));
|
||||||
|
Node node = new Node(new NodeRef(id), lat, lon);
|
||||||
|
refs.put(node.getRef(),node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NodeList wList = doc.getElementsByTagName("way");
|
||||||
|
for (int temp = 0; temp < wList.getLength(); temp++) {
|
||||||
|
org.w3c.dom.Node wNode = wList.item(temp);
|
||||||
|
if (wNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
|
||||||
|
Element e = (Element) wNode;
|
||||||
|
try {
|
||||||
|
long id = Long.valueOf(e.getAttribute("id"));
|
||||||
|
List<NodeRef> nodeRefList = new ArrayList<>();
|
||||||
|
NodeList nrList = e.getElementsByTagName("nd");
|
||||||
|
for (int temp2 = 0; temp2 < nrList.getLength(); temp2++) {
|
||||||
|
org.w3c.dom.Node nrNode = nrList.item(temp2);
|
||||||
|
if (nrNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
|
||||||
|
Element nd = (Element) nrNode;
|
||||||
|
long ref = Long.valueOf(nd.getAttribute("ref"));
|
||||||
|
NodeRef nodeRef = new NodeRef(ref);
|
||||||
|
Node node = refs.get(nodeRef);
|
||||||
|
if ( node == null )
|
||||||
|
{
|
||||||
|
System.out.println("unknown node id " + nodeRef);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nodeRefList.add(node.getRef());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Way way = new Way(id, nodeRefList);
|
||||||
|
ways.add(way);
|
||||||
|
}
|
||||||
|
catch (Exception bad)
|
||||||
|
{
|
||||||
|
System.err.println("Too bad way");
|
||||||
|
bad.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception any)
|
||||||
|
{
|
||||||
|
System.err.println("Too bad");
|
||||||
|
any.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump()
|
||||||
|
{
|
||||||
|
System.out.println(refs);
|
||||||
|
System.out.println(ways);
|
||||||
|
}
|
||||||
|
public static void main(String pArgs[])
|
||||||
|
{
|
||||||
|
String sample = "/home/plhardy/valbonne3D/valbonne_oct_2020.osm";
|
||||||
|
|
||||||
|
OsmReader osmreader = new OsmReader(sample);
|
||||||
|
osmreader.read();
|
||||||
|
osmreader.dump();
|
||||||
|
}
|
||||||
|
}
|
||||||
22
java/org/artisanlogiciel/osm/Way.java
Normal file
22
java/org/artisanlogiciel/osm/Way.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package org.artisanlogiciel.osm;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Way {
|
||||||
|
long id;
|
||||||
|
|
||||||
|
public Way(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Way(long id, List<NodeRef> ndlist) {
|
||||||
|
this.id = id;
|
||||||
|
this.ndlist = ndlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NodeRef> getNdlist() {
|
||||||
|
return ndlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NodeRef> ndlist;
|
||||||
|
}
|
||||||
59
java/org/artisanlogiciel/osm/convert/OsmToDrawing.java
Normal file
59
java/org/artisanlogiciel/osm/convert/OsmToDrawing.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package org.artisanlogiciel.osm.convert;
|
||||||
|
|
||||||
|
import org.artisanlogiciel.graphics.Drawing;
|
||||||
|
import org.artisanlogiciel.graphics.DrawingLine;
|
||||||
|
import org.artisanlogiciel.osm.Node;
|
||||||
|
import org.artisanlogiciel.osm.NodeRef;
|
||||||
|
import org.artisanlogiciel.osm.Way;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a way with resolved ref ( ie with NodeRef having non null getNode() )
|
||||||
|
* and create a Drawing from it.
|
||||||
|
*/
|
||||||
|
public class OsmToDrawing {
|
||||||
|
|
||||||
|
double refx = 0;
|
||||||
|
double refy = 0;
|
||||||
|
int mulx = 1;
|
||||||
|
int muly = 1;
|
||||||
|
|
||||||
|
public OsmToDrawing()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmToDrawing(int mulx, int muly) {
|
||||||
|
this.mulx = mulx;
|
||||||
|
this.muly = muly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OsmToDrawing(double refx, double refy, int mulx, int muly) {
|
||||||
|
this.refx = refx;
|
||||||
|
this.refy = refy;
|
||||||
|
this.mulx = mulx;
|
||||||
|
this.muly = muly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrawingLine getDrawingLine(Way way)
|
||||||
|
{
|
||||||
|
DrawingLine drawingLine = new DrawingLine();
|
||||||
|
for (NodeRef nr : way.getNdlist())
|
||||||
|
{
|
||||||
|
Node node = nr.getNode();
|
||||||
|
drawingLine.addPoint(new Point((int) ( (node.getLat() - refx)* mulx ) , (int) ( (node.getLon() - refy ) * muly) ));
|
||||||
|
}
|
||||||
|
return drawingLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawing getDrawing(List<Way> ways)
|
||||||
|
{
|
||||||
|
Drawing drawing = new Drawing();
|
||||||
|
for (Way way : ways) {
|
||||||
|
drawing.addLine(getDrawingLine(way));
|
||||||
|
}
|
||||||
|
return drawing;
|
||||||
|
}
|
||||||
|
}
|
||||||
16376
lab/valbonne_oct_2020.osm
Normal file
16376
lab/valbonne_oct_2020.osm
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user