How to make a mouse maze in Java

This is the code to make a mouse maze with recursion using a stack and a list with a GUI in Java.

First we will make a Mouse class

Mouse.java

 

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;


public class Mouse {
   public int x,y;
   public Stack<Coordinate> decisions;
   public List<Coordinate> solution;
   
   public Mouse(int x, int y){
      this.x = x;
      this.y = y;
      decisions = new Stack<Coordinate>();
      solution = new ArrayList<Coordinate>();
   }
}

Then we will make the coordinate class

Coordinate.java

public class Coordinate {
public int x,y;

public Coordinate(int x,int y){
   this.x = x;
   this.y = y;
}

@Override
public boolean equals(Object obj) {

   boolean sameSame = false;
   if (obj != null && obj instanceof Coordinate)
    {
      if(this.x == ((Coordinate)obj).x && this.y == ((Coordinate)obj).y){
         sameSame = true;
      }
        
    }
   return sameSame;
}
}

Now its time for the decision class

Decision.java

public class Decision {
   
   public boolean up,down,left,right;
   public int x,y;
   public Decision(int x, int y){
      up = down = left = right = false;
      this.x = x;
      this.y = y;
   }
   public Decision(boolean up,boolean down,boolean right,boolean left){
      this.up = up;
      this.down = down;
      this.right = right;
      this.left = left;
   }
   public void setLeft(boolean left){
      this.left = left;
   }
   public void setRight(boolean right){
      this.right = right;
   }
   public void setUp(boolean up){
      this.up = up;
   }
   public void setDown(boolean down){
      this.down = down;
   }
   @Override
   public String toString() {
      // TODO Auto-generated method stub
      return x + " x  --  y " + y;
   }

}

Now we have to make the maze class which does most of the hard work

Maze.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JComponent;




public class Maze extends JComponent{
   public char[][] maze = null;
   public Rectangle[][] rects = null;
   public boolean mousebool = false;
   public boolean backtrack = false;
   public Mouse mouse;
   public Random random = new Random();
   public Coordinate startingPoint;
   public boolean first = true;
   public boolean solv = true;
   public int lastx,lasty;
   public String navigation = "working!!!";

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
   
      if(maze != null){
      for(int i = 0;i < maze.length;i++){
         for(int j = 0;j < maze[0].length;j++){
            if(maze[i][j] == '1'){
               g.setColor(Color.BLACK);
               g.fillRect(rects[i][j].x, rects[i][j].y, rects[i][j].width, rects[i][j].height);
               g.setColor(Color.WHITE);
               g.drawRect(rects[i][j].x, rects[i][j].y, rects[i][j].width, rects[i][j].height);
            }else if(maze[i][j] == '0'){
               g.setColor(Color.white);
               g.fillRect(rects[i][j].x, rects[i][j].y, rects[i][j].width, rects[i][j].height);
               g.setColor(Color.BLACK);
               g.drawRect(rects[i][j].x, rects[i][j].y, rects[i][j].width, rects[i][j].height);
            }
         }
      }
      if(mousebool){
         g.setColor(Color.PINK);
         
         g.fillOval(rects[mouse.x][mouse.y].x, rects[mouse.x][mouse.y].y, rects[mouse.x][mouse.y].width, rects[mouse.x][mouse.y].height);
      }
      }
      
   }
   public void setMaze(char[][] maze){
      mousebool = false;
      this.maze = maze;
      rects = new Rectangle[maze.length][maze[0].length];
      for(int i = 0;i < rects.length;i++){
         for(int j = 0;j < rects[0].length;j++){
            rects[i][j] = new Rectangle(i * (getWidth()/rects.length),j * (getHeight()/rects[0].length)
                  ,getWidth()/rects.length,getHeight()/rects[0].length);
         }
      }
      repaint();
   }
   public void setMouse(int x,int y){
      mousebool = true;
      mouse = new Mouse(x,y);
      startingPoint = new Coordinate(x,y);
      mouse.solution.add(new Coordinate(x,y));
      mouse.decisions.push(new Coordinate(x,y));
      first = true;
      
      repaint();
   }
   public void solve(){
      

         if(mouse.x > 0 && mouse.x < maze.length - 1 && mouse.y > 0 && mouse.y < maze[0].length - 1 && mouse.decisions.size() > 0){
            
            
              //System.out.println(wasHere(coord) + "now");
            //north
              System.out.println(wasHere(new Coordinate(mouse.x,mouse.y - 1)) + "north");
              if (!(maze[mouse.x][mouse.y - 1] == '1') && !wasHere(new Coordinate(mouse.x,mouse.y - 1))) mouse.decisions.push(new Coordinate(mouse.x,mouse.y - 1));
            //east
              System.out.println(wasHere(new Coordinate(mouse.x + 1,mouse.y)) + "east");
              if (!(maze[mouse.x + 1][mouse.y] == '1') && !wasHere(new Coordinate(mouse.x + 1,mouse.y))) mouse.decisions.push(new Coordinate(mouse.x + 1,mouse.y));
              //west
              if (!(maze[mouse.x - 1][mouse.y] == '1') && !wasHere(new Coordinate(mouse.x - 1,mouse.y))) mouse.decisions.push(new Coordinate(mouse.x - 1,mouse.y));
             //south
              if(!(maze[mouse.x][mouse.y + 1] == '1') && !wasHere(new Coordinate(mouse.x,mouse.y + 1))) mouse.decisions.push(new Coordinate(mouse.x,mouse.y + 1));
              
             
            
              Coordinate coord = mouse.decisions.pop();
             
              mouse.x = coord.x;
              mouse.y = coord.y;
              
             
              mouse.solution.add(coord);
              
              

              ActionListener taskPerformer = new ActionListener() {
                    

                  @Override
                  public void actionPerformed(ActionEvent arg0) {
                     solve();
                     
                  }
                };
                javax.swing.Timer t = new javax.swing.Timer( 250, taskPerformer);
                t.setRepeats(false);
                t.start();  
              //solve();
               
               repaint();
         }else{
            solv = false;
            if(mouse.decisions.size() == 0){
               mouse.solution.clear();
               navigation = "there is no solution";
            }else{
               mouse.solution.clear();
               findPath(startingPoint.x,startingPoint.y);
               navigation = "maze complete";
            }
         }
         
         
         
         //solve();
   }
   public boolean findPath(int x,int y){
      if(x < 0 || y < 0 || x > maze.length - 1 || y > maze[0].length - 1)return false;
      
      if(!(x > 0 && x < maze.length - 1 && y > 0 && y < maze[0].length - 1) && maze[x][y] == '0')
         {
         mouse.solution.add(new Coordinate(x,y));
         return true;// && maze[x][y] == '0') return true;//&& maze[x][y] == '0') return true;
         }
      if(maze[x][y] == '1') return false;
      
      mouse.solution.add(new Coordinate(x,y));
      if(!mouse.solution.contains(new Coordinate(x,y - 1)))
      if(findPath(x,y-1) == true) return true;
      if(!mouse.solution.contains(new Coordinate(x+1,y)))
      if(findPath(x + 1,y) == true) return true;
      if(!mouse.solution.contains(new Coordinate(x,y+1)))
      if(findPath(x,y + 1)== true) return true;
      if(!mouse.solution.contains(new Coordinate(x-1,y)))
      if(findPath(x - 1,y)== true) return true;
      mouse.solution.remove(new Coordinate(x,y));
      return false;
   }
   
   public boolean wasHere(Coordinate coord){
      return mouse.solution.contains(coord);
   }
   public void TraverseMouse(int x){
      if(x < mouse.solution.size()){
         Coordinate coord = mouse.solution.get(x);
         mouse.x = coord.x;
         mouse.y = coord.y; 
         final int xt = x+=1;
         ActionListener taskPerformer = new ActionListener() {
              

            @Override
            public void actionPerformed(ActionEvent arg0) {
               TraverseMouse(xt);
               
            }
          };
          javax.swing.Timer t = new javax.swing.Timer( 250, taskPerformer);
          t.setRepeats(false);
          t.start();   
      }
      repaint();
      
      
   }
   public String Navigation(){
      return navigation;
   }
   }

And finally the Main class to make the GUI

Main.java

 

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;


public class Main {
public static int width;
public static int height;
public static char[][] maze1;
   public static void main(String[] args) {
      try {
           UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
       }catch(Exception ex) {
           ex.printStackTrace();
       }
      
      
      SwingUtilities.invokeLater(new Runnable() {
          public void run() {
              create();
          }
      });
   

   }
   public static void create(){
      JFrame frame = new JFrame("Mouse Maze");
      final Maze maze = new Maze();
      frame.setSize(500, 500);
      frame.setLocation((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth()/2)-264,
            (int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()/2)-330);
      maze.setSize(400, 400);
      Container content = frame.getContentPane();
      //Creates a new container
      content.setLayout(new BorderLayout());
      
      frame.add(maze,BorderLayout.CENTER);
      //frame.add(maze);
      JPanel panel = new JPanel(new BorderLayout());
      JPanel panel1 = new JPanel(new BorderLayout());
      JPanel panel2 = new JPanel(new BorderLayout());
      JPanel finish = new JPanel(new BorderLayout());
      final JLabel textFile = new JLabel("          ex: maze.txt         ");
      JButton pickFile = new JButton("Pick file");
      pickFile.addActionListener(new ActionListener(){

         @Override
         public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            JFileChooser chooser = new JFileChooser();
             FileNameExtensionFilter filter = new FileNameExtensionFilter(
                 ".txt file", "txt");
             chooser.setFileFilter(filter);
             
             int returnVal = chooser.showOpenDialog(null);
             if(returnVal == JFileChooser.APPROVE_OPTION) {
                try {
                  BufferedReader read = new BufferedReader(new FileReader(chooser.getSelectedFile()));
                  String rea = read.readLine();
                  String[] split = rea.split(" ");
                  width =  Integer.valueOf(split[0]);
                  height = Integer.valueOf(split[1]);
                  
                  String readline;
                  int num = 0;
                  maze1 = new char[width][height];
                  while((readline = read.readLine()) != null){
                     char[] ch = readline.toCharArray();
                     for(int i = 0;i < ch.length;i++){
                        maze1[i][num] = ch[i];
                     }
                     num++;
                  }
                  maze.setMaze(maze1);
               } catch (FileNotFoundException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
                textFile.setText(chooser.getSelectedFile().getName());
             }else{
                
             }
         }
         
      });
      
      panel.add(pickFile,BorderLayout.CENTER);
      panel.add(textFile,BorderLayout.WEST);
      JButton setMouse = new JButton("Set Mouse");
      final JTextField mouseText = new JTextField("x,y",15);
      JButton solve = new JButton("SOLVE");
      JButton traverse = new JButton("TRAVERSE");
      final JLabel error = new JLabel("ERROR MESSAGES!!!!");
      panel2.add(solve,BorderLayout.NORTH);
      panel2.add(traverse,BorderLayout.CENTER);
      panel2.add(error,BorderLayout.SOUTH);
      panel1.add(setMouse,BorderLayout.CENTER);
      panel1.add(mouseText,BorderLayout.WEST);
      finish.add(panel,BorderLayout.NORTH);
      finish.add(panel1,BorderLayout.CENTER);
      finish.add(panel2,BorderLayout.SOUTH);
      //content.setLayout(new BorderLayout());
      content.add(finish, BorderLayout.SOUTH);
      traverse.addActionListener(new ActionListener(){

         @Override
         public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            maze.TraverseMouse(0);
         }
         
      });
      solve.addActionListener(new ActionListener(){

         @Override
         public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            
               maze.solve();
               
               error.setText(maze.navigation);
            
         }
         
      });
      setMouse.addActionListener(new ActionListener(){

         @Override
         public void actionPerformed(ActionEvent arg0) {
            String mousePosition = mouseText.getText();
            String[] splitposition = mousePosition.split(",");
            try{
            int x = Integer.valueOf(splitposition[0]);
            int y = Integer.valueOf(splitposition[1]);
            if(x >= width || y >= height){
               error.setText("those coordinates are not in range of your maze, try again,  0-"+ (width - 1)+",0-"+(height-1));
            }else if(maze1[x][y] == '1'){
               error.setText("you cannot place the mouse on a wall, try again");
            }else{
               maze.setMouse(x, y);
               error.setText("coordinates set.");
            }
            }catch(NumberFormatException e){
               error.setText("You Must enter the mouse position \"x,y\" example:  10,20");
            }catch(ArrayIndexOutOfBoundsException e){
               e.printStackTrace();
               error.setText("You Must enter the mouse position \"x,y\" example:  10,20");
            }
            
         }
         
      });
      
      //frame.add(panel);
      
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      //makes it so you can close
      frame.setVisible(true);
      //char[][] ch = new char[][]{{'1','1','1','1'},{'1','0','0','1'},{'1','0','0','1'},{'1','1','1','1'}};
      //maze.setMaze(ch);
   }
      
      }
 

You will have to use a text file in this format where a 1 is a wall and a 0 is part of the path remember .txt file the first line means 10 width and 5 height for the maze


10 5
1111111111
1010001111
1011011111
1011000011
1111111111

 

You can try it and alter it to your own code, thanks for reading.

 

Author: John Rowan

I am a Computer Science major at West Chester University and I love everything to do with computers. My specialty is Android programming but I actually love to code in any language specifically learning new things.