package amphis; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JPanel; // note : utilise la classe UnionFind qui se trouve dans Amphi3Connectivity enum Direction { Vertical, Horizontal }; class Wall { final int x; final int y; final Direction direction; boolean closed; public Wall(int x, int y, Direction direction) { this.x = x; this.y = y; this.direction = direction; this.closed = true; } } public class Amphi3Maze extends JFrame { private static final long serialVersionUID = 2465232426222345837L; private static final int step = 20; Amphi3Maze(int width, int height) { Vector<Wall> walls = new Vector<Wall>(); for (int x = 0; x < width; x++) for (int y = 0; y < height; y++) { if (x < width - 1) walls.add(new Wall(x, y, Direction.Vertical)); if (y < height - 1) walls.add(new Wall(x, y, Direction.Horizontal)); } System.out.println(walls.size() + " walls"); shuffle(walls); int n = width * height; UnionFind uf = new UnionFind(n); // codage : x * height + y for (Wall w: walls) { int cell = w.x * height + w.y; int next = cell + (w.direction == Direction.Horizontal ? 1 : height); if (uf.find(cell) == uf.find(next)) continue; uf.union(cell, next); w.closed = false; } MazeWindow window = new MazeWindow(walls, width, height, step); this.setTitle("labyrinthe"); window.setPreferredSize(new Dimension(width * step + 1, height * step + 1)); this.add(window, BorderLayout.CENTER); this.pack(); this.add(window); this.addKeyListener(window); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(false); this.setLocationRelativeTo(null); this.setVisible(true); } // mélange de Knuth void shuffle(Vector<Wall> a) { for (int i = 1; i < a.size(); i++) { int j = (int)(Math.random() * (i + 1)); Wall tmp = a.get(i); a.set(i, a.get(j)); a.set(j, tmp); } } public static void main(String[] args) { new Amphi3Maze(40, 30); } } class MazeWindow extends JPanel implements KeyListener { private static final long serialVersionUID = 1L; private final int width, height, step; private final Vector<Wall> walls; MazeWindow(Vector<Wall> walls, int width, int height, int step) { this.walls = walls; this.width = width; this.height = height; this.step = step; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setStroke(new BasicStroke(3)); int w = this.width * this.step; int h = this.height * this.step; g.drawLine(0, 0, w, 0); g.drawLine(0, 0, 0, h); g.drawLine(w, 0, w, h); g.drawLine(0, h, w, h); for (Wall wall: this.walls) { if (!wall.closed) continue; int x = wall.x * this.step; int y = wall.y * this.step; switch (wall.direction){ case Horizontal: g2d.drawLine(x, y + step, x + step, y + step); break; case Vertical: g2d.drawLine(x + step, y, x + step, y + step); break; } } } @Override public void keyTyped(KeyEvent ev) { char key = ev.getKeyChar(); if (key == 'q') System.exit(0); } @Override public void keyPressed(KeyEvent ev) { } @Override public void keyReleased(KeyEvent ev) { } }