3 Replies - 438 Views - Last Post: 27 May 2012 - 01:16 PM Rate Topic: -----

#1 redman8442  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 11-October 11

Maze, using JButtons and recursion.

Posted 26 May 2012 - 10:07 AM

I have 4 classes, Maze,MazeCell, GUI, and Main. I know have to write the mazeCrawler class. I first have to be able to solve the maze using JButtons that were place in the JFrame. Then I have to make an auto solver using recursion. I am so stuck on this I can't even get my JButtons to work. I have been working on this for over a week now and I am about to give up on it. Here is my code

GUI class
 


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
import java.util.Scanner;

public class GUI implements ActionListener {
  
   private JButton northButton = new JButton("North");
   private JButton southButton = new JButton("South");
   private JButton eastButton = new JButton("East");
   private JButton westButton = new JButton("West");
   private JButton solveButton = new JButton("Solve");
   private JButton saveButton = new JButton("Save");
   private MazeCrawler maze;
   private final String SAVE_FILE_NAME = "maze.txt";

   public static void pause() {
      try {
         Thread.sleep(25);        // wait 1/40 s
      } catch (Exception e) {
         e.printStackTrace();
      }
   } // end method pause

   private static ArrayList<String> getTextMaze(String filename) {
      ArrayList<String> textMaze = new ArrayList<String>();
      File handle = new File(filename);
      try {
         Scanner mazeFile = new Scanner(handle);
         while (mazeFile.hasNext()) {
            textMaze.add(mazeFile.nextLine());
         }
      } catch (Exception e) {
         System.out.println("Error reading file");
         System.exit(1);
      }
      return textMaze;
   } // end getTextMaze

   public void go() {
      JFrame frame = new JFrame();
      frame.setTitle("CS241 Maze Crawl");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      maze = new MazeCrawler(15, 32);
      //maze = new MazeCrawler(getTextMaze(SAVE_FILE_NAME));

      int xSize = Math.max(MazeCell.size * (maze.getColumns() + 1), 400);
      frame.setSize(xSize, MazeCell.size * (maze.getRows() + 1) + 60);
      frame.setLocation(300, 50);
      frame.getContentPane().add(BorderLayout.CENTER, maze);
      JPanel buttonPanel = new JPanel();

      buttonPanel.add(westButton);
      westButton.addActionListener(this);
      buttonPanel.add(northButton);
      northButton.addActionListener(this);
      buttonPanel.add(southButton);
      southButton.addActionListener(this);
      buttonPanel.add(eastButton);
      eastButton.addActionListener(this);
      buttonPanel.add(solveButton);
      solveButton.addActionListener(this);
      buttonPanel.add(saveButton);
      saveButton.addActionListener(this);
      
      frame.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
      frame.setVisible(true);
   } // end method main

   public static void win() {
      JOptionPane.showMessageDialog(null, "Path Found!");
      System.exit(0);
   } // end method 

   public static void lose() {
      JOptionPane.showMessageDialog(null, "Nowhere to go from here!");
      System.exit(1);
   } // end method lose
@Override
   public void actionPerformed(ActionEvent event) {
      if (event.getSource() == northButton) {
         maze.moveNorth();
      }
      if (event.getSource() == southButton) {
         maze.moveSouth();
      }
      if (event.getSource() == eastButton) {
         maze.moveEast();
      }
      if (event.getSource() == westButton) {
         maze.moveWest();
      }
      if (event.getSource() == saveButton) {
         maze.saveToFile(SAVE_FILE_NAME);
      }
      if (event.getSource() == solveButton) {
         maze.solveMaze();
      }

      if (maze.isWin()) {
         win();
      }
      if (maze.isNoMove()) {
         lose();
      }   
   } // end actionPerformed
   
} // end class GUI




Maze class
package  

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;

/**
 * Maze:  This class represents a rectangular 2D maze suitable for 
 * display using the Java SWING Library.
 * @author doom 2008
 */
public class Maze extends JPanel {
   
   public MazeCell[][] maze;
   private int rows;      // vertical dimention of the maze, in cells
   private int columns;   // horizontal dimention of the maze, in cells

   /**
    * This constructor creates a 2D maze from a formatted List of Strings.  
    * @param textMaze   Each String in the ArrayList represents one row of 
    * the maze.  Each character/symbol in a String represents one cell in the maze
    * (Preconditions)  This routine assumes that all Strings are of the same
    * length (all rows must be of the same length in a rectangular maze).
    * This routine assumes all characters in the string are legal symbols for
    * MazeCell.  Violation of either of these conditions will result in a 
    * run-time error/crash.
    */
   public Maze(ArrayList<String> textMaze) {
      this.rows = textMaze.size();
      this.columns = textMaze.get(0).length();
      maze = new MazeCell[rows][columns];
      buildEmptyMaze();
      fillMazeFromFile(textMaze);
   } // end constructor

   /**
    * This constructor creates a random 2D maze of the given size.  
    * @param rows The vertical dimention of the maze, in cells
    * @param columns The horizontal dimention of the maze, in cells
    * Note:  Walls, Start, and Exit for the maze are randomly determined.
    * There is no guarantee that a path exists between the Start and
    * Exit.
    */
   public Maze(int rows, int columns) {
      this.rows = rows;
      this.columns = columns;
      maze = new MazeCell[rows][columns];
      buildEmptyMaze();
      fillMaze(0, 0, rows - 1, columns - 1);
      getRandomEmptyCell().setType(MazeCell.Type.TRAIL_HEAD);
      getRandomEmptyCell().setType(MazeCell.Type.EXIT);
   } // end constructor

   /**
    * Graphically displays the maze as required for a JPanel
    * This routine is called implictitly by this.refresh() or
    * (for immediate redraw) this.paint(this.getGraphics())
    */
   @Override
   public void paintComponent(Graphics g) {
      g.setColor(Color.black);
      g.fillRect(0, 0, getWidth(), getHeight());
      for (int row = 0; row < rows; row++) {
         for (int column = 0; column < columns; column++) {
            MazeCell cell = maze[row][column];
            g.setColor(cell.getColor());
            g.fillRect(cell.getX(), cell.getY(), MazeCell.size, MazeCell.size);
         } // end for each column
      } // end for each row     
   } // method paintComponent

      /**
    * @return The vertical dimention of the rectangular maze, in cells
    */
   public int getRows() {
      return rows;
   }

   /**
    * @return  The horizontal dimention of the rectangular maze, in cells
    */
   public int getColumns() {
      return columns;
   }
      
    /**
    * @return Returns a copy of a MazeCell from the indicated row,
    * column coordinates of the maze.  The returned value is a copy
    * only, to protect the privacy of the data. 
    */
   public MazeCell getCell(int row, int column) {
      return new MazeCell(maze[row][column]);
   } // end method getCell
   
   /**
    * setCell:  This method updates the type information for a MazeCell.  It
    * does not allow the user to directly access the actual MazeCell objects
    * to protect the maze from tinkering (such as replacing a mazeCell with a
    * mazeCell that has the incorrect x,y,row,column information, etc.
    * @param copyCell A mazeCell that contains the information to be updated
    * in the actual maze's mazeCells.  Most likely, this mazeCell will be a
    * copy of an actual MazeCell object produced via a call to getCell() or
    * getTrailHead().
    */
   public void setCell(MazeCell copyCell) {
      MazeCell realCell = maze[copyCell.getRow()][copyCell.getColumn()];
      realCell.setType(copyCell.getType());
   } // end method setCell
   
   /**
    * @return A copy of the current position of the path through the maze.
    */
   public MazeCell getTrailHead() {
      for (int row = 0; row < rows; row++) {
         for (int column = 0; column < columns; column++) {
            MazeCell cell = maze[row][column];
            if (cell.getType() == MazeCell.Type.TRAIL_HEAD) {
               return new MazeCell(cell);
            }
         } // end for each column
      } // end for each row 
      return null;
   }  // end method getTrailHead  

   /**  
    * Populates a 2D array with empty MazeCells
   */
   private void buildEmptyMaze() {
      for (int row = 0; row < rows; row++) {
         for (int column = 0; column < columns; column++) {
            MazeCell cell = new MazeCell(row, column);
            maze[row][column] = cell;
         } // end for each column
      } // end for each row
   } // end method buildEmptyMaze

   /**
    * fillMaze:  Fills a grid of empty MazeCells (maze) with randomly
    * placed walls to form a maze.  Parameters indicate the coordinates
    * of the subgrid (to fill) within a potentially larger 2D array
    * of MazeCells. 
    */
   private void fillMaze(int minRow, int minCol, int maxRow, int maxCol) {
      // Base case:  If grid of empty cells is smaller than 3x3 then we 
      // do not have space to add further walls
      if  ( ((maxRow - minRow) < 2) || ((maxCol - minCol) < 2)){ 
         return;
      }
      // Recursive case:  Add a vertical and horizontal wall at random
      // interior positions
      int wallRow = minRow + 1 + (int) (Math.random() * (maxRow - minRow - 1));
      int wallCol = minCol + 1 + (int) (Math.random() * (maxCol - minCol - 1));

      // Randomly place one vertical and one horizontal wall in maze
      for (int row = minRow; row <= maxRow; row++) {
         maze[row][wallCol].setType(MazeCell.Type.WALL);
      }
      for (int col = minCol; col <= maxCol; col++) {
         maze[wallRow][col].setType(MazeCell.Type.WALL);
      }

      // Put a random hole in each of the four walls 
      int northPosition = minRow + (int) (Math.random() * (wallRow - minRow));
      int southPosition = wallRow + 1 + (int) (Math.random() * (maxRow - wallRow - 1));
      int westPosition = minCol + (int) (Math.random() * (wallCol - minCol));
      int eastPosition = wallCol + 1 + (int) (Math.random() * (maxCol - wallCol - 1));
      maze[northPosition][wallCol].setType(MazeCell.Type.EMPTY);
      maze[southPosition][wallCol].setType(MazeCell.Type.EMPTY);
      maze[wallRow][eastPosition].setType(MazeCell.Type.EMPTY);
      maze[wallRow][westPosition].setType(MazeCell.Type.EMPTY);

      // Recursive step:  The two walls divide the current grid of empty cells 
      // into four (smaller) grids of empty cells.  Recursively fill each
      // of these four areas!
      fillMaze(minRow, minCol, wallRow - 1, wallCol - 1);  // NW cell
      fillMaze(minRow, wallCol + 1, wallRow - 1, maxCol); // NE cell
      fillMaze(wallRow + 1, minCol, maxRow, wallCol - 1);  // SW cell
      fillMaze(wallRow + 1, wallCol + 1, maxRow, maxCol);  // SE cell
   } // end method fillMaze

   /**
    * This method creates a maze from a text/character description.
    * @param textMaze Each character in the arrayList of Strings is a
    * symbol that represents the type (Wall, Empty, etc) of the mazeCell
    * in the coresponding (row,column) position in the maze.
    */
   private void fillMazeFromFile(ArrayList<String> textMaze) {
      for (int row = 0; row < rows; row++) {
         for (int column = 0; column < columns; column++) {
            maze[row][column].setType(textMaze.get(row).charAt(column));
         } // end for each column
      } // end for each row
   } // end method buildMaze

   /**
    * @return  Returns a random traversable cell in the existing maze.
    */
   private MazeCell getRandomEmptyCell() {
      MazeCell cell = null;
      do {
         int row = (int) (Math.random() * rows);
         int col = (int) (Math.random() * columns);
         cell = maze[row][col];
      } while (cell.getType() != MazeCell.Type.EMPTY);
      return cell;
   } // end method getRandomEmptyCell
  
} // end class Maze




MazeCell class
package CadenheadProject4;
import java.awt.*;
   /**
    * MazeCell objects represent a cell for use in 2-dimentional maze 
    * Each MazeCell may be traversable (e.g. Type.EMPTY), or 
    * non-traversable (e.g. Type.WALL).  One traversable cell must be the 
    * "start" of the maze (Type.TRAIL_HEAD).  At least one traversable cell 
    * must be an "exit" from the maze (Type.EXIT).
    * Maze cells are labeled by table row and column, with origin (0,0) being
    * the upper-left corner. 
    * @author doom 2008
    */
public class MazeCell {
   public enum Type { EMPTY, WALL, TRAIL, TRAIL_HEAD, EXIT };
   public final char WALL = '#';
   public final char EMPTY = '.';
   public final char START = 's';
   public final char EXIT = 'x';
   public static final int size = 15;
   private Type cellType ; 
   private int row;
   private int column;

   /**
    * Creates an empty cell for use in an n by m rectangular maze. 
    * @param row position in the overall maze for this maze cell
    * @param column position in the overall maze for this maze cell
    */
   public MazeCell(int row, int column) {
      this.column = column;
      this.row = row;
      setType(Type.EMPTY);
   } // end constructor
   
   public MazeCell (MazeCell original) {
      this.row = original.getRow();
      this.column = original.getColumn();
      setType(original.getType());
   } // end copy constructor
   
   /**
    * Set the maze cell's cellType (wall, empty, etc) by setting it from
    * options in MazeCell.Type
    * @param The maze cell's cellType (e.g. Type.EMPTY, Type.WALL, etc).
    */
   public void setType(Type type) {
      this.cellType = type;
   } // end method setType

   /**
    * Set the maze cell's cellType (wall, empty, etc) by using a one
    * character text symbol.  Useful for creating a maze from a text format.
    * @param 'x' (wall), ' ' (empty), 'e' (exit), or 's' (start)
    */
   public void setType(char typeChar) {
      switch (typeChar) {
         case EMPTY:
            setType(Type.EMPTY);
            break;
         case WALL:
            setType(Type.WALL);
            break;
         case START:
            setType(Type.TRAIL_HEAD);
            break;
         case EXIT:
            setType(Type.EXIT);
            break;
         default:
            System.out.println("Error creating Maze");
            System.exit(1);
      } // end switch
      // System.out.println(cellType);
   } // end method setType

   /**
    * @return The cellType of mazecell (Type.WALL, Type.EXIT, etc).
    */
   public Type getType() {
      return cellType;
   } // end method getType

   /**
    * @return The one character symbol used to represent the maze
    * cell in text representation (e.g. # for Wall, . for empty, etc.)
    */
   public char getTypeChar() {
      char symbol = '*';
      switch (cellType) {
         case EMPTY: return EMPTY;
         case WALL: return WALL;
         case TRAIL_HEAD: return START;
         case EXIT: return EXIT;
      }
      return symbol;
   } // end method getTypeChar
   
   /**
    * @return The appropriate display color for this maze
    *  cell (by cellType: Wall, Empty, etc.).  Returns PINK if
    *  cell is of non-standard cellType, likely due to an error 
    *  elsewhere.
    */
   public Color getColor() {
      Color color = Color.PINK;
      if (cellType == Type.EMPTY) {
         color = Color.WHITE;
      }
      if (cellType == Type.WALL) {
         color = Color.BLACK;
      }
      if (cellType == Type.TRAIL) {
         color = Color.LIGHT_GRAY;
      }
      if (cellType == Type.TRAIL_HEAD) {
         color = Color.BLUE;
      }
      if (cellType == Type.EXIT) {
         color = Color.RED;
      }
      return color;
   } // end method getColor

   /**
    * @return This maze cell's horizontal display position on the canvas
    */
   public int getX() {
      return column * size;
   } // end method getX

   /**
    * @return This maze cell's vertical display position on the canvas
    */
   public int getY() {
      return row * size;
   } // end method getY
   
   /**
    * @return This maze cell's row position in the overall maze
    */
   public int getRow() {
      return row;
   } // end method getRow
   
   /**
    * @return This maze cell's column position in the overall maze
    */
   public int getColumn() {
      return column;
   } // end method getColumn
   
} // end class MazeCell



Main class
package CadenheadProject4;

public class Main {
   public static void main(String[] args) {
      GUI mazeWindow = new GUI();
      mazewindow.go();
   } // end method main
} // end class Main


Then here is the start of my MazeCrawler class. If someone could help me with just one of the move methods i have i will be able to write the rest. Then I can get the recursive solver to work also. Thank you in advance if anyone wants to help
package  
import java.awt.event.ActionEvent;
import java.util.ArrayList;

/**
 *
 * @author Brians
 */
public class MazeCrawler extends Maze {
    private Object event;
    
     
    
    public MazeCrawler(int rows, int columns) {
        super(rows, columns);
    }

    public MazeCrawler(ArrayList<String> textMaze) {
        super(textMaze);
    }

    public boolean isWin() {
        return true;
    }

    public boolean isNoMove() {
        return true;
    }

    public void moveNorth() {
        int xPosition = getTrailHead().getX();
        int yPosition = getTrailHead().getY();
       if (xPosition  == 0 && yPosition == 0) {
        
           moveNorth();
      }
            }
    public void moveSouth() {
    }

    public void moveEast() {
    }

    public void moveWest() {
    }

    public void saveToFile(String filename) {
    }

    public void solveMaze() {
    }
}




Is This A Good Question/Topic? 0
  • +

Replies To: Maze, using JButtons and recursion.

#2 TheCoderNextDoor  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 27-May 12

Re: Maze, using JButtons and recursion.

Posted 27 May 2012 - 03:57 AM

Nice job coding first of all. Looks all pretty solid and I really like what I see. Right off the bat if you have any errors from the compiler post those, now exactly what do you need help with? I know you need someone to help you with one of the move methods and I don't see how thats really so hard, wouldn't you just do
else{
   xPosition +=1;
   yPosition +=1;
}
? Reply back
Was This Post Helpful? 0
  • +
  • -

#3 redman8442  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 24
  • Joined: 11-October 11

Re: Maze, using JButtons and recursion.

Posted 27 May 2012 - 11:35 AM

Ok when I run the program all it does is pop up a jOptionPane saying path found. I believe the code is the GUI class. In the win method. It always just goes straight to that code for some reason. That is what is confusing me. No matter what kind of code I write for the move methods in the mazecrawler class it always just pops to the win method in GUI class. So any help with why it does this and some pointers on the move stuff it would be greatly appreciated.
Was This Post Helpful? 0
  • +
  • -

#4 TheCoderNextDoor  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 3
  • Joined: 27-May 12

Re: Maze, using JButtons and recursion.

Posted 27 May 2012 - 01:16 PM

Can you send me the whole project? Like the whole folder so I can run it on my computer, because I don't see why its only running that win method.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1