initial commit for labryinth project on git_hub.
Signed-off-by: philippe lhardy <philippe@pavilionartlogiciel>
This commit is contained in:
542
java/org/artisanlogiciel/games/Display.java
Normal file
542
java/org/artisanlogiciel/games/Display.java
Normal file
@@ -0,0 +1,542 @@
|
||||
package org.artisanlogiciel.games;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Container;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
Display
|
||||
**/
|
||||
public class Display extends JFrame
|
||||
|
||||
{
|
||||
Object param;
|
||||
JPanel pane = new JPanel();
|
||||
MazeComponent maze;
|
||||
MazeControler controler;
|
||||
LabyModel model;
|
||||
|
||||
Display(LabyModel model, MazeComponent comp)
|
||||
{
|
||||
super("Maze display");
|
||||
maze=comp;
|
||||
this.param=param;
|
||||
this.model=model;
|
||||
Container con = this.getContentPane();
|
||||
con.add(pane);
|
||||
con.add(new JScrollPane(comp), BorderLayout.CENTER);
|
||||
controler = new MazeControler();
|
||||
con.add(controler,BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
void resolve()
|
||||
{
|
||||
model.resolve(model.getWidth()-1,model.getHeight()-1,maze);
|
||||
}
|
||||
|
||||
void goNorth()
|
||||
{
|
||||
maze.goNorth();
|
||||
}
|
||||
|
||||
void goSouth()
|
||||
{
|
||||
maze.goSouth();
|
||||
}
|
||||
|
||||
void goEast()
|
||||
{
|
||||
maze.goEast();
|
||||
}
|
||||
|
||||
void goWest()
|
||||
{
|
||||
maze.goWest();
|
||||
}
|
||||
|
||||
void setWallSize(int size)
|
||||
{
|
||||
maze.setWallSize(size);
|
||||
}
|
||||
|
||||
private class MazeControler extends JPanel
|
||||
{
|
||||
public MazeControler()
|
||||
{
|
||||
JPanel controlPanel = new JPanel();
|
||||
JButton button=new JButton("Resolve");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
//
|
||||
System.out.println("Resolving");
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
JButton north = new JButton("North");
|
||||
Action goNorth = new AbstractAction()
|
||||
{
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
//
|
||||
System.out.println("go North");
|
||||
goNorth();
|
||||
}
|
||||
};
|
||||
KeyStroke kup=KeyStroke.getKeyStroke("UP");
|
||||
getInputMap().put(kup,"goNorth");
|
||||
getActionMap().put("goNorth",goNorth);
|
||||
controlPanel.getInputMap().put(kup,"goNorth");
|
||||
controlPanel.getActionMap().put("goNorth",goNorth);
|
||||
north.getActionMap().put("goNorth",goNorth);
|
||||
JButton east = new JButton("East");
|
||||
Action goEast = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
//
|
||||
System.out.println("go East");
|
||||
goEast();
|
||||
}
|
||||
};
|
||||
east.addActionListener(goEast);
|
||||
KeyStroke kright=KeyStroke.getKeyStroke("RIGHT");
|
||||
getInputMap().put(kright,"goEast");
|
||||
getActionMap().put("goEast",goEast);
|
||||
controlPanel.getInputMap().put(kright,"goEast");
|
||||
controlPanel.getActionMap().put("goEast",goEast);
|
||||
JButton west = new JButton("West");
|
||||
Action goWest = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
//
|
||||
System.out.println("go West");
|
||||
goWest();
|
||||
}
|
||||
};
|
||||
west.addActionListener(goWest);
|
||||
KeyStroke kwest=KeyStroke.getKeyStroke("LEFT");
|
||||
getInputMap().put(kwest,"goWest");
|
||||
getActionMap().put("goWest",goWest);
|
||||
controlPanel.getInputMap().put(kwest,"goWest");
|
||||
controlPanel.getActionMap().put("goWest",goWest);
|
||||
JButton south = new JButton("South");
|
||||
Action goSouth = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
//
|
||||
System.out.println("go South");
|
||||
goSouth();
|
||||
}
|
||||
};
|
||||
south.addActionListener(goSouth);
|
||||
KeyStroke kdown=KeyStroke.getKeyStroke("DOWN");
|
||||
controlPanel.getInputMap().put(kdown,"goSouth");
|
||||
controlPanel.getActionMap().put("goSouth",goSouth);
|
||||
getInputMap().put(KeyStroke.getKeyStroke("DOWN"),"goSouth");
|
||||
getActionMap().put("goSouth",goSouth);
|
||||
controlPanel.getInputMap().put(KeyStroke.getKeyStroke("DOWN"),"goSouth");
|
||||
controlPanel.getActionMap().put("goSouth",goSouth);
|
||||
|
||||
controlPanel.add(button,BorderLayout.NORTH);
|
||||
controlPanel.add(north,BorderLayout.NORTH);
|
||||
controlPanel.add(east,BorderLayout.EAST);
|
||||
controlPanel.add(west,BorderLayout.WEST);
|
||||
controlPanel.add(south,BorderLayout.SOUTH);
|
||||
add(controlPanel,BorderLayout.NORTH);
|
||||
final JSlider slider=new JSlider(2,40);
|
||||
slider.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e)
|
||||
{
|
||||
setWallSize(slider.getValue());
|
||||
}
|
||||
});
|
||||
add(slider,BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MazeComponent extends JComponent
|
||||
implements MazeCreationListener,
|
||||
MazeResolutionListener
|
||||
{
|
||||
WallsProvider map;
|
||||
int width = 10;
|
||||
int height = 10;
|
||||
int offsetX = 5;
|
||||
int offsetY = 5;
|
||||
Position current = null;
|
||||
LinkedList<Position> solvedPath = null;
|
||||
final Object lockChange = new Object();
|
||||
// current postion of human resolution
|
||||
int sX = 0;
|
||||
int sY = 0;
|
||||
// goal exit
|
||||
int gX = -1;
|
||||
int gY = -1;
|
||||
|
||||
void checkExit()
|
||||
{
|
||||
if ((sX == gX) && (sY == gY))
|
||||
{
|
||||
System.out.println("Exit found by human !");
|
||||
}
|
||||
}
|
||||
void goNorth()
|
||||
{
|
||||
resetResolution();
|
||||
if ( (map.getWalls(sX,sY) & Brick.UP) == 0 )
|
||||
{
|
||||
sY = sY -1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void goSouth()
|
||||
{
|
||||
resetResolution();
|
||||
if ( (map.getWalls(sX,sY) & Brick.DOWN) == 0 )
|
||||
{
|
||||
sY =sY + 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void goEast()
|
||||
{
|
||||
resetResolution();
|
||||
if ( (map.getWalls(sX,sY) & Brick.RIGHT) == 0 )
|
||||
{
|
||||
sX = sX + 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
}
|
||||
}
|
||||
|
||||
void goWest()
|
||||
{
|
||||
resetResolution();
|
||||
if ( (map.getWalls(sX,sY) & Brick.LEFT) == 0 )
|
||||
{
|
||||
sX = sX - 1;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
|
||||
checkExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public MazeComponent(WallsProvider map, int width, int height, int offsetX, int offsetY)
|
||||
{
|
||||
super();
|
||||
this.map=map;
|
||||
this.width=width;
|
||||
this.height=height;
|
||||
this.offsetX=offsetX;
|
||||
this.offsetY=offsetY;
|
||||
setPreferredSize(new Dimension(1+2*offsetX+map.getWidth()*width,
|
||||
1+2*offsetY+map.getHeight()*height));
|
||||
gX = map.getWidth() -1;
|
||||
gY = map.getHeight() -1;
|
||||
}
|
||||
|
||||
public void setWallSize(int size)
|
||||
{
|
||||
|
||||
width=size;
|
||||
height=size;
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
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 !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawWalls(Graphics g, int x, int y, short walls, boolean full)
|
||||
{
|
||||
if ( (full) && (( walls & Brick.UP ) == Brick.UP )) g.drawLine(x, y, x+width, y);
|
||||
if ( ( walls & Brick.DOWN ) == Brick.DOWN ) g.drawLine(x, y+height, x+width, y+height);
|
||||
if ( ( walls & Brick.RIGHT ) == Brick.RIGHT ) g.drawLine(x+width, y, x+width, y+height);
|
||||
if ( (full) && (( walls & Brick.LEFT ) == Brick.LEFT )) g.drawLine(x, y, x, y+height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
short walls=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() / width);
|
||||
int mY = (int) ( (double) r.getHeight() / height);
|
||||
int pX = (int) ( (double) (r.getX() - offsetX) / width);
|
||||
int pY = (int) ( (double) (r.getY() - offsetY) / height);
|
||||
|
||||
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.blue);
|
||||
}
|
||||
drawDot(g,new Position(sX,sY),pX,pY,mX,mY);
|
||||
|
||||
synchronized(lockChange)
|
||||
{
|
||||
g.setColor(Color.red);
|
||||
if ( current != null)
|
||||
{
|
||||
drawDot(g,current,pX,pY,mX,mY);
|
||||
}
|
||||
if (solvedPath != null)
|
||||
{
|
||||
for ( Position resolved : solvedPath )
|
||||
{
|
||||
drawDot(g,resolved,pX,pY,mX,mY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.setColor(Color.black);
|
||||
for ( ; pY < mY ; pY ++)
|
||||
{
|
||||
for ( pX = 0; pX < mX ; pX ++)
|
||||
{
|
||||
x=offsetX+pX*width;
|
||||
y=offsetY+pY*height;
|
||||
walls = map.getWalls(pX,pY);
|
||||
drawWalls(g,x,y,walls,(pX == 0) || (pY==0));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawDot(Graphics g,Position dot, int pX, int pY, int mX, int mY)
|
||||
{
|
||||
int radius = ( height > width ) ? width : height;
|
||||
int a = radius / 4;
|
||||
if (( dot.getX() >= pX ) && ( dot.getY() >= pY ) && ( dot.getX() < mX ) && ( dot.getY() < mY ) )
|
||||
{
|
||||
int x=offsetX+dot.getX()*width;
|
||||
int y=offsetY+dot.getY()*height;
|
||||
g.drawOval(x+1,y+1,radius-a,radius-a);
|
||||
//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+pX*width;
|
||||
int y=offsetY+pY*height;
|
||||
g.drawLine(x+1,y+1,x+width-1,y+height-1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean notifySearch(Position pPosition)
|
||||
{
|
||||
synchronized(lockChange)
|
||||
{
|
||||
current = pPosition;
|
||||
}
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public void notifySearchError(String error)
|
||||
{
|
||||
System.err.println(error);
|
||||
}
|
||||
|
||||
public void notifyCompletion(LinkedList<Position> solvedPath)
|
||||
{
|
||||
LinkedList<Position> newPath = (LinkedList<Position>) solvedPath.clone();
|
||||
System.out.println("resolution completed");
|
||||
synchronized(lockChange)
|
||||
{
|
||||
this.solvedPath = newPath;
|
||||
}
|
||||
// should redraw ...
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void resetResolution()
|
||||
{
|
||||
solvedPath = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String pArgs[])
|
||||
{
|
||||
LabyModel model = null;
|
||||
int W = 600;
|
||||
int H = 400;
|
||||
|
||||
if ( pArgs.length > 0 )
|
||||
{
|
||||
try {
|
||||
model = new LabyModel("raw",new FileInputStream(pArgs[0]));
|
||||
}
|
||||
catch (IOException io)
|
||||
{
|
||||
io.printStackTrace(System.err);
|
||||
}
|
||||
|
||||
int w = W / model.getWidth();
|
||||
int h = H / model.getHeight();
|
||||
if ( w < 5 ) w = 5;
|
||||
if ( h < 5 ) h = 5;
|
||||
MazeComponent comp = new MazeComponent(model,w,h,3,3);
|
||||
Display display=new Display(model, comp);
|
||||
model.setMazeListener(comp);
|
||||
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
display.setBounds(W,H,W,H);
|
||||
display.setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("enter width height and maxdepth");
|
||||
Scanner console = new Scanner(System.in);
|
||||
int width = console.nextInt();
|
||||
int height = console.nextInt();
|
||||
int maxdepth = console.nextInt();
|
||||
model = new LabyModel(width, height,maxdepth, new java.util.Random());
|
||||
int w = W / width;
|
||||
int h = H / height;
|
||||
if ( w < 5 ) w = 5;
|
||||
if ( h < 5 ) h = 5;
|
||||
MazeComponent comp = new MazeComponent(model,w,h,3,3);
|
||||
Display display=new Display(model,comp);
|
||||
model.setMazeListener(comp);
|
||||
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
display.setBounds(W,H,W,H);
|
||||
display.setVisible(true);
|
||||
|
||||
model.generateWithEntry(0, 0);
|
||||
LinkedList<Position> exits = new LinkedList<Position>();
|
||||
model.addEntryOrExit(-1,0);
|
||||
model.addEntryOrExit(width,height -1);
|
||||
System.out.println("Generation completed");
|
||||
String name="lab" + width + "x" + height;
|
||||
File outfile = new File(new File("lab"), name + ".raw");
|
||||
if ( ! outfile.exists())
|
||||
{
|
||||
System.out.println( "Saving to " + outfile + " ...");
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(outfile);
|
||||
model.streamOut("raw",out);
|
||||
out.flush();
|
||||
out.close();
|
||||
System.out.println( "... Done.");
|
||||
}
|
||||
catch (IOException io)
|
||||
{
|
||||
io.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println( "" + outfile + " already exists");
|
||||
}
|
||||
outfile = new File(new File("lab"),name + ".stl");
|
||||
if ( ! outfile.exists())
|
||||
{
|
||||
System.out.println( "Saving to " + outfile + " ...");
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(outfile);
|
||||
Wall3d.streamWallsOut(name,(WallsProvider) model,out);
|
||||
out.flush();
|
||||
out.close();
|
||||
System.out.println( "... Done.");
|
||||
}
|
||||
catch (IOException io)
|
||||
{
|
||||
io.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println( "" + outfile + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user