maze.java
来自「This is a simple Maze Game developed in 」· Java 代码 · 共 448 行
JAVA
448 行
package amazeproject;import gui.aMazeGUI;import java.awt.Color;import java.awt.Graphics;import java.util.ArrayList;import java.util.EmptyStackException;import java.util.Iterator;import java.util.LinkedList;import java.util.Stack;import java.util.Vector;import javax.swing.JPanel;/* * Maze.java * * Created on June 20, 2007, 7:15 PM * *//** * Maze Representation Class * @author Tomasz Gebarowski */public class Maze extends JPanel { //Default Dimensions of a maze public int sizeX = 15; public int sizeY = 15; //2D array of cell objects private Cell cells[][] = null; //Cell stack used for maze generation using Depth First method private Stack cellStack = new Stack(); //Visited cells counter ( generation ) private int visitedCells = 1; //Total number of cells to be visited (generation ) private int totalCells = sizeX * sizeY; //Currently processed cell private Cell currentCell = null; //Stack used for backtracking in maze solving algorithm private Stack steps; private boolean drawRoute = false; //Routing map used to store distance from end point private int routingMap[][]; //Determines if we run program public boolean debugMode = false; /** Creates a new instance of Maze */ public Maze() { init(10,10); } /** Initialize Maze structure * @param width Width of maze * @param height Height of maze */ public void init(int width, int height) { sizeX = width; sizeY = height; // Cell initialization cells = new Cell[sizeX][sizeY]; totalCells = sizeX * sizeY; for (int i = 0; i < sizeX; i++) for (int j = 0; j < sizeY; j++) { cells[i][j] = new Cell(this); cells[i][j].row = i; cells[i][j].col = j; } currentCell = cells[0][0]; visitedCells = 1; //Clear cell stack cellStack.clear(); } /** Return all cell neighbors that have all walls * @param Cell Cell which neighbors we look for * @return ArrayList ArrayList of neighbors */ private ArrayList getNeighborsWithWalls(Cell cCell) { ArrayList neighbors = new ArrayList(); int count = 0; for (int countRow = -1; countRow <= 1; countRow++) for (int countCol = -1; countCol <= 1; countCol++) { if ( (cCell.row + countRow < sizeX) && (cCell.col+countCol < sizeY) && (cCell.row+countRow >= 0) && (cCell.col+countCol >= 0) && ((countCol == 0) || (countRow == 0)) && (countRow != countCol) ) { if (cells[cCell.row+countRow][cCell.col+countCol].hasAllWalls()) { neighbors.add( cells[cCell.row+countRow][cCell.col+countCol]); } } } return neighbors; } /** Generate maze **/ public void generate() { drawRoute = false; // If number of visited cells is smaller then totalCells while (visitedCells < totalCells) { // get a list of the neighboring cells with all walls intact ArrayList adjacentCells = getNeighborsWithWalls(currentCell); // test for cell existance if (adjacentCells.size() > 0) { // select one wall and knock down the wall between it and the current cell int randomCell = (int)Math.floor(Math.random() * adjacentCells.size()); Cell cell = ((Cell)adjacentCells.get(randomCell)); currentCell.knockDownWall(cell); cellStack.push(currentCell); // push the current cell onto the stack currentCell = cell; //set the random neighbor the new current cell visitedCells++; } else { // In no cells, pop current cell from stack currentCell = (Cell)cellStack.pop(); } } // Set Start & End cells[0][0].isStart = true; cells[sizeX-1][sizeY-1].isEnd = true; cells[sizeX-1][sizeY-1].weight = sizeX * sizeY - 1; repaint(); } /** Function starting tracing process ( selecting a proper way from the routingMap ) */ public void trace() { steps = new Stack(); Cell currentCell = cells[sizeX-1][sizeY-1]; cells[sizeX-1][sizeY-1].visited = true; //start tracing from last cell trace(currentCell); drawRoute = true; } /** Function following a given path from a currentCell * It uses routingMap to select a proper way and the shortest path */ public void trace(Cell currentCell) { // Set smallest weight int smallestWeight = 1; // Weight of endpoint int endpoint = sizeX * sizeY - 1; // If current weight is different then endpoint weight then continue while ( currentCell.weight != endpoint ) { // Select all adjacent paths Vector adjCells = currentCell.findPath(); Iterator it = adjCells.iterator(); // By default turn on backtracking boolean backtrack = true; // If adjacent paths exits then start processing one path while ( it.hasNext() ) { Cell c = (Cell)it.next(); // If cell is visited for the first time if ( !c.visited ) { c.weight = this.routingMap[c.row][c.col]; if ( debugMode ) System.out.println("C.weight: " + c.weight + " smallest weight: " + smallestWeight); // End point detected if ( c.weight == endpoint ) { steps.push(c); backtrack = false; // Follow smallest weight } else if ( c.weight == smallestWeight ) { steps.push(c); backtrack = false; } } } // Backtracking handler if ( backtrack ) { if ( debugMode ) { System.out.println("Backtracking"); System.out.println("Weight:" + smallestWeight); } // pop last step if ( !steps.isEmpty() ) { steps.pop(); // decrement weight smallestWeight--; } } try { // Peek step to process Cell tmp = (Cell)steps.peek(); // If cell was not visited if ( !tmp.visited ) { if ( debugMode ) System.out.println("Going to : row: " + tmp.row + " col: " + tmp.col ); currentCell = tmp; currentCell.visited = true; this.cells[currentCell.row][currentCell.col].visited = true;; // Increment weight smallestWeight++; } } catch (EmptyStackException e ) { } } }; /** Runs solving algorithm based on routing table */ public void solve(aMazeGUI parent) { // List working as queue used to store cells to be processed LinkedList frontier = new LinkedList(); // allocate memory for routing map routingMap = new int[sizeX][sizeY]; for ( int i = 0; i < sizeX; i++ ) for ( int j = 0; j < sizeY; j++ ) routingMap[i][j] = -1; int currentWeight = 0; //Define end & start points int targetX = sizeX -1; int targetY = sizeY -1; int startX = 0; int startY = 0; //Give the highest weight to starting point routingMap[startX][startY] = sizeX * sizeY -1; if ( debugMode ) { System.out.println("Start: " + startX + " " + startY); System.out.println("Target: " + targetX + " " + targetY); } //Set zeroth weight to endpoint routingMap[targetX][targetY] = currentWeight; Cell nC = cells[targetX][targetY]; nC.weight = currentWeight; //Add endpoint to queue frontier.addLast(nC); // If queue is not empty while ( !frontier.isEmpty() ) { boolean changed = false; Cell currentCell = (Cell)frontier.removeFirst(); int mapValue = routingMap[currentCell.row][currentCell.col]; // If cell is not the last one if ( mapValue != sizeX * sizeY - 1 ) { // Find all possible paths from cell Vector vct = currentCell.findPath(); if (debugMode) System.out.println(vct); Iterator it = vct.iterator(); // Iterate over all paths while (it.hasNext() ) { Cell c = (Cell)it.next(); // If cell was not previously visited if ( routingMap[c.row][c.col] == -1 ) { // Set its weight c.weight = currentCell.weight + 1; routingMap[c.row][c.col] = c.weight; if ( debugMode ) System.out.println(c.row + " " + c.col + " weight: " + c.weight); frontier.addLast(c); } } // Increment weight currentWeight++; } } if ( debugMode ) { printRoutingMap(); System.out.println("--------------Trace----------------"); } // Start tracing - process of path selection based on distances in routingMap trace(); if ( debugMode ) printTrace(); try { Thread.currentThread().sleep(500); } catch (InterruptedException ex) { ex.printStackTrace(); } repaint(); parent.disableSolveButton(); } /** Function used to print trace */ public void printTrace() { System.out.println("STACK Content: \n"); Iterator it = steps.iterator(); while ( it.hasNext() ) { Cell tmp = (Cell)it.next(); if ( tmp.visited ) System.out.println(tmp); } } /** Function used to draw a trace **/ public void drawTrace(Graphics g ) { g.setColor(Color.green); Iterator it = steps.iterator(); while ( it.hasNext() ) { Cell tmp = (Cell)it.next(); if ( tmp.visited ) { g.fillRect( tmp.row*tmp.cellSize + tmp.padding, tmp.col*tmp.cellSize + tmp.padding, tmp.cellSize, tmp.cellSize ); } } g.setColor(Color.black); } /** Function used to print a routing map */ public void printRoutingMap() { for ( int j = 0; j < sizeY; j++ ) { for ( int i = 0; i < sizeX; i++ ) System.out.print(routingMap[i][j] + "\t"); System.out.println(""); } } /** Return given cell * @param int X coefficient * @param int Y coefficient * @return Cell Cell associated to given coordinates */ public Cell getCell(int x, int y ) { return this.cells[x][y]; } /** Paint the whole maze **/ public void paintComponent(Graphics g) { //Clear Window g.clearRect(0,0, this.getWidth(), this.getHeight() ); if (drawRoute) { this.drawTrace(g); } for (int i = 0; i < sizeX; i++) { for (int j = 0; j < sizeY; j++) { cells[i][j].paint(g); } } } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?