Advertisement
Guest User

Untitled

a guest
Jun 27th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.25 KB | None | 0 0
  1. package maze;
  2.  
  3. import java.util.ArrayList;
  4. import javax.swing.*;
  5. import java.awt.*;
  6.  
  7. /**
  8.  * Maze:  This class represents a rectangular 2D maze suitable for
  9.  * display using the Java SWING Library.
  10.  * @author doom 2008
  11.  */
  12. public class Maze extends JPanel {
  13.  
  14.    private MazeCell[][] maze;
  15.    private int rows;      // vertical dimention of the maze, in cells
  16.    private int columns;   // horizontal dimention of the maze, in cells
  17.  
  18.    /**
  19.     * This constructor creates a 2D maze from a formatted List of Strings.  
  20.     * @param textMaze   Each String in the ArrayList represents one row of
  21.     * the maze.  Each character/symbol in a String represents one cell in the maze
  22.     * (Preconditions)  This routine assumes that all Strings are of the same
  23.     * length (all rows must be of the same length in a rectangular maze).
  24.     * This routine assumes all characters in the string are legal symbols for
  25.     * MazeCell.  Violation of either of these conditions will result in a
  26.     * run-time error/crash.
  27.     */
  28.    public Maze(ArrayList<String> textMaze) {
  29.       this.rows = textMaze.size();
  30.       this.columns = textMaze.get(0).length();
  31.       maze = new MazeCell[rows][columns];
  32.       buildEmptyMaze();
  33.       fillMazeFromFile(textMaze);
  34.    } // end constructor
  35.  
  36.    /**
  37.     * This constructor creates a random 2D maze of the given size.  
  38.     * @param rows The vertical dimention of the maze, in cells
  39.     * @param columns The horizontal dimention of the maze, in cells
  40.     * Note:  Walls, Start, and Exit for the maze are randomly determined.
  41.     * There is no guarantee that a path exists between the Start and
  42.     * Exit.
  43.     */
  44.    public Maze(int rows, int columns) {
  45.       this.rows = rows;
  46.       this.columns = columns;
  47.       maze = new MazeCell[rows][columns];
  48.       buildEmptyMaze();
  49.       fillMaze(0, 0, rows - 1, columns - 1);
  50.       getRandomEmptyCell().setType(MazeCell.Type.TRAIL_HEAD);
  51.       getRandomEmptyCell().setType(MazeCell.Type.EXIT);
  52.    } // end constructor
  53.  
  54.    /**
  55.     * Graphically displays the maze as required for a JPanel
  56.     * This routine is called implictitly by this.refresh() or
  57.     * (for immediate redraw) this.paint(this.getGraphics())
  58.     */
  59.    public void paintComponent(Graphics g) {
  60.       g.setColor(Color.black);
  61.       g.fillRect(0, 0, getWidth(), getHeight());
  62.       for (int row = 0; row < rows; row++) {
  63.          for (int column = 0; column < columns; column++) {
  64.             MazeCell cell = maze[row][column];
  65.             g.setColor(cell.getColor());
  66.             g.fillRect(cell.getX(), cell.getY(), MazeCell.size, MazeCell.size);
  67.          } // end for each column
  68.       } // end for each row    
  69.    } // method paintComponent
  70.  
  71.       /**
  72.     * @return The vertical dimention of the rectangular maze, in cells
  73.     */
  74.    public int getRows() {
  75.       return rows;
  76.    }
  77.  
  78.    /**
  79.     * @return  The horizontal dimention of the rectangular maze, in cells
  80.     */
  81.    public int getColumns() {
  82.       return columns;
  83.    }
  84.      
  85.     /**
  86.     * @return Returns a copy of a MazeCell from the indicated row,
  87.     * column coordinates of the maze.  The returned value is a copy
  88.     * only, to protect the privacy of the data.
  89.     */
  90.    public MazeCell getCell(int row, int column) {
  91.       return new MazeCell(maze[row][column]);
  92.    } // end method getCell
  93.    
  94.    /**
  95.     * setCell:  This method updates the type information for a MazeCell.  It
  96.     * does not allow the user to directly access the actual MazeCell objects
  97.     * to protect the maze from tinkering (such as replacing a mazeCell with a
  98.     * mazeCell that has the incorrect x,y,row,column information, etc.
  99.     * @param copyCell A mazeCell that contains the information to be updated
  100.     * in the actual maze's mazeCells.  Most likely, this mazeCell will be a
  101.     * copy of an actual MazeCell object produced via a call to getCell() or
  102.     * getTrailHead().
  103.     */
  104.    public void setCell(MazeCell copyCell) {
  105.       MazeCell realCell = maze[copyCell.getRow()][copyCell.getColumn()];
  106.       realCell.setType(copyCell.getType());
  107.    } // end method setCell
  108.    
  109.    /**
  110.     * @return A copy of the current position of the path through the maze.
  111.     */
  112.    public MazeCell getTrailHead() {
  113.       for (int row = 0; row < rows; row++) {
  114.          for (int column = 0; column < columns; column++) {
  115.             MazeCell cell = maze[row][column];
  116.             if (cell.getType() == MazeCell.Type.TRAIL_HEAD) {
  117.                return new MazeCell(cell);
  118.             }
  119.          } // end for each column
  120.       } // end for each row
  121.       return null;
  122.    }  // end method getTrailHead  
  123.  
  124.    /**  
  125.     * Populates a 2D array with empty MazeCells
  126.    */
  127.    private void buildEmptyMaze() {
  128.       for (int row = 0; row < rows; row++) {
  129.          for (int column = 0; column < columns; column++) {
  130.             MazeCell cell = new MazeCell(row, column);
  131.             maze[row][column] = cell;
  132.          } // end for each column
  133.       } // end for each row
  134.    } // end method buildEmptyMaze
  135.  
  136.    /**
  137.     * fillMaze:  Fills a grid of empty MazeCells (maze) with randomly
  138.     * placed walls to form a maze.  Parameters indicate the coordinates
  139.     * of the subgrid (to fill) within a potentially larger 2D array
  140.     * of MazeCells.
  141.     */
  142.    private void fillMaze(int minRow, int minCol, int maxRow, int maxCol) {
  143.       // Base case:  If grid of empty cells is smaller than 3x3 then we
  144.       // do not have space to add further walls
  145.       if  ( ((maxRow - minRow) < 2) || ((maxCol - minCol) < 2)){
  146.          return;
  147.       }
  148.       // Recursive case:  Add a vertical and horizontal wall at random
  149.       // interior positions
  150.       int wallRow = minRow + 1 + (int) (Math.random() * (maxRow - minRow - 1));
  151.       int wallCol = minCol + 1 + (int) (Math.random() * (maxCol - minCol - 1));
  152.  
  153.       // Randomly place one vertical and one horizontal wall in maze
  154.       for (int row = minRow; row <= maxRow; row++) {
  155.          maze[row][wallCol].setType(MazeCell.Type.WALL);
  156.       }
  157.       for (int col = minCol; col <= maxCol; col++) {
  158.          maze[wallRow][col].setType(MazeCell.Type.WALL);
  159.       }
  160.  
  161.       // Put a random hole in each of the four walls
  162.       int northPosition = minRow + (int) (Math.random() * (wallRow - minRow));
  163.       int southPosition = wallRow + 1 + (int) (Math.random() * (maxRow - wallRow - 1));
  164.       int westPosition = minCol + (int) (Math.random() * (wallCol - minCol));
  165.       int eastPosition = wallCol + 1 + (int) (Math.random() * (maxCol - wallCol - 1));
  166.       maze[northPosition][wallCol].setType(MazeCell.Type.EMPTY);
  167.       maze[southPosition][wallCol].setType(MazeCell.Type.EMPTY);
  168.       maze[wallRow][eastPosition].setType(MazeCell.Type.EMPTY);
  169.       maze[wallRow][westPosition].setType(MazeCell.Type.EMPTY);
  170.  
  171.       // Recursive step:  The two walls divide the current grid of empty cells
  172.       // into four (smaller) grids of empty cells.  Recursively fill each
  173.       // of these four areas!
  174.       fillMaze(minRow, minCol, wallRow - 1, wallCol - 1);  // NW cell
  175.       fillMaze(minRow, wallCol + 1, wallRow - 1, maxCol); // NE cell
  176.       fillMaze(wallRow + 1, minCol, maxRow, wallCol - 1);  // SW cell
  177.       fillMaze(wallRow + 1, wallCol + 1, maxRow, maxCol);  // SE cell
  178.    } // end method fillMaze
  179.  
  180.    /**
  181.     * This method creates a maze from a text/character description.
  182.     * @param textMaze Each character in the arrayList of Strings is a
  183.     * symbol that represents the type (Wall, Empty, etc) of the mazeCell
  184.     * in the coresponding (row,column) position in the maze.
  185.     */
  186.    private void fillMazeFromFile(ArrayList<String> textMaze) {
  187.       for (int row = 0; row < rows; row++) {
  188.          for (int column = 0; column < columns; column++) {
  189.             maze[row][column].setType(textMaze.get(row).charAt(column));
  190.          } // end for each column
  191.       } // end for each row
  192.    } // end method buildMaze
  193.  
  194.    /**
  195.     * @return  Returns a random traversable cell in the existing maze.
  196.     */
  197.    private MazeCell getRandomEmptyCell() {
  198.       MazeCell cell = null;
  199.       do {
  200.          int row = (int) (Math.random() * rows);
  201.          int col = (int) (Math.random() * columns);
  202.          cell = maze[row][col];
  203.       } while (cell.getType() != MazeCell.Type.EMPTY);
  204.       return cell;
  205.    } // end method getRandomEmptyCell
  206.  
  207. } // end class Maze
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement