import java.awt.*; import javax.swing.*; /** * Creates a random maze, then solves it by finding a path from the * upper left corner to the lower right corner. (After doing * one maze, it waits a while then starts over by creating a * new random maze.) */ public class Maze extends JPanel implements Runnable { // a main routine makes it possible to run this class as a program public static void main(String[] args) { JFrame window = new JFrame("Maze Solver"); window.setContentPane(new Maze()); window.pack(); window.setLocation(120, 80); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); } int[][] maze; // Description of state of maze. The value of maze[i][j] // is one of the constants wallCode, pathcode, emptyCode, // or visitedCode. (Value can also be negative, temporarily, // inside createMaze().) // A maze is made up of walls and corridors. maze[i][j] // is either part of a wall or part of a corridor. A cell // cell that is part of a corridor is represented by pathCode // if it is part of the current path through the maze, by // visitedCode if it has already been explored without finding // a solution, and by emptyCode if it has not yet been explored. final static int backgroundCode = 0; final static int wallCode = 1; final static int pathCode = 2; final static int emptyCode = 3; final static int visitedCode = 4; Color[] color; // colors associated with the preceding 5 constants; int rows = 31; // number of rows of cells in maze, including a wall around edges int columns = 41; // number of columns of cells in maze, including a wall around edges int border = 0; // minimum number of pixels between maze and edge of panel int sleepTime = 5000; // wait time after solving one maze before making another int speedSleep = 30; // short delay between steps in making and solving maze int blockSize = 12; // size of each cell int width = -1; // width of panel, to be set by checkSize() int height = -1; // height of panel, to be set by checkSize() int totalWidth; // width of panel, minus border area (set in checkSize()) int totalHeight; // height of panel, minus border area (set in checkSize()) int left; // left edge of maze, allowing for border (set in checkSize()) int top; // top edge of maze, allowing for border (set in checkSize()) boolean mazeExists = false; // set to true when maze[][] is valid; used in // redrawMaze(); set to true in createMaze(), and // reset to false in run() public Maze() { color = new Color[] { new Color(200,0,0), new Color(200,0,0), new Color(128,128,255), Color.WHITE, new Color(200,200,200) }; setBackground(color[backgroundCode]); setPreferredSize(new Dimension(blockSize*columns, blockSize*rows)); new Thread(this).start(); } void checkSize() { // Called before drawing the maze, to set parameters used for drawing. if (getWidth() != width || getHeight() != height) { width = getWidth(); height = getHeight(); int w = (width - 2*border) / columns; int h = (height - 2*border) / rows; left = (width - w*columns) / 2; top = (height - h*rows) / 2; totalWidth = w*columns; totalHeight = h*rows; } } synchronized protected void paintComponent(Graphics g) { super.paintComponent(g); checkSize(); redrawMaze(g); } void redrawMaze(Graphics g) { // draws the entire maze if (mazeExists) { int w = totalWidth / columns; // width of each cell int h = totalHeight / rows; // height of each cell for (int j=0; j0; i--) { r = (int)(Math.random() * i); // choose a wall randomly and maybe tear it down tearDown(wallrow[r],wallcol[r]); wallrow[r] = wallrow[i]; wallcol[r] = wallcol[i]; } for (i=1; i