From 96c72506fb5089babd9981f2c11748c7dc46b777 Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Sun, 11 Oct 2020 12:44:22 +0200 Subject: [PATCH] Add java.util.random seed as initial parameter - prepare for short save allowing to fully recreate initial lab having only seed and x,y,depth paramters --- java/org/artisanlogiciel/games/Display.java | 1501 ++++++++--------- java/org/artisanlogiciel/games/LabyModel.java | 1063 +++++------- java/org/artisanlogiciel/games/Main.java | 3 +- .../games/MazeParamEditor.java | 11 + .../org/artisanlogiciel/games/MazeParams.java | 3 + .../games/MazeParamsFixed.java | 9 +- 6 files changed, 1117 insertions(+), 1473 deletions(-) diff --git a/java/org/artisanlogiciel/games/Display.java b/java/org/artisanlogiciel/games/Display.java index 3e19c58..1bf5f20 100644 --- a/java/org/artisanlogiciel/games/Display.java +++ b/java/org/artisanlogiciel/games/Display.java @@ -23,6 +23,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.LinkedList; import java.util.Locale; +import java.util.Random; import java.util.ResourceBundle; import javax.imageio.ImageIO; @@ -41,13 +42,12 @@ import org.artisanlogiciel.graphics.SvgWriter; /** * Display is Main JFrame for this tool **/ -public class Display extends JFrame -{ +public class Display extends JFrame { // to please eclipse, not supposed to be serialized private static final long serialVersionUID = 8500214871372184418L; final static ResourceBundle labels = ResourceBundle.getBundle("LabelsBundle", Locale.getDefault(), Display.class.getClassLoader(), new UTF8Control()); - + MazeComponent maze; MazeControler controler; LabyModel model; @@ -56,498 +56,428 @@ public class Display extends JFrame MazeParams params = null; - Drawing drawing = new Drawing(); + Display(LabyModel model, int W, int H, MazeParams params) { + super(labels.getString("title")); + if (params != null) { + // fixedParams = new MazeParamsFixed(params.getSaveDir(),params.getWidth(),params.getHeight(),params.getMaxDepth()); + this.params = params; + } + this.model = model; + maze = createMazeComponent(model, W, H); - Display(LabyModel model,int W, int H, MazeParams params) - { - super(labels.getString("title")); - if (params != null) - { - // fixedParams = new MazeParamsFixed(params.getSaveDir(),params.getWidth(),params.getHeight(),params.getMaxDepth()); - this.params = params; - } - this.model = model; - maze = createMazeComponent(model,W,H); + Container con = this.getContentPane(); + JScrollPane scrollableMaze = new JScrollPane(maze); + scrollableMaze.addMouseMotionListener(maze); + con.add(scrollableMaze, BorderLayout.CENTER); + controler = new MazeControler(params); + con.add(controler.getMoveControl(), BorderLayout.NORTH); + con.add(controler.getGenerationControl(), BorderLayout.SOUTH); - Container con = this.getContentPane(); - JScrollPane scrollableMaze = new JScrollPane(maze); - scrollableMaze.addMouseMotionListener(maze); - con.add(scrollableMaze, BorderLayout.CENTER); - controler = new MazeControler(params); - con.add(controler.getMoveControl(), BorderLayout.NORTH); - con.add(controler.getGenerationControl(), BorderLayout.SOUTH); + addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if (autoSize) { + maze.getAutoSize(); + } + } + }); - addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent e) { - if ( autoSize ) - { - maze.getAutoSize(); - } - } - }); - - model.setMazeListener(maze); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setBounds(W, H, W, H); - setVisible(true); - } - - private static MazeComponent createMazeComponent(LabyModel model, int W, int H) - { - MazeCellParameters cp = new MazeCellParameters(model.getWidth(),model.getHeight(), W, H, 3, 3); - MazeComponent comp = new MazeComponent(model, cp); - return comp; + model.setMazeListener(maze); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(W, H, W, H); + setVisible(true); } - void recreateModel() - { - // recreate labyrinth - if (params != null) - { - params = controler.getSettings().getParams(); - // DON'T keep current model... - model = new LabyModel(params, new java.util.Random()); - maze.resetWallsProvider(model); - model.setMazeListener(maze); - - model.reset(); - - // we are in GUI event thread, need to release it and do it outside. - new Thread() { - public void run() { - model.generateWithEntry(0, 0); - model.addEntryOrExit(-1, 0); - model.addEntryOrExit(params.getWidth(), params.getHeight() - 1); - } - }.start(); - } + private static MazeComponent createMazeComponent(LabyModel model, int W, int H) { + MazeCellParameters cp = new MazeCellParameters(model.getWidth(), model.getHeight(), W, H, 3, 3); + MazeComponent comp = new MazeComponent(model, cp); + return comp; } - void resetModel() - { - // recreate labyrinth - if (params != null) - { - params = controler.getSettings().getParams(); - model = new LabyModel(params, new java.util.Random()); - maze.resetWallsProvider(model); - model.setMazeListener(maze); + void recreateModel() { + // recreate labyrinth + if (params != null) { + params = controler.getSettings().getParams(); + // DON'T keep current model... + // TODO control SEED. + model = new LabyModel(params); + maze.resetWallsProvider(model); + model.setMazeListener(maze); - - // we are in GUI event thread, need to release it and do it outside. - new Thread() { - public void run() { - maze.changed(null,null,model); - } - }.start(); + model.reset(); - - } + // we are in GUI event thread, need to release it and do it outside. + new Thread() { + public void run() { + model.generateWithEntry(0, 0); + model.addEntryOrExit(-1, 0); + model.addEntryOrExit(params.getWidth(), params.getHeight() - 1); + } + }.start(); + } } - void resolve() - { - model.reset(); + void resetModel() { + // recreate labyrinth + if (params != null) { + params = controler.getSettings().getParams(); + model = new LabyModel(params); + maze.resetWallsProvider(model); + model.setMazeListener(maze); + + + // we are in GUI event thread, need to release it and do it outside. + new Thread() { + public void run() { + maze.changed(null, null, model); + } + }.start(); + + + } + } + + void resolve() { + model.reset(); model.resolve(model.getWidth() - 1, model.getHeight() - 1, maze); } - void goNorth() - { + void goNorth() { maze.goNorth(); } - void goSouth() - { + void goSouth() { maze.goSouth(); } - void goEast() - { + void goEast() { maze.goEast(); } - void goWest() - { + void goWest() { maze.goWest(); } - void setWallSize(int size) - { + void setWallSize(int size) { maze.setWallSize(size); } - void setAutoSize(boolean autoSize) - { - this.autoSize = autoSize; - if ( autoSize ) - { - maze.getAutoSize(); - } + void setAutoSize(boolean autoSize) { + this.autoSize = autoSize; + if (autoSize) { + maze.getAutoSize(); + } } - void addWallInDrawing(int pX, int pY, Drawing d) - { - short walls = model.getWalls(pX,pY); - short wdrawn = 0; - // todo - int w = 2; - int h = 2; - int ox=0; - int oy=0; - - int x = ox + (int) (pX * w); - int y = oy + (int) (pY * h); - DrawingLine dl = new DrawingLine(); - // order matters since all points are linked - if ( (pY == 0) && LabyModel.isFlagSet(walls,Brick.UP) ) - { - dl.addPoint(new Point(x, y)); - dl.addPoint(new Point(x + (int) w, y)); - wdrawn |= Brick.UP; - } - if (LabyModel.isFlagSet(walls,Brick.RIGHT)) - { - if ( ! LabyModel.isFlagSet(wdrawn,Brick.UP) ) - { - dl.addPoint(new Point(x + (int) w, y)); - } - dl.addPoint(new Point(x + (int) w, y + (int) h)); - wdrawn |= Brick.RIGHT; - } - if (LabyModel.isFlagSet(walls,Brick.DOWN)) - { - if ( ! LabyModel.isFlagSet(wdrawn,Brick.RIGHT) ) - { - if (wdrawn != 0) - { - d.addLine(dl); - dl = new DrawingLine(); - } - dl.addPoint(new Point(x + (int) w, y + (int) h)); - } - dl.addPoint(new Point(x, y + (int) h)); - wdrawn |= Brick.DOWN; - } - if ( (pX == 0 ) && LabyModel.isFlagSet(walls,Brick.LEFT)) - { - if ( ! LabyModel.isFlagSet(wdrawn,Brick.DOWN) ) - { - if (wdrawn != 0) - { - d.addLine(dl); - dl = new DrawingLine(); - } - dl.addPoint(new Point(x, y + (int) h)); - } - dl.addPoint(new Point(x, y)); - wdrawn |= Brick.LEFT; - } - if (wdrawn != 0) - { - d.addLine(dl); - } + void addWallInDrawing(int pX, int pY, Drawing d) { + short walls = model.getWalls(pX, pY); + short wdrawn = 0; + // todo + int w = 2; + int h = 2; + int ox = 0; + int oy = 0; + + int x = ox + (int) (pX * w); + int y = oy + (int) (pY * h); + DrawingLine dl = new DrawingLine(); + // order matters since all points are linked + if ((pY == 0) && LabyModel.isFlagSet(walls, Brick.UP)) { + dl.addPoint(new Point(x, y)); + dl.addPoint(new Point(x + (int) w, y)); + wdrawn |= Brick.UP; + } + if (LabyModel.isFlagSet(walls, Brick.RIGHT)) { + if (!LabyModel.isFlagSet(wdrawn, Brick.UP)) { + dl.addPoint(new Point(x + (int) w, y)); + } + dl.addPoint(new Point(x + (int) w, y + (int) h)); + wdrawn |= Brick.RIGHT; + } + if (LabyModel.isFlagSet(walls, Brick.DOWN)) { + if (!LabyModel.isFlagSet(wdrawn, Brick.RIGHT)) { + if (wdrawn != 0) { + d.addLine(dl); + dl = new DrawingLine(); + } + dl.addPoint(new Point(x + (int) w, y + (int) h)); + } + dl.addPoint(new Point(x, y + (int) h)); + wdrawn |= Brick.DOWN; + } + if ((pX == 0) && LabyModel.isFlagSet(walls, Brick.LEFT)) { + if (!LabyModel.isFlagSet(wdrawn, Brick.DOWN)) { + if (wdrawn != 0) { + d.addLine(dl); + dl = new DrawingLine(); + } + dl.addPoint(new Point(x, y + (int) h)); + } + dl.addPoint(new Point(x, y)); + wdrawn |= Brick.LEFT; + } + if (wdrawn != 0) { + d.addLine(dl); + } } - Drawing createDrawing() - { - Drawing d = new Drawing(); - { - short walls; - - // draw all walls within clip bounds horiz first then lines - for (int y = 0; y < model.getHeight(); y++) - { - for (int x = 0; x < model.getWidth(); x ++) - { - addWallInDrawing(x,y,d); + Drawing createDrawing() { + Drawing d = new Drawing(); + { + short walls; + + // draw all walls within clip bounds horiz first then lines + for (int y = 0; y < model.getHeight(); y++) { + for (int x = 0; x < model.getWidth(); x++) { + addWallInDrawing(x, y, d); } } - } - return d; + } + return d; } // to allow to log / write somewher into screen... - void writeSentence(String pSentence) - { - // TODO - System.out.println( pSentence); + void writeSentence(String pSentence) { + // TODO + System.out.println(pSentence); } - void writeError(String pError) - { - System.err.println(pError); + void writeError(String pError) { + System.err.println(pError); } - void saveImc() - { - Drawing d = createDrawing(); + void saveImc() { + Drawing d = createDrawing(); - if ( d != null ) - { - File outfile = new File(params.getSaveDir(), params.getName() + ".imc"); - writeSentence("Saving to " + outfile + " ..."); - try - { - DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile)); - d.saveLinesKompressed(out); - out.flush(); - out.close(); - writeSentence("... Done."); - } - catch (IOException io) - { - io.printStackTrace(System.err); - } - } + if (d != null) { + File outfile = new File(params.getSaveDir(), params.getName() + ".imc"); + writeSentence("Saving to " + outfile + " ..."); + try { + DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile)); + d.saveLinesKompressed(out); + out.flush(); + out.close(); + writeSentence("... Done."); + } catch (IOException io) { + io.printStackTrace(System.err); + } + } } - void saveSvg() - { - Drawing d = createDrawing(); + void saveSvg() { + Drawing d = createDrawing(); - if ( d != null ) - { - File outfile = new File(params.getSaveDir(), params.getName() + ".svg"); - writeSentence("Saving to " + outfile + " ..."); - try - { - DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile)); - SvgWriter writer = new SvgWriter(d.getInternLines()); - writer.writeTo(out); - out.flush(); - out.close(); - writeSentence("... Done."); - } - catch (IOException io) - { - io.printStackTrace(System.err); - } - } - else - { - writeError("drawing creation failed"); - } + if (d != null) { + File outfile = new File(params.getSaveDir(), params.getName() + ".svg"); + writeSentence("Saving to " + outfile + " ..."); + try { + DataOutputStream out = new DataOutputStream(new FileOutputStream(outfile)); + SvgWriter writer = new SvgWriter(d.getInternLines()); + writer.writeTo(out); + out.flush(); + out.close(); + writeSentence("... Done."); + } catch (IOException io) { + io.printStackTrace(System.err); + } + } else { + writeError("drawing creation failed"); + } } - - void savePng() - { - File file = new File("snapshot.png"); - // BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB); - BufferedImage bi = new BufferedImage(maze.getSize().width, maze.getSize().height, BufferedImage.TYPE_INT_ARGB); + void savePng() { + File file = new File("snapshot.png"); + // BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_ARGB); + BufferedImage bi = new BufferedImage(maze.getSize().width, maze.getSize().height, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.createGraphics(); // this.paint(g); - maze.paint(g); + maze.paint(g); g.dispose(); - try{ - ImageIO.write(bi,"png",file); - }catch (Exception e) { + try { + ImageIO.write(bi, "png", file); + } catch (Exception e) { e.printStackTrace(); } } - private class MazeSettings extends JPanel - { - MazeParams params; + private class MazeSettings extends JPanel { + MazeParams params; - JTextField textWidth = null; - JTextField textHeight = null; - JTextField textDepth = null; + JTextField textWidth = null; + JTextField textHeight = null; + JTextField textDepth = null; - // TODO set width and height and depth of maze with gui - public MazeSettings(MazeParams params) - { - super(); - this.params = params; - createSettingsGui(); - } + // TODO set width and height and depth of maze with gui + public MazeSettings(MazeParams params) { + super(); + this.params = params; + createSettingsGui(); + } - void createSettingsGui() - { - if ( params != null ) - { - JButton buttonReset = new JButton("reset");//labels.getString("reset")); - buttonReset.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) - { - resetModel(); - } - }); - add(buttonReset); + void createSettingsGui() { + if (params != null) { + JButton buttonReset = new JButton("reset");//labels.getString("reset")); + buttonReset.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + resetModel(); + } + }); + add(buttonReset); - } - if ( params != null ) - { - JLabel widthLabel = new JLabel(labels.getString("width")); - textWidth = new JTextField("0" + params.getWidth()); - add(widthLabel); - add(textWidth); - JLabel heightLabel = new JLabel(labels.getString("height")); - textHeight = new JTextField("0" + params.getHeight()); - add(heightLabel); - add(textHeight); - JLabel depthLabel = new JLabel(labels.getString("depth")); - textDepth = new JTextField("0" + params.getMaxDepth()); - add(depthLabel); - add(textDepth); - } - } + } + if (params != null) { + JLabel widthLabel = new JLabel(labels.getString("width")); + textWidth = new JTextField("0" + params.getWidth()); + add(widthLabel); + add(textWidth); + JLabel heightLabel = new JLabel(labels.getString("height")); + textHeight = new JTextField("0" + params.getHeight()); + add(heightLabel); + add(textHeight); + JLabel depthLabel = new JLabel(labels.getString("depth")); + textDepth = new JTextField("0" + params.getMaxDepth()); + add(depthLabel); + add(textDepth); + } + } - public MazeParams getParams() - { - return new MazeParamsFixed(params.getSaveDir(), - Integer.parseInt(textWidth.getText()), - Integer.parseInt(textHeight.getText()), - Integer.parseInt(textDepth.getText())); - } + public MazeParams getParams() { + return new MazeParamsFixed(params.getSaveDir(), + Integer.parseInt(textWidth.getText()), + Integer.parseInt(textHeight.getText()), + Integer.parseInt(textDepth.getText()), + new Random().nextLong() + ); + } } - - private class MazeControler extends JPanel - { + private class MazeControler extends JPanel { /** - * + * */ private static final long serialVersionUID = 1L; - private MazeSettings settings = null; + private MazeSettings settings = null; - private JPanel resizecontrol = null; + private JPanel resizecontrol = null; - private void setMazeName(String pName) - { - MazeParamsFixed p = (MazeParamsFixed) params; - p.setName(pName); - } + private void setMazeName(String pName) { + MazeParamsFixed p = (MazeParamsFixed) params; + p.setName(pName); + } - private JMenu createSavingMenu() - { - final JTextField saveName = new JTextField("newlaby "); - final JButton savePngButton = new JButton(labels.getString("save") +" png"); - Action savePngAction = new AbstractAction() { - public void actionPerformed(ActionEvent evt) - { - // - System.out.println("save png"); - setMazeName(saveName.getText()); - savePng(); - } - }; - savePngButton.addActionListener(savePngAction); - final JButton saveSvgButton = new JButton(labels.getString("save") +" svg"); - Action saveSvgAction = new AbstractAction() { - public void actionPerformed(ActionEvent evt) - { - writeSentence("save png"); - setMazeName(saveName.getText()); - saveSvg(); - } - }; - saveSvgButton.addActionListener(saveSvgAction); - final JButton saveButton = new JButton(labels.getString("save") +" raw"); - Action saveAction = new AbstractAction() { - public void actionPerformed(ActionEvent evt) - { - // - System.out.println("save"); - setMazeName(saveName.getText()); - MazeParamsFixed p = (MazeParamsFixed) params; - save(p,model); - } - }; - saveButton.addActionListener(saveAction); - final JButton saveImcButton = new JButton(labels.getString("save") +" imc"); - Action saveImcAction = new AbstractAction() { - public void actionPerformed(ActionEvent evt) - { - // - System.out.println("save imc"); - setMazeName(saveName.getText()); - saveImc(); - } - }; - saveImcButton.addActionListener(saveImcAction); + private JMenu createSavingMenu() { + final JTextField saveName = new JTextField("newlaby "); + final JButton savePngButton = new JButton(labels.getString("save") + " png"); + Action savePngAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + // + System.out.println("save png"); + setMazeName(saveName.getText()); + savePng(); + } + }; + savePngButton.addActionListener(savePngAction); + final JButton saveSvgButton = new JButton(labels.getString("save") + " svg"); + Action saveSvgAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + writeSentence("save png"); + setMazeName(saveName.getText()); + saveSvg(); + } + }; + saveSvgButton.addActionListener(saveSvgAction); + final JButton saveButton = new JButton(labels.getString("save") + " raw"); + Action saveAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + // + System.out.println("save"); + setMazeName(saveName.getText()); + MazeParamsFixed p = (MazeParamsFixed) params; + save(p, model); + } + }; + saveButton.addActionListener(saveAction); + final JButton saveImcButton = new JButton(labels.getString("save") + " imc"); + Action saveImcAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + // + System.out.println("save imc"); + setMazeName(saveName.getText()); + saveImc(); + } + }; + saveImcButton.addActionListener(saveImcAction); - JMenu saveMenu = new JMenu("Save"); - saveMenu.add(saveName); - saveMenu.add(saveSvgButton); - saveMenu.add(savePngButton); - saveMenu.add(saveButton); - saveMenu.add(saveImcButton); + JMenu saveMenu = new JMenu("Save"); + saveMenu.add(saveName); + saveMenu.add(saveSvgButton); + saveMenu.add(savePngButton); + saveMenu.add(saveButton); + saveMenu.add(saveImcButton); - return saveMenu; + return saveMenu; - } + } - private JPanel createResolveQuitBar() - { - JPanel resolveQuitBar = new JPanel(new FlowLayout()); + private JPanel createResolveQuitBar() { + JPanel resolveQuitBar = new JPanel(new FlowLayout()); - JButton buttonCreate = new JButton(labels.getString("create")); - buttonCreate.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) - { - recreateModel(); - } - }); - resolveQuitBar.add(buttonCreate); + JButton buttonCreate = new JButton(labels.getString("create")); + buttonCreate.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + recreateModel(); + } + }); + resolveQuitBar.add(buttonCreate); - JButton resolveButton = new JButton(labels.getString("resolve")); - resolveButton.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent evt) - { + JButton resolveButton = new JButton(labels.getString("resolve")); + resolveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { // System.out.println("Resolving"); resolve(); } }); - - resolveQuitBar.add(resolveButton); - final JButton quitButton = new JButton(labels.getString("quit")); - Action quitAction = new AbstractAction() { - public void actionPerformed(ActionEvent evt) - { + resolveQuitBar.add(resolveButton); + + final JButton quitButton = new JButton(labels.getString("quit")); + Action quitAction = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { // System.out.println("quit"); - System.exit(0); + System.exit(0); } }; - quitButton.addActionListener(quitAction); + quitButton.addActionListener(quitAction); - resolveQuitBar.add(quitButton); + resolveQuitBar.add(quitButton); - return resolveQuitBar; + return resolveQuitBar; - } - - public MazeControler(MazeParams params) - { - // super(new BorderLayout()); - super(); - BoxLayout layout = new BoxLayout(this,BoxLayout.Y_AXIS); - setLayout(layout); + } - JMenuBar menuBar = new JMenuBar(); - menuBar.add(createSavingMenu()); - add(menuBar); + public MazeControler(MazeParams params) { + // super(new BorderLayout()); + super(); + BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS); + setLayout(layout); + + JMenuBar menuBar = new JMenuBar(); + menuBar.add(createSavingMenu()); + add(menuBar); + + add(createResolveQuitBar()); - add(createResolveQuitBar()); - controlPanel = new JPanel(new BorderLayout()); - settings = new MazeSettings(params); - @SuppressWarnings("serial") - Action goNorth = new AbstractAction() - { - public void actionPerformed(ActionEvent evt) - { + settings = new MazeSettings(params); + @SuppressWarnings("serial") + Action goNorth = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { // System.out.println("go North"); goNorth(); @@ -556,10 +486,8 @@ public class Display extends JFrame JButton north = addDirection(this, labels.getString("north"), "UP", goNorth); @SuppressWarnings("serial") - Action goEast = new AbstractAction() - { - public void actionPerformed(ActionEvent evt) - { + Action goEast = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { // System.out.println("go East"); goEast(); @@ -569,10 +497,8 @@ public class Display extends JFrame JButton east = addDirection(this, labels.getString("east"), "RIGHT", goEast); @SuppressWarnings("serial") - Action goWest = new AbstractAction() - { - public void actionPerformed(ActionEvent evt) - { + Action goWest = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { // System.out.println("go West"); goWest(); @@ -581,247 +507,210 @@ public class Display extends JFrame JButton west = addDirection(this, labels.getString("west"), "LEFT", goWest); @SuppressWarnings("serial") - Action goSouth = new AbstractAction() - { - public void actionPerformed(ActionEvent evt) - { + Action goSouth = new AbstractAction() { + public void actionPerformed(ActionEvent evt) { // System.out.println("go South"); goSouth(); } }; JButton south = addDirection(this, labels.getString("south"), "DOWN", goSouth); - + controlPanel.add(north, BorderLayout.NORTH); controlPanel.add(west, BorderLayout.WEST); controlPanel.add(east, BorderLayout.EAST); controlPanel.add(south, BorderLayout.SOUTH); add(controlPanel, BorderLayout.NORTH); - // control display panel contains controls for display - // zoom , autozoom. - final JPanel controlDisplayPanel = new JPanel(new BorderLayout()); - final JCheckBox showAll = new JCheckBox("show all"); - showAll.addChangeListener(new ChangeListener() - { - public void stateChanged(ChangeEvent e) - { - maze.setShowAll( showAll.isSelected()); - } - }); + // control display panel contains controls for display + // zoom , autozoom. + final JPanel controlDisplayPanel = new JPanel(new BorderLayout()); + final JCheckBox showAll = new JCheckBox("show all"); + showAll.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + maze.setShowAll(showAll.isSelected()); + } + }); final JSlider slider = new JSlider(2, 40); - slider.addChangeListener(new ChangeListener() - { - public void stateChanged(ChangeEvent e) - { + slider.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { setWallSize(slider.getValue()); } }); - final JCheckBox autoSlide = new JCheckBox("autoslide"); - autoSlide.addChangeListener(new ChangeListener() - { - public void stateChanged(ChangeEvent e) - { - setAutoSize( autoSlide.isSelected()); - } - }); + final JCheckBox autoSlide = new JCheckBox("autoslide"); + autoSlide.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + setAutoSize(autoSlide.isSelected()); + } + }); - resizecontrol = new JPanel(new FlowLayout()); - resizecontrol.add(showAll); + resizecontrol = new JPanel(new FlowLayout()); + resizecontrol.add(showAll); resizecontrol.add(slider); - resizecontrol.add(autoSlide); + resizecontrol.add(autoSlide); - add(controlDisplayPanel, BorderLayout.SOUTH); - add(resizecontrol,BorderLayout.WEST); - add(settings,BorderLayout.EAST); + add(controlDisplayPanel, BorderLayout.SOUTH); + add(resizecontrol, BorderLayout.WEST); + add(settings, BorderLayout.EAST); } - private JPanel getMoveControl() - { - return this; - } + private JPanel getMoveControl() { + return this; + } - private JPanel getResizeControl() - { - return resizecontrol; - } + private JPanel getResizeControl() { + return resizecontrol; + } - private JPanel getGenerationControl() - { - return settings; - } + private JPanel getGenerationControl() { + return settings; + } - public MazeSettings getSettings() - { - return settings; - } + public MazeSettings getSettings() { + return settings; + } } - private JButton addDirection(final JPanel panel, final String direction, String key, Action goAction) - { + private JButton addDirection(final JPanel panel, final String direction, String key, Action goAction) { String actionName = "go" + direction; JButton button = new JButton(direction); button.addActionListener(goAction); KeyStroke keystroke = KeyStroke.getKeyStroke(key); - // attach keys to maze + // attach keys to maze maze.getInputMap().put(keystroke, actionName); maze.getActionMap().put(actionName, goAction); return button; } - private static class MazeCellParameters - { - double width = 10; // width of one cell + 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; + 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; + 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; - } + 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; + 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); - } + setCellSize(w, h); + } - public void setCellSize(double w, double h) - { - width = w; - height = h; - } + public void setCellSize(double w, double h) { + width = w; + height = h; + } - public double getWidth() - { - return width; - } + public double getWidth() { + return width; + } - public double getHeight() - { - return height; - } + public double getHeight() { + return height; + } - public int getOffsetX() - { - return offsetX; - } + public int getOffsetX() { + return offsetX; + } - public int getOffsetY() - { - return offsetY; - } + public int getOffsetY() { + return offsetY; + } - public Dimension getDimension() - { - return new Dimension(offsetX + (int) (mapWidth * width), - offsetY + (int) (mapHeight * height)); - } + 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)) + 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)) + 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 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) - { + 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 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 ); + 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 - { + } 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); @@ -831,19 +720,18 @@ public class Display extends JFrame } private static class MazeComponent - extends JComponent - implements MazeCreationListener, - MazeResolutionListener, - MouseMotionListener - { + extends JComponent + implements MazeCreationListener, + MazeResolutionListener, + MouseMotionListener { private static final long serialVersionUID = 3163272907991176390L; - + // WallsProvider map; - LabyModel map; - final MazeCellParameters cp; + LabyModel map; + final MazeCellParameters cp; Position current = null; LinkedList solvedPath = null; - LinkedList drawingPath = null; + LinkedList drawingPath = null; final Object lockChange = new Object(); // current postion of human resolving int sX = 0; @@ -851,87 +739,73 @@ public class Display extends JFrame // goal exit int gX = -1; int gY = -1; - - // not set by default for debug, will show any path - boolean showAll = false; - - // for a given (x,y) pixel return cell position. - Position getPosition(int x, int y) - { - int pX = (int) ((double) (x - cp.getOffsetX()) / cp.getWidth()); + + // not set by default for debug, will show any path + boolean showAll = false; + + // for a given (x,y) pixel return cell position. + 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) { - // should find the cell ... - DirectionPosition last = null; - short path = 0; - Position newPosition = getPosition(e.getX(),e.getY()); - if (drawingPath == null ) - { - drawingPath = new LinkedList<>(); - last = new DirectionPosition((short) 0,newPosition); - System.out.println("Mouse dragged Cell " + newPosition + " Button " + e.getModifiersEx() + " " + InputEvent.BUTTON1_DOWN_MASK); - 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 : replace with direction. - if ( ( e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK ) != 0 ) - { - 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); - } - System.out.println("Mouse dragged from Cell " + first.getPosition() + "To" + newPosition + " Button " + e.getModifiersEx() + " " + InputEvent.BUTTON1_DOWN_MASK); - } - changed(null,null,map); - } + return new Position(pX, pY); + } - @Override - public void mouseMoved(MouseEvent e) { - // System.out.println("Mouse moved (" + e.getX() + ',' + e.getY() + ')'); - Position newPosition = getPosition(e.getX(),e.getY()); - if ( ( newPosition.getX() >= 0 ) && ( newPosition.getY() >= 0 ) ) - { - requestFocus(); - } - } + @Override + public void mouseDragged(MouseEvent e) { + // should find the cell ... + DirectionPosition last = null; + short path = 0; + Position newPosition = getPosition(e.getX(), e.getY()); + if (drawingPath == null) { + drawingPath = new LinkedList<>(); + last = new DirectionPosition((short) 0, newPosition); + System.out.println("Mouse dragged Cell " + newPosition + " Button " + e.getModifiersEx() + " " + InputEvent.BUTTON1_DOWN_MASK); + 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 : replace with direction. + if ((e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0) { + 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); + } + System.out.println("Mouse dragged from Cell " + first.getPosition() + "To" + newPosition + " Button " + e.getModifiersEx() + " " + InputEvent.BUTTON1_DOWN_MASK); + } + changed(null, null, map); + } - public void setShowAll(boolean showall ) - { - this.showAll = showall; - System.out.println(showAll ? "show all" : "X"); - } - - void checkExit() - { - if ((sX == gX) && (sY == gY)) - { + @Override + public void mouseMoved(MouseEvent e) { + // System.out.println("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; + System.out.println(showAll ? "show all" : "X"); + } + + void checkExit() { + if ((sX == gX) && (sY == gY)) { System.out.println("Exit found by human !"); } } - void goNorth() - { + void goNorth() { resetResolution(); - if ((map.getWalls(sX, sY) & Brick.UP) == 0) - { + if ((map.getWalls(sX, sY) & Brick.UP) == 0) { sY = sY - 1; // should redraw ... invalidate(); @@ -942,11 +816,9 @@ public class Display extends JFrame } - void goSouth() - { + void goSouth() { resetResolution(); - if ((map.getWalls(sX, sY) & Brick.DOWN) == 0) - { + if ((map.getWalls(sX, sY) & Brick.DOWN) == 0) { sY = sY + 1; // should redraw ... invalidate(); @@ -957,11 +829,9 @@ public class Display extends JFrame } - void goEast() - { + void goEast() { resetResolution(); - if ((map.getWalls(sX, sY) & Brick.RIGHT) == 0) - { + if ((map.getWalls(sX, sY) & Brick.RIGHT) == 0) { sX = sX + 1; // should redraw ... invalidate(); @@ -971,11 +841,9 @@ public class Display extends JFrame } } - void goWest() - { + void goWest() { resetResolution(); - if ((map.getWalls(sX, sY) & Brick.LEFT) == 0) - { + if ((map.getWalls(sX, sY) & Brick.LEFT) == 0) { sX = sX - 1; // should redraw ... invalidate(); @@ -986,79 +854,69 @@ public class Display extends JFrame } - /** - width, height of one cell, - offsetX, offsetY of upper left corner - **/ + /** + * width, height of one cell, + * offsetX, offsetY of upper left corner + **/ // public MazeComponent(WallsProvider map, MazeCellParameters cp) - public MazeComponent(LabyModel map, MazeCellParameters cp) - { + public MazeComponent(LabyModel map, MazeCellParameters cp) { super(); - this.cp = cp; + 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 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); + 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 ... + public int getAutoSize() { + Rectangle r = getBounds(); + cp.adaptTo((int) r.getWidth(), (int) r.getHeight()); + // should redraw ... invalidate(); repaint(); - return 50; - } + return 50; + } - public void changed(Position cl, Position cr, WallsProvider map) - { + public void changed(Position cl, Position cr, WallsProvider map) { // should redraw ... invalidate(); repaint(); Object waiter = new Object(); - synchronized (waiter) - { - try - { + synchronized (waiter) { + try { waiter.wait(10); - } - catch (InterruptedException e) - { + } catch (InterruptedException e) { System.err.println("Interrupted !"); } } } @Override - protected void paintComponent(Graphics g) - { + protected void paintComponent(Graphics g) { super.paintComponent(g); int x = 0; int y = 0; short walls = 0; - short path = 0; + short path = 0; // try to display only visible part... // should compute pX, pY, mX, mY based on clip... @@ -1082,94 +940,74 @@ public class Display extends JFrame mX = mX + pX; mY = mY + pY; - if (mX > map.getWidth()) - { + if (mX > map.getWidth()) { mX = map.getWidth(); } - if (mY > map.getHeight()) - { + if (mY > map.getHeight()) { mY = map.getHeight(); } - if ((sX == gX) && (sY == gY)) - { + 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); + } 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) - { + synchronized (lockChange) { g.setColor(Color.red); - if (current != null) - { + if (current != null) { cp.drawDot(g, current, pX, pY, mX, mY); } - if (solvedPath != null) - { - for (DirectionPosition resolved : solvedPath) - { + if (solvedPath != null) { + for (DirectionPosition resolved : solvedPath) { // cp.drawDot(g, resolved.getPosition(), pX, pY, mX, mY); - cp.drawPath(g,resolved, pX, pY, mX, mY); + cp.drawPath(g, resolved, pX, pY, mX, mY); } } } - int aX = pX; - int aY = pY; - + 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++) - { + // 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) - { - System.out.println("*"); - 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); - } - } - } - } - } + if (this.showAll) { + System.out.println("*"); + 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) - { + public boolean notifySearch(DirectionPosition pPosition) { + synchronized (lockChange) { current = pPosition.getPosition(); } // should redraw ... @@ -1179,17 +1017,14 @@ public class Display extends JFrame } - public void notifySearchError(String error) - { + public void notifySearchError(String error) { System.err.println(error); } - public void notifyCompletion(LinkedList solvedPath) - { + public void notifyCompletion(LinkedList solvedPath) { LinkedList newPath = new LinkedList<>(solvedPath); System.out.println("resolution completed"); - synchronized (lockChange) - { + synchronized (lockChange) { this.solvedPath = newPath; } // should redraw ... @@ -1197,92 +1032,70 @@ public class Display extends JFrame repaint(); } - public void resetResolution() - { + public void resetResolution() { solvedPath = null; } } - private static void setupDisplay(LabyModel model, int W, int H, MazeParams params) - { - Display display = new Display(model, W,H,params); + private static void setupDisplay(LabyModel model, int W, int H, MazeParams params) { + Display display = new Display(model, W, H, params); } - public static void save(MazeParamsFixed params,LabyModel model) - { - File outfile = new File(params.getSaveDir(), params.getName() + ".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); - } + public static void save(MazeParamsFixed params, LabyModel model) { + File outfile = new File(params.getSaveDir(), params.getName() + ".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"); + } else { + System.out.println("" + outfile + " already exists"); + } + outfile = new File(params.getSaveDir(), params.getName() + ".stl"); + if (!outfile.exists()) { + System.out.println("Saving to " + outfile + " ..."); + try { + FileOutputStream out = new FileOutputStream(outfile); + Wall3d.streamWallsOut(params.getName(), model, out); + out.flush(); + out.close(); + System.out.println("... Done."); + } catch (IOException io) { + io.printStackTrace(System.err); } - outfile = new File(params.getSaveDir(), params.getName() + ".stl"); - if (!outfile.exists()) - { - System.out.println("Saving to " + outfile + " ..."); - try - { - FileOutputStream out = new FileOutputStream(outfile); - Wall3d.streamWallsOut(params.getName(), model, out); - out.flush(); - out.close(); - System.out.println("... Done."); - } - catch (IOException io) - { - io.printStackTrace(System.err); - } - } - else - { - System.out.println("" + outfile + " already exists"); - } - + } else { + System.out.println("" + outfile + " already exists"); + } + } - public static void main(String pArgs[]) - { + public static void main(String pArgs[]) { LabyModel model = null; int W = 600; int H = 400; - System.out.println("Default Locale " + Locale.getDefault()); + System.out.println("Default Locale " + Locale.getDefault()); - if ( (pArgs.length > 0) && (pArgs[0].length() > 0)) - { - try - { + if ((pArgs.length > 0) && (pArgs[0].length() > 0)) { + try { model = new LabyModel("raw", new FileInputStream(pArgs[0])); - } - catch (IOException io) - { + } catch (IOException io) { io.printStackTrace(System.err); - System.exit(1); + System.exit(1); } - setupDisplay(model, W,H,null); - } - else - { - MazeParamsFixed params = new MazeParamsFixed(new File("lab"),20,20,12); - model = new LabyModel(params, new java.util.Random()); + setupDisplay(model, W, H, null); + } else { + MazeParamsFixed params = new MazeParamsFixed(new File("lab"), 20, 20, 12,1024L); + model = new LabyModel(params); - setupDisplay(model,W,H,params); + setupDisplay(model, W, H, params); /* model.generateWithEntry(0, 0); @@ -1292,8 +1105,8 @@ public class Display extends JFrame System.out.println("Generation completed"); */ - /* - */ + /* + */ } } diff --git a/java/org/artisanlogiciel/games/LabyModel.java b/java/org/artisanlogiciel/games/LabyModel.java index 3ace732..22ed466 100644 --- a/java/org/artisanlogiciel/games/LabyModel.java +++ b/java/org/artisanlogiciel/games/LabyModel.java @@ -18,8 +18,7 @@ import java.io.DataInputStream; * openList if all moves from its position have not been resolved a node is * tagged CLOSED when fully processed **/ -public class LabyModel implements WallsProvider -{ +public class LabyModel implements WallsProvider { /** * WARNING don't change those values, they are used as it is for @@ -27,21 +26,21 @@ public class LabyModel implements WallsProvider */ private final static short FLAGLENGTH = 7; private final static short CLEAR = 0; // mandatory 0 since array creation is - // initialized with 0. + // initialized with 0. public final static short HORIZONTAL = 1; public final static short VERTICAL = 2; 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 + // ? // can be both POSITIVE and NEGATIVE, it means that you can move in positive direction and in negative direction. public final static short POSITIVE = 8; public final static short NEGATIVE = 16; // can it be both OPEN and CLOSED ? private final static short OPEN = 32; // can be reused once generation is - // completed + // 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 DOWN = Brick.DOWN << FLAGLENGTH | DIRECTION | VERTICAL | POSITIVE; public final static short RIGHT = Brick.RIGHT << FLAGLENGTH | DIRECTION | HORIZONTAL | POSITIVE; @@ -58,7 +57,7 @@ public class LabyModel implements WallsProvider // remains 2 free bits ( keep one out for sign ) // orders matters see getReverseDirection - private static final short[] AllDirections = { LEFT, DOWN, RIGHT, UP }; + private static final short[] AllDirections = {LEFT, DOWN, RIGHT, UP}; private int width; private int height; @@ -84,15 +83,14 @@ public class LabyModel implements WallsProvider // list of entries and exits. private final LinkedList entryExits = new LinkedList(); private final Object coherentLock = new Object(); // before getting the lock - // and after lock release - // all is coherent ( ie - // check() is ok ), + // and after lock release + // all is coherent ( ie + // check() is ok ), MazeCreationListener listener = null; - private LabyModel(int width, int height, int maxdepth, Random random) - { + private LabyModel(int width, int height, int maxdepth, Random random) { this.width = width; this.height = height; this.maxdepth = maxdepth; @@ -101,215 +99,183 @@ public class LabyModel implements WallsProvider t = new short[width][height]; } - public LabyModel(MazeParams params, Random random) - { - this(params.getWidth(),params.getHeight(),params.getMaxDepth(),random); + public LabyModel(MazeParams params) { + this(params.getWidth(), params.getHeight(), params.getMaxDepth(), new java.util.Random(params.getSeed())); } /** - construct LabyModel from an InputStream, yet only "raw" is supported - **/ - public LabyModel(String pFormat, InputStream pIn) throws IOException - { + * construct LabyModel from an InputStream, yet only "raw" is supported + **/ + public LabyModel(String pFormat, InputStream pIn) throws IOException { parseInputStream(pFormat, pIn); } - public void setMazeListener(MazeCreationListener listener) - { + public void setMazeListener(MazeCreationListener listener) { this.listener = listener; } // FIXME FULLY BREAK RESOLVING... - public void noWalls(int x, int y) - { - if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) - { - // t[x][y] |= DIRECTION | VERTICAL | POSITIVE | HORIZONTAL | NEGATIVE | LEFT | RIGHT | UP | DOWN; - t[x][y] |= LEFT | RIGHT | UP | DOWN; - } + public void noWalls(int x, int y) { + if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) { + // t[x][y] |= DIRECTION | VERTICAL | POSITIVE | HORIZONTAL | NEGATIVE | LEFT | RIGHT | UP | DOWN; + t[x][y] |= LEFT | RIGHT | UP | DOWN; + } } /* set direction existing onee are lost */ // FIXME FULLY BREAK RESOLVING... - public void setDirection(int x, int y, short path) - { - if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) - { - t[x][y]= (short) (path | OPEN); - } + public void setDirection(int x, int y, short path) { + if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) { + t[x][y] = (short) (path | OPEN); + } } - /** add a new direction, exiting ones are kept */ + /** + * add a new direction, exiting ones are kept + */ // FIXME FULLY BREAK RESOLVING... - public void addDirection(int x, int y, short path) - { - if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) - { - t[x][y]|= (short) (path | OPEN); - } + public void addDirection(int x, int y, short path) { + if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) { + t[x][y] |= (short) (path | OPEN); + } } // entry and exit can be outside the model boundaries a one x or one y out. - public boolean addEntryOrExit(int x, int y) - { + public boolean addEntryOrExit(int x, int y) { entryExits.add(new Position(x, y)); - if ((x > 0) && (x < width) && (y > 0) && (y < height)) - { + if ((x > 0) && (x < width) && (y > 0) && (y < height)) { t[x][y] |= ENTRY; } return true; } - public void debugOut() - { - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { + public void debugOut() { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { out4XY(x, y); } System.out.print('\n'); } } - public void out4XY(int x, int y) - { + public void out4XY(int x, int y) { int direction = t[x][y]; - if ((direction & OPEN) == OPEN) - { + if ((direction & OPEN) == OPEN) { System.out.print("?"); - } - else if ((direction & CLOSED) == CLOSED) - { + } else if ((direction & CLOSED) == CLOSED) { System.out.print("."); - } - else - { + } else { System.out.print(" "); } // don't display information about short. direction &= ~OPEN; direction &= ~GOAL; direction &= ~CLOSED; - switch (direction) - { - case LEFT: // left - System.out.print("<-"); - break; - case DOWN: // down - System.out.print("vv"); - break; - case RIGHT: // right - System.out.print("->"); - break; - case UP: // up - System.out.print("^^"); - break; - case HORIZONTAL: // - - System.out.print("--"); - break; - case VERTICAL: // | - System.out.print("||"); - break; - case CLEAR: - System.out.print(" "); - break; - case CLOSED: - System.out.print("00"); - break; - case RIGHT | LEFT: - System.out.print("--"); - break; - case UP | DOWN: - System.out.print("||"); - break; - case RIGHT | UP: - System.out.print("^>"); - break; - case RIGHT | DOWN: - System.out.print("v>"); - break; - case LEFT | DOWN: - System.out.print(""); - break; - case LEFT | RIGHT | UP | DOWN: - System.out.print("++"); - break; - case OPEN: - System.out.print("??"); - break; - case GOAL: - System.out.print("**"); - break; - default: - System.out.print(".."); + switch (direction) { + case LEFT: // left + System.out.print("<-"); + break; + case DOWN: // down + System.out.print("vv"); + break; + case RIGHT: // right + System.out.print("->"); + break; + case UP: // up + System.out.print("^^"); + break; + case HORIZONTAL: // - + System.out.print("--"); + break; + case VERTICAL: // | + System.out.print("||"); + break; + case CLEAR: + System.out.print(" "); + break; + case CLOSED: + System.out.print("00"); + break; + case RIGHT | LEFT: + System.out.print("--"); + break; + case UP | DOWN: + System.out.print("||"); + break; + case RIGHT | UP: + System.out.print("^>"); + break; + case RIGHT | DOWN: + System.out.print("v>"); + break; + case LEFT | DOWN: + System.out.print(""); + break; + case LEFT | RIGHT | UP | DOWN: + System.out.print("++"); + break; + case OPEN: + System.out.print("??"); + break; + case GOAL: + System.out.print("**"); + break; + default: + System.out.print(".."); } - if (((t[x][y] & RIGHT) == RIGHT) || ((x + 1 < width) && ((t[x + 1][y] & LEFT) == LEFT))) - { + if (((t[x][y] & RIGHT) == RIGHT) || ((x + 1 < width) && ((t[x + 1][y] & LEFT) == LEFT))) { System.out.print("-"); - } - else - { + } else { System.out.print("H"); } } - public String outHorizWall2XY(int x, int y) - { + public String outHorizWall2XY(int x, int y) { String freeway = " "; - if ((t[x][y] & SOLVED) == SOLVED) - { + if ((t[x][y] & SOLVED) == SOLVED) { freeway = "*"; } - if ((x < 0) || (x > width)) - { + if ((x < 0) || (x > width)) { return " H"; } - if ((y < 0) || (y >= height)) - { + if ((y < 0) || (y >= height)) { return "HH"; } - if (((t[x][y] & DOWN) == DOWN) || ((y + 1 < height) && ((t[x][y + 1] & UP) == UP))) - { + if (((t[x][y] & DOWN) == DOWN) || ((y + 1 < height) && ((t[x][y + 1] & UP) == UP))) { return freeway + "H"; - } - else - { + } else { return "HH"; } } - public String out2XY(int x, int y) - { + public String out2XY(int x, int y) { // can check for entry exits. - if ((y < 0) || (y >= height) || (x < 0) || (x > width)) - { + if ((y < 0) || (y >= height) || (x < 0) || (x > width)) { return " H"; } String low = ""; int direction = t[x][y]; String freeway = " "; - if ((t[x][y] & SOLVED) == SOLVED) - { + if ((t[x][y] & SOLVED) == SOLVED) { freeway = "*"; } // don't display information about short. @@ -317,79 +283,69 @@ public class LabyModel implements WallsProvider direction &= ~GOAL; direction &= ~CLOSED; direction &= ~SOLVED; - switch (direction) - { - case LEFT: - case DOWN: - case RIGHT: - case UP: - low = freeway; - break; - case HORIZONTAL: // - - low = " "; - break; - case VERTICAL: // | - low = " "; - break; - case CLEAR: - low = " "; - break; - case CLOSED: - low = "0"; - break; - case RIGHT | LEFT: - case UP | DOWN: - case RIGHT | UP: - case RIGHT | DOWN: - case LEFT | DOWN: - case LEFT | UP: - case LEFT | RIGHT | UP: - case LEFT | RIGHT | DOWN: - case LEFT | DOWN | UP: - case RIGHT | DOWN | UP: - case LEFT | RIGHT | UP | DOWN: - low = "."; - break; - case OPEN: - low = "?"; - break; - case GOAL: - low = "*"; - break; - default: - low = "."; + switch (direction) { + case LEFT: + case DOWN: + case RIGHT: + case UP: + low = freeway; + break; + case HORIZONTAL: // - + low = " "; + break; + case VERTICAL: // | + low = " "; + break; + case CLEAR: + low = " "; + break; + case CLOSED: + low = "0"; + break; + case RIGHT | LEFT: + case UP | DOWN: + case RIGHT | UP: + case RIGHT | DOWN: + case LEFT | DOWN: + case LEFT | UP: + case LEFT | RIGHT | UP: + case LEFT | RIGHT | DOWN: + case LEFT | DOWN | UP: + case RIGHT | DOWN | UP: + case LEFT | RIGHT | UP | DOWN: + low = "."; + break; + case OPEN: + low = "?"; + break; + case GOAL: + low = "*"; + break; + default: + low = "."; } - for (Position exit : entryExits) - { - if ((exit.getX() == x + 1) && (exit.getY() == y)) - { + for (Position exit : entryExits) { + if ((exit.getX() == x + 1) && (exit.getY() == y)) { low = low + ">"; return low; } } - if (((t[x][y] & RIGHT) == RIGHT) || ((x + 1 < width) && ((t[x + 1][y] & LEFT) == LEFT))) - { + if (((t[x][y] & RIGHT) == RIGHT) || ((x + 1 < width) && ((t[x + 1][y] & LEFT) == LEFT))) { low = low + freeway; - } - else - { + } else { low = low + "H"; } return low; } - public LabyMap toLabyMap() - { - synchronized (coherentLock) - { + public LabyMap toLabyMap() { + synchronized (coherentLock) { Brick[][] brickMap = new Brick[width][height]; - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { brickMap[x][y] = new Brick(out2XY(x, y), outHorizWall2XY(x, y), getWalls(x, y)); } } @@ -397,55 +353,45 @@ public class LabyModel implements WallsProvider } } - public int getWidth() - { + public int getWidth() { return this.width; } - public int getHeight() - { + public int getHeight() { return this.height; } - public LinkedList getOpenList() - { + public LinkedList getOpenList() { return openList; } - public void reset() - { + public void reset() { depth = 0; computeOpenList(); - resetResolving(); + resetResolving(); } - public void resetResolving() - { - // don't keep solved path - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - t[x][y] &= ~(SOLVED); + public void resetResolving() { + // don't keep solved path + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + t[x][y] &= ~(SOLVED); } } } - public void fullReset() - { + public void fullReset() { depth = 0; openList.clear(); maxreached = false; deepest = 0; deepestEnd = null; // clear open - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - // resetCell(x,y); - t[x][y] &= ~( OPEN | SOLVED); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + // resetCell(x,y); + t[x][y] &= ~(OPEN | SOLVED); } } @@ -454,26 +400,21 @@ public class LabyModel implements WallsProvider /** * check model coherency and fix if model needed a fix it means that * algorithm has a problem - * + * * @return true if model is ok and no fix was applied. **/ - public boolean check() - { + public boolean check() { boolean check = true; - synchronized (coherentLock) - { + synchronized (coherentLock) { // node in OPEN should be tagged OPEN and not CLOSED. - for (Position p : openList) - { + for (Position p : openList) { int x = p.getX(); int y = p.getY(); - if (isFlagSet(t[x][y],OPEN)) - { + if (isFlagSet(t[x][y], OPEN)) { check = false; t[x][y] |= OPEN; } - if (isFlagSet(t[x][y],CLOSED)) - { + if (isFlagSet(t[x][y], CLOSED)) { check = false; t[x][y] &= ~CLOSED; } @@ -486,19 +427,14 @@ public class LabyModel implements WallsProvider } // coherency : if CLOSED then not OPEN - public void computeOpenList() - { + public void computeOpenList() { openList.clear(); - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - if (isFlagSet(t[x][y],CLOSED)) - { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + if (isFlagSet(t[x][y], CLOSED)) { t[x][y] &= ~OPEN; } - if (isFlagSet(t[x][y],OPEN) || (t[x][y] == CLEAR)) - { + if (isFlagSet(t[x][y], OPEN) || (t[x][y] == CLEAR)) { openList.add(new Position(x, y)); } } @@ -506,30 +442,27 @@ public class LabyModel implements WallsProvider } /** - generate a maze with an entry set at (x,y) with a maxdepth - **/ - public void generateWithEntry(int x, int y) - { + * This is core of generator. + *

+ * generate a maze with an entry set at (x,y) with a maxdepth + **/ + public void generateWithEntry(int x, int y) { openList.add(new Position(x, y)); - while (!openList.isEmpty()) - { + while (!openList.isEmpty()) { + // this is where magic happens step(); - synchronized (coherentLock) - { + synchronized (coherentLock) { linearwork++; - if (linearwork % maxdepth == 0) - { + if (linearwork % maxdepth == 0) { coherentLock.notifyAll(); - if (listener != null) - { + if (listener != null) { listener.changed(null, null, this); } // should not continue in depth first... - if (!openList.isEmpty()) - { + if (!openList.isEmpty()) { // insert head as next position to pick up. Position current = openList.removeFirst(); openList.add(current); @@ -539,43 +472,35 @@ public class LabyModel implements WallsProvider } - if (deepestEnd != null) - { + if (deepestEnd != null) { t[deepestEnd.getX()][deepestEnd.getY()] |= GOAL; } } - public int getDepth() - { + public int getDepth() { return depth; } - public Position getDeepestEnd() - { + public Position getDeepestEnd() { return deepestEnd; } - public int getDeepestPath() - { + public int getDeepestPath() { return deepest; } - public boolean maxReached() - { + public boolean maxReached() { return maxreached; } /** - * @param p - * Position + * @param p Position * @return true if newly added , false if already open. **/ - private boolean open(boolean first, Position p) - { + private boolean open(boolean first, Position p) { int x = p.getX(); int y = p.getY(); - if ((t[x][y] & OPEN) != OPEN) - { + if ((t[x][y] & OPEN) != OPEN) { t[x][y] |= OPEN; openList.addLast(p); return true; @@ -583,244 +508,194 @@ public class LabyModel implements WallsProvider return false; } - public final static boolean isFlagSet(short check, short flag) - { - return ((check & flag) == flag); + public final static boolean isFlagSet(short check, short flag) { + return ((check & flag) == flag); } - public final short getCell(Position p) - { - return t[p.getX()][p.getY()]; + public final short getCell(Position p) { + return t[p.getX()][p.getY()]; } - public final void updateCell(Position p, short flags) - { - t[p.getX()][p.getY()] |= flags; + public final void updateCell(Position p, short flags) { + t[p.getX()][p.getY()] |= flags; } - public final static short getReverseDirection(int index) - { - return AllDirections[(index + 2) % 4]; + public final static short getReverseDirection(int index) { + return AllDirections[(index + 2) % 4]; } - /** return direction to use to be closer to 'to' from 'from' */ - public final static short getDirection(Position from, Position to) - { - short pointingdirection = DIRECTION; - if ( from.equals(to) ) - { - return pointingdirection; - } - if ( from.getX() < to.getX() ) - { - pointingdirection |= RIGHT; - } - else - if ( from.getX() > to.getX() ) - { - pointingdirection |= LEFT; - } - if ( from.getY() < to.getY() ) - { - pointingdirection |= DOWN; - } - else - if ( from.getY() > to.getY() ) - { - pointingdirection |= UP; - } - return pointingdirection; + /** + * return direction to use to be closer to 'to' from 'from' + */ + public final static short getDirection(Position from, Position to) { + short pointingdirection = DIRECTION; + if (from.equals(to)) { + return pointingdirection; + } + if (from.getX() < to.getX()) { + pointingdirection |= RIGHT; + } else if (from.getX() > to.getX()) { + pointingdirection |= LEFT; + } + if (from.getY() < to.getY()) { + pointingdirection |= DOWN; + } else if (from.getY() > to.getY()) { + pointingdirection |= UP; + } + return pointingdirection; } - + /** * resolve this labrynth using internal representation * initial (x,y) is exit, will return list of positions from start (0,0) to end (x,y) **/ - public LinkedList resolve(int x, int y, MazeResolutionListener rlistener) - { - long safeguard = width * height; + public LinkedList resolve(int x, int y, MazeResolutionListener rlistener) { + long safeguard = width * height; int newx = 0; int newy = 0; - resetResolving(); + resetResolving(); - // list of alternate paths + // list of alternate paths LinkedList> altpath = new LinkedList<>(); - // list of positions from start to end + // list of positions from start to end LinkedList backpath = new LinkedList(); - // position that point to (x,y). - DirectionPosition found = new DirectionPosition((short) 0,new Position(x, y)); - // entry - Position entry = new Position(0, 0); + // 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(); + while (!found.getPosition().equals(entry)) { + Position last = found.getPosition(); backpath.addFirst(found); - found = null; + 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; + { + // 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, 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; - } + 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; - } + // internal GUARD. + if (!isFlagSet(reversedirection, pointingdirection)) { + System.out.println("[FATAL] Internal ERROR. Please check AllDirections order " + + (reversedirection & pointingdirection) + " " + pointingdirection); + return backpath; + } - Position p = new Position(newx,newy); - if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) - { - if (isFlagSet(getCell(p),reversedirection)) - { - if (found != null) - { - // there is already a potential solution in adjacent cell of last. - System.out.println("alternate " + p + " from " + last + "/" + safeguard); - // could be a unique parent of two paths... - // but search from other entry/exits than generated - // from - // ie entry(0,0) exit(width-1,height-1) not yet - // implemented. - { - if (! isFlagSet(getCell(p), SOLVED )) - { - LinkedList cp = new LinkedList(backpath); - DirectionPosition altfound = new DirectionPosition(reversedirection,p); - cp.addFirst(altfound); - altpath.addLast(cp); - rlistener.notifySearchError("record alternate path " + p.toString()); - } - else - { - // this was already solved, might be a loop. - if (rlistener != null) - { - rlistener.notifySearchError("Loop " + last.toString() + " has two parents " + found.toString() + " " - + p.toString()); - } - // continue; - } - } - } - else - { - if (! isFlagSet(getCell(p), SOLVED )) - { - // this is first potential solution in adjacent cell of last. - System.out.println("check " + p + " from " + last + "/" + safeguard); - - found = new DirectionPosition(reversedirection,p); - if (rlistener != null) - { - rlistener.notifySearch(found); - } - } - else - { - // was already solved. - System.out.println("already solved " + p + " from " + last + "/" + safeguard); - } - } - // support multiple pathes - } - else - { - System.out.println("not reachable " + p + " from " + last + "/" + safeguard); - } - } - else - { - System.out.println("p outofbounds " + p + "/" + safeguard); - } - } - if (found == null) - { - if ( ! altpath.isEmpty() ) - { - // new possible backpath - backpath = altpath.removeFirst(); - found = backpath.removeFirst(); - if (rlistener != null) - { - rlistener.notifySearchError("try alternate path " + found.toString()); - rlistener.notifySearch(found); - } - } - } - } - if (found == null) - { - if ( ! altpath.isEmpty() ) - { - rlistener.notifySearchError("No path found BUT ALTPATH !" ); - } - rlistener.notifySearchError("No path found !"); - break; - } + Position p = new Position(newx, newy); + if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) { + if (isFlagSet(getCell(p), reversedirection)) { + if (found != null) { + // there is already a potential solution in adjacent cell of last. + System.out.println("alternate " + p + " from " + last + "/" + safeguard); + // could be a unique parent of two paths... + // but search from other entry/exits than generated + // from + // ie entry(0,0) exit(width-1,height-1) not yet + // implemented. + { + if (!isFlagSet(getCell(p), SOLVED)) { + LinkedList cp = new LinkedList(backpath); + DirectionPosition altfound = new DirectionPosition(reversedirection, p); + cp.addFirst(altfound); + altpath.addLast(cp); + rlistener.notifySearchError("record alternate path " + p.toString()); + } else { + // this was already solved, might be a loop. + if (rlistener != null) { + rlistener.notifySearchError("Loop " + last.toString() + " has two parents " + found.toString() + " " + + p.toString()); + } + // continue; + } + } + } else { + if (!isFlagSet(getCell(p), SOLVED)) { + // this is first potential solution in adjacent cell of last. + System.out.println("check " + p + " from " + last + "/" + safeguard); + + found = new DirectionPosition(reversedirection, p); + if (rlistener != null) { + rlistener.notifySearch(found); + } + } else { + // was already solved. + System.out.println("already solved " + p + " from " + last + "/" + safeguard); + } + } + // support multiple pathes + } else { + System.out.println("not reachable " + p + " from " + last + "/" + safeguard); + } + } else { + System.out.println("p outofbounds " + p + "/" + safeguard); + } + } + if (found == null) { + if (!altpath.isEmpty()) { + // new possible backpath + backpath = altpath.removeFirst(); + found = backpath.removeFirst(); + if (rlistener != null) { + rlistener.notifySearchError("try alternate path " + found.toString()); + rlistener.notifySearch(found); + } + } + } + } + if (found == null) { + if (!altpath.isEmpty()) { + rlistener.notifySearchError("No path found BUT ALTPATH !"); + } + rlistener.notifySearchError("No path found !"); + break; + } // System.out.println(found); - if (isFlagSet(getCell(found.getPosition()), SOLVED )) - { - System.out.println("[INFO] position already solved" + found.toString() + " *length:" + backpath.size()); - } - else - { - updateCell(found.getPosition(),SOLVED); - } + 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; - } + + 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) { rlistener.notifyCompletion(backpath); } return backpath; } - private final void closePosition(int x, int y) - { - t[x][y] &= ~OPEN; - t[x][y] |= CLOSED; + private final void closePosition(int x, int y) { + t[x][y] &= ~OPEN; + t[x][y] |= CLOSED; } /** @@ -829,81 +704,61 @@ public class LabyModel implements WallsProvider * * @returns whether process closed current node. **/ - public boolean step() - { + public boolean step() { boolean complete = false; Position current = null; - synchronized (coherentLock) - { + synchronized (coherentLock) { - if (!openList.isEmpty()) - { + if (!openList.isEmpty()) { // last : in depth before. current = openList.getLast(); - } - else - { + } else { return true; } - if (current != null) - { + if (current != null) { int x = current.getX(); int y = current.getY(); // should find all free positions... ArrayList freeDirection = new ArrayList(); - for (short direction : AllDirections) - { + for (short direction : AllDirections) { int delta = 0; int newx = -1; int newy = -1; - if ((direction & POSITIVE) == POSITIVE) - { + if ((direction & POSITIVE) == POSITIVE) { delta = 1; - } - else - { + } else { delta = -1; } - if ((direction & HORIZONTAL) == HORIZONTAL) - { + if ((direction & HORIZONTAL) == HORIZONTAL) { newx = x + delta; newy = y; - } - else - { + } else { newy = y + delta; newx = x; } - if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) - { - if ((t[newx][newy]) == CLEAR) - { + if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) { + if ((t[newx][newy]) == CLEAR) { freeDirection.add(Short.valueOf(direction)); } } } - if (!freeDirection.isEmpty()) - { + if (!freeDirection.isEmpty()) { // control random using our own pseudorandom short direction = 0; - if (freeDirection.size() > 1) - { + if (freeDirection.size() > 1) { direction = freeDirection.get(random.nextInt(freeDirection.size())); - } - else - { + } else { direction = freeDirection.get(0); Position last = openList.removeLast(); - if (last != current) - { + if (last != current) { // GUARD, should not happen ( or multi-thread access // to model error ) System.err.println("INTERNAL ERROR 3"); @@ -915,38 +770,28 @@ public class LabyModel implements WallsProvider int newx = -1; int newy = -1; - if ((direction & POSITIVE) == POSITIVE) - { + if ((direction & POSITIVE) == POSITIVE) { delta = 1; - } - else - { + } else { delta = -1; } - if ((direction & HORIZONTAL) == HORIZONTAL) - { + if ((direction & HORIZONTAL) == HORIZONTAL) { newx = x + delta; newy = y; - } - else - { + } else { newy = y + delta; newx = x; } Position target = new Position(newx, newy, current.getDepth() + 1); open(false, target); - if ((t[x][y] & DIRECTION) == DIRECTION) - { + if ((t[x][y] & DIRECTION) == DIRECTION) { t[x][y] |= direction; - } - else - { + } else { t[x][y] = direction; } // not a 'direction' ... is it necessary to check ? - if (freeDirection.size() > 1) - { + if (freeDirection.size() > 1) { // keep it open at the very same place, previous open // did add another node to inspect. return false; @@ -956,24 +801,20 @@ public class LabyModel implements WallsProvider // last ) // can proceed to close - } - else - { + } else { // no free direction remaining => closing Position last = openList.removeLast(); - if (last != current) - { + if (last != current) { // GUARD, should not happen. System.err.println("INTERNAL ERROR 3"); return false; } } complete = true; - closePosition(x,y); + closePosition(x, y); - final int currentdepth = current.getDepth(); - if ( currentdepth > deepest) - { + final int currentdepth = current.getDepth(); + if (currentdepth > deepest) { deepest = currentdepth; deepestEnd = current; } @@ -982,34 +823,28 @@ public class LabyModel implements WallsProvider return complete; } - public short getWalls(int x, int y) - { + public short getWalls(int x, int y) { short walls = 0; - for (short direction : AllDirections) - { - if (hasWallInDirection(x, y, direction)) - { + for (short direction : AllDirections) { + if (hasWallInDirection(x, y, direction)) { walls |= (direction >> FLAGLENGTH); } } return walls; } - public short getPath(int x, int y) - { + public short getPath(int x, int y) { short path = 0; - if (( x < width ) && ( y < height )) - { - path = t[x][y]; - } - return path; + if ((x < width) && (y < height)) { + path = t[x][y]; + } + return path; } /** * is there a wall in that direction ? **/ - public boolean hasWallInDirection(int x, int y, short direction) - { + public boolean hasWallInDirection(int x, int y, short direction) { int newx = 0; int newy = 0; int delta = 0; @@ -1017,113 +852,87 @@ public class LabyModel implements WallsProvider int reversedirection = 0; // is this direction on the path ? yes => no wall - if ((t[x][y] & direction) == direction) - { + if ((t[x][y] & direction) == direction) { return false; } // is adjacent tile in direction pointing in reverse direction ? yes => // no wall - if ((direction & POSITIVE) == POSITIVE) - { + if ((direction & POSITIVE) == POSITIVE) { delta = 1; - } - else - { + } else { delta = -1; } - if ((direction & HORIZONTAL) == HORIZONTAL) - { + if ((direction & HORIZONTAL) == HORIZONTAL) { newx = x + delta; newy = y; reversedirection = (direction == RIGHT) ? LEFT : RIGHT; - } - else - { + } else { newy = y + delta; newx = x; reversedirection = (direction == UP) ? DOWN : UP; } - if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) - { - return !isFlagSet(t[newx][newy],(short)reversedirection); - } - else - { + if ((newx >= 0) && (newy >= 0) && (newx < width) && (newy < height)) { + return !isFlagSet(t[newx][newy], (short) reversedirection); + } else { // outside boundaries. // TODO CHECK exits. return true; } } - public void streamOut(String pFormat, OutputStream pOut) throws IOException - { - if ((pFormat == null) || (pFormat.equals("raw"))) - { + 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.write(new byte[]{(byte) 'L', (byte) 'A', (byte) 'B', (byte) '0'}); dataOut.writeInt(getWidth()); dataOut.writeInt(getHeight()); dataOut.flush(); - for (int y = 0; y < getHeight(); y++) - { - for (int x = 0; x < getWidth(); x++) - { + for (int y = 0; y < getHeight(); y++) { + for (int x = 0; x < getWidth(); x++) { dataOut.writeShort(t[x][y]); } } dataOut.flush(); - } - else - { + } else { throw new IOException("Format " + pFormat + " Not yet implemented."); } } - private void streamIn(String pFormat, InputStream pIn) throws IOException - { + 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 + + 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"); - } + 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 - { + } else { throw new IOException("Format " + pFormat + " Not yet implemented."); } diff --git a/java/org/artisanlogiciel/games/Main.java b/java/org/artisanlogiciel/games/Main.java index 91864d5..4b19244 100644 --- a/java/org/artisanlogiciel/games/Main.java +++ b/java/org/artisanlogiciel/games/Main.java @@ -16,7 +16,8 @@ public class Main public LabyMap generate2(MazeParamEditor params) { - LabyModel model = new LabyModel(params, new java.util.Random(1024L)); + params.setSeed(1024L); + LabyModel model = new LabyModel(params); model.generateWithEntry(0, 0); final int width = params.getWidth(); diff --git a/java/org/artisanlogiciel/games/MazeParamEditor.java b/java/org/artisanlogiciel/games/MazeParamEditor.java index 664e1b2..003723b 100644 --- a/java/org/artisanlogiciel/games/MazeParamEditor.java +++ b/java/org/artisanlogiciel/games/MazeParamEditor.java @@ -8,6 +8,7 @@ import java.util.Scanner; **/ class MazeParamEditor implements MazeParams { + long seed; int width; int height; int maxdepth; @@ -27,6 +28,11 @@ class MazeParamEditor implements MazeParams maxdepth = console.nextInt(); } + public long getSeed() + { + return seed; + } + public int getWidth() { return width; @@ -51,6 +57,11 @@ class MazeParamEditor implements MazeParams return name; } + public void setSeed(long seed) + { + this.seed = seed; + } + public File getSaveDir() { return labdir; diff --git a/java/org/artisanlogiciel/games/MazeParams.java b/java/org/artisanlogiciel/games/MazeParams.java index 77f5753..e2020a8 100644 --- a/java/org/artisanlogiciel/games/MazeParams.java +++ b/java/org/artisanlogiciel/games/MazeParams.java @@ -7,6 +7,9 @@ import java.io.File; **/ public interface MazeParams { + /** currently seed of java.util.random **/ + public long getSeed(); + public int getWidth(); public int getHeight(); diff --git a/java/org/artisanlogiciel/games/MazeParamsFixed.java b/java/org/artisanlogiciel/games/MazeParamsFixed.java index 0e40257..6f9e505 100644 --- a/java/org/artisanlogiciel/games/MazeParamsFixed.java +++ b/java/org/artisanlogiciel/games/MazeParamsFixed.java @@ -4,6 +4,7 @@ import java.io.File; public class MazeParamsFixed implements MazeParams { + long seed; int width; int height; int maxdepth; @@ -27,10 +28,16 @@ public class MazeParamsFixed implements MazeParams maxdepth=MD; } - public MazeParamsFixed(File saveDir, int W, int H, int 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()