Picture 1 down below is of a Maze program I wrote as it looks when you open it. Picture 2 is the same Maze after the program finds its way out.

I want to alter the code so the program adds each blue spot one at a time as it works its way through the maze, and if it hits a dead end, to erase each blue dot one at a time as it backs up. The code for the system to find its way through the maze is below. I'm a first year java programmer, so I'm sorry if it's a little unorthodox or anything. For instance, I know this could be a lot shorter. I could rewrite it with fewer if statements and such.

When the code hits square (5,3) I'd like the blue dots to keep going up and search the upper right chamber, and then back up and move on to square (6,3) when it realizes it went into a dead end.

I've tried a few different things with the Sleep() method, but all it seems to do is lengthen the time it takes for the whole maze to update with the blue path straight through.

Thanks for your help.

public void findNext(int x, int y) {
        maze[x][y].beenTested = true;
        maze[x][y].addSpot();
		
        if(y == 9) {
            foundExit = true;
        }
        if (y > 0) {
            if ((maze[x][y-1].isOpen) && !(maze[x+1][y].beenTested) && !(foundExit)) {
                findNext(x + 1, y);
            }
        }
        if (x < 9) {
            if ((maze[x+1][y].isOpen) && !(maze[x][y+1].beenTested) && !(foundExit)) {
                findNext(x, y + 1);
            }
        }
        if (y < 9) {
            if ((maze[x][y+1].isOpen) && !(maze[x-1][y].beenTested) && !(foundExit)) {
                findNext(x - 1, y);
            }
        }
        if (x > 0) {
            if ((maze[x-1][y].isOpen) && !(maze[x][y-1].beenTested) && !(foundExit)) {
                findNext(x, y - 1);
            }
        }
        if(!foundExit) {
            maze[x][y].removeSpot();
        }
    }

Recommended Answers

All 11 Replies

What thread does your findNext run on? Is it on the Swing thread (started in reponse to a user input)?
Real-time UI updates like this typically fail because the "worker" code is running on the Swing thread and thus blocks Swings normal UI activity until it finishes. Sleeping doesn't help in this case because its the Swing thread that is slept. You need to run findNext in a "worker" thread so the Swing thread can update the UI when you sleep the worker.
If all this is new to you, read http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html

commented: Good one. +2

I think that's what's going on. Does this mean I have to move my findNext() to a new class? Could you give me an example of how to do that? I've used the TumbleItem applet code, and the "How to use Swing Timers" tutorial to try and do it, and the only thing I can think of that I haven't tried is moving everything but my main method to a new class, and I'm not sure how to do that without messing things up.

I have a class for each event button class, and 4 other button classes that each extend event button, as well as 2 classes that combine to create the spotted squares. And then my main method basically handles everything else. This was originally designed to run in BlueJ, but I moved it out and added a very very simple main method that just starts the Driver() from BlueJ.

I'd have to be extremely careful about moving code into a new class. Is there anyway I can do what I'm hoping to do without creating a new class? My entire Driver() is below. Can you help?

/**
 * Assignment 7
 * Date: December 1, 2008
 * Author: ***** ********
 * 
 * This driver creates a window and adds a
 * 2 dimensional array of rectangles for the
 * basis of a maze as well as various tools
 * to control different aspects of the maze.
 */

import javax.swing.*;
import java.awt.*;
import javax.swing.Timer;

public class Driver {

    public JFrame           mazeWindow;
    public Marker[][]       maze;
    public final int        maxR = 10, maxC = 10;
    public Label            xVal, yVal, result;
    public Label[]          xVals, yVals, instructions;
    public TextField        xField, yField;
    private boolean         foundExit;
    public openButton       oButton;
    public closeButton      cButton;
    public MazeButton       mButton;
    public ClearButton      rButton;
    
    public Driver() {
        
        mazeWindow = new JFrame("Maze");
        mazeWindow.setBounds(20, 50, 732, 550);
        mazeWindow.setLayout(null);
        mazeWindow.setVisible(true);
        mazeWindow.setResizable(false);
        mazeWindow.setBackground(Color.white);
        
        xVal = new Label("X Value", Label.CENTER);
        xVal.setBounds(570, 318, 50, 25);
        mazeWindow.add(xVal);
        
        xField = new TextField();
        xField.setBounds(625, 315, 25, 25);
        mazeWindow.add(xField);
        
        yVal = new Label("Y Value", Label.CENTER);
        yVal.setBounds(570, 348, 50, 25);
        mazeWindow.add(yVal);
        
        yField = new TextField();
        yField.setBounds(625, 345, 25, 25);
        mazeWindow.add(yField);
        
        oButton = new openButton(525, 375, this);
        mazeWindow.add(oButton);
        
        cButton = new closeButton(615, 375, this);
        mazeWindow.add(cButton);
        
        mButton = new MazeButton(525, 175, this);
        mazeWindow.add(mButton);
        
        rButton = new ClearButton(525, 410, this);
        mazeWindow.add(rButton);
        
	maze = new Marker[maxR][maxC];
        createGrid(50, 50);
        createMaze();        
        
	xVals = new Label[maxR + 1];
        yVals = new Label[maxC + 1];
        
        createLabels();
        createInstructions();
        
        result = new Label(new String(), Label.CENTER);
        result.setBounds(525, 270, 180, 25);
        mazeWindow.add(result);
        
        
        
        mazeWindow.repaint();
        
    }
    
    private void createGrid(int x, int y) {
        
        final int index = y;
               
        for (int r = 0; r < maxR; r++) {
            for (int c = 0; c < maxC; c++) {
                maze[r][c] = new Marker(x, y, 45, 45);
                y = y + 45;
                mazeWindow.add(maze[r][c]);
                
            }
            x = x + 45;
            y = index;
        }
    }
    
    private void createMaze() {
        
        maze[1][2].setOpen();
        maze[1][3].setOpen();
        maze[1][4].setOpen();
        maze[1][5].setOpen();
        maze[1][7].setOpen();
        maze[1][8].setOpen();
        maze[2][0].setOpen();
        maze[2][1].setOpen();
        maze[2][2].setOpen();
        maze[2][5].setOpen();
        maze[2][6].setOpen();
        maze[2][7].setOpen();
        maze[3][5].setOpen();
        maze[4][1].setOpen();
        maze[4][4].setOpen();
        maze[4][5].setOpen();
        maze[4][7].setOpen();
        maze[4][8].setOpen();
        maze[4][9].setOpen();
        maze[5][1].setOpen();
        maze[5][2].setOpen();
        maze[5][3].setOpen();
        maze[5][4].setOpen();
        maze[5][8].setOpen();
        maze[6][1].setOpen();
        maze[6][3].setOpen();
        maze[6][6].setOpen();
        maze[6][8].setOpen();
        maze[7][1].setOpen();
        maze[7][3].setOpen();
        maze[7][4].setOpen();
        maze[7][5].setOpen();
        maze[7][6].setOpen();
        maze[7][8].setOpen();
        maze[8][1].setOpen();
        maze[8][2].setOpen();
        maze[8][6].setOpen();
        maze[8][7].setOpen();
        maze[8][8].setOpen();
               
    }
    
    public void createLabels() {
        
        String temp;
        int x = 50, y = 65;
        
        for (int a = 0; a < maxC; a++) {
            temp = Integer.toString(a);
            xVals[a] = new Label(temp, Label.CENTER);
            xVals[a].setBounds(x, 25, 45, 25);
            mazeWindow.add(xVals[a]);
            x = x + 45;
        }
        
        xVals[maxC] = new Label("X", Label.CENTER);
        xVals[maxC].setBounds(260, 5, 30, 25);
        mazeWindow.add(xVals[maxC]);
        
        for (int b = 0; b < maxR; b++) {
            temp = Integer.toString(b);
            yVals[b] = new Label(temp, Label.CENTER);
            yVals[b].setBounds(25, y, 25, 45);
            mazeWindow.add(yVals[b]);
            y = y + 45;
        }
        
        yVals[maxR] = new Label("Y", Label.CENTER);
        yVals[maxR].setBounds(5, 265, 25, 45);
        mazeWindow.add(yVals[maxR]);
    }
    
    private void createInstructions() {
        
        final int i = 4;
        
        instructions = new Label[i];
        
        instructions[0] = new Label("CREATE ANY MAZE YOU WISH", Label.CENTER);
        instructions[0].setBounds(510, 25, 220, 25);
        
        instructions[1] = new Label("There are only 2 rules:");
        instructions[1].setBounds(510, 60, 220, 25);
        
        instructions[2] = new Label("1) The entrance must be in row 0.");
        instructions[2].setBounds(510, 85, 220, 25);
        
        instructions[3] = new Label("2) The exit must be in row 9.");
        instructions[3].setBounds(510, 110, 220, 25);
        
        for(int x = 0; x < i; x++)
            mazeWindow.add(instructions[x]);            
    }
 
    
    public void open() {
        
        int x, y;
        
        x = Integer.parseInt(xField.getText());
        y = Integer.parseInt(yField.getText());
        if((x >= 0) && (x <= 9) && (y >= 0) && (y <= 9))
            maze[x][y].setOpen();
               
        xField.setText(new String());
        yField.setText(new String());
    }
    
    public void close() {
    
        int x, y;
        
        x = Integer.parseInt(xField.getText());
        y = Integer.parseInt(yField.getText());
        if((x >= 0) && (x <= 9) && (y >= 0) && (y <= 9))
            maze[x][y].setClosed();
               
        xField.setText(new String());
        yField.setText(new String());
    }
    
    public void tryMaze() {
        
        int start = findStart();
        boolean flag = false;
		
        if(start == 10) {
            result.setText("No Way In");
        }
        else {
            findNext(start, 0);
            flag = true;
        }
        if (flag) {
            if (foundExit) {
                result.setText("Made It Out");
            }
            else {
                result.setText("No Way Out");
            }
        }
        flag = false;
        mazeWindow.repaint();
    }
    
    public int findStart() {
        
        int s = 10, c = 0;
        boolean foundStart = false;
        
        while ((!foundStart) && (c < maxC)) {
            if(maze[c][0].isOpen) {
                foundStart = true;
                maze[c][0].partOfPath = true;
                s = c;
            }
            c++;
        }
        return s;
    }
    
    public void findNext(int x, int y) {
    
		
		
        maze[x][y].beenTested = true;
        maze[x][y].addSpot();
	mazeWindow.repaint();
		
        if(y == 9) {
            foundExit = true;
        }
        if (x < 9) {
            if ((maze[x+1][y].isOpen) && !(maze[x+1][y].beenTested) && !(foundExit)) {
                findNext(x + 1, y);
            }
        }
        if (y < 9) {
            if ((maze[x][y+1].isOpen) && !(maze[x][y+1].beenTested) && !(foundExit)) {
                findNext(x, y + 1);
            }
        }
        if (x > 0) {
            if ((maze[x-1][y].isOpen) && !(maze[x-1][y].beenTested) && !(foundExit)) {
                findNext(x - 1, y);
            }
        }
        if (y > 0) {
            if ((maze[x][y-1].isOpen) && !(maze[x][y-1].beenTested) && !(foundExit)) {
                findNext(x, y - 1);
            }
        }
        if(!foundExit) {
            maze[x][y].removeSpot();
        }
    }
    
public void clearMaze() {
        
        result.setText(new String());
        for(int r = 0; r < maxR; r++) {
            for(int c = 0; c < maxC; c++) {
                maze[r][c].beenTested = false;
                maze[r][c].partOfPath = false;
                maze[r][c].removeSpot();
            }
        }
        mazeWindow.repaint();
        foundExit = false;
    }
	
	public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
		Driver app = new Driver();
						
		}
		});
	}	
}

I guess that tryMaze is the entry point where the real work starts, and that you call it in response to the button being clicked. Just change that call to run in another thread, using an anonymous inner class something like this:

new Runnable() {
	public void run() {
		// call your tryMaze here
	}
}.start();

(didn't have time to check that exactly, done from memory)

I guess that tryMaze is the entry point where the real work starts, and that you call it in response to the button being clicked. Just change that call to run in another thread, using an anonymous inner class something like this:

new Runnable() {
	public void run() {
		// call your tryMaze here
	}
}.start();

(didn't have time to check that exactly, done from memory)

So when the button is pressed, have the code above execute, and have the above code call tryMaze? Then where do I put the timer and stuff?

So when the button is pressed, have the code above execute, and have the above code call tryMaze? Then where do I put the timer and stuff?

Yes, just that, you don't need the timers etc, this should be sufficient (assuming I typed it ok!). Now, when your method does its sleep(...) the Java Swing thread will be able to run and process window updates.

Oops- I did miss-type, missed the line with the Thread! This should be better

new Thread(
  new Runnable() {
	public void run() {
		// call your tryMaze here
	}
  }
).start();

I got it working! It does exactly what I wanted it to do. You're my new favorite person on the internet James. Thanks a lot.

Great! Glad to help.
May I make a completely shameless request for you to show your appreciation by giving me an "add to JamesCherrill's reputation"?
It's up to you, of course.

I had already done it! But definitely no shame in asking, especially since I had messed with it for hours before remembering this website and hadn't made any progress.

I think that's what's going on. Does this mean I have to move my findNext() to a new class? Could you give me an example of how to do that? I've used the TumbleItem applet code, and the "How to use Swing Timers" tutorial to try and do it, and the only thing I can think of that I haven't tried is moving everything but my main method to a new class, and I'm not sure how to do that without messing things up.

I have a class for each event button class, and 4 other button classes that each extend event button, as well as 2 classes that combine to create the spotted squares. And then my main method basically handles everything else. This was originally designed to run in BlueJ, but I moved it out and added a very very simple main method that just starts the Driver() from BlueJ.

I'd have to be extremely careful about moving code into a new class. Is there anyway I can do what I'm hoping to do without creating a new class? My entire Driver() is below. Can you help?

/**
 * Assignment 7
 * Date: December 1, 2008
 * Author: ***** ********
 * 
 * This driver creates a window and adds a
 * 2 dimensional array of rectangles for the
 * basis of a maze as well as various tools
 * to control different aspects of the maze.
 */

import javax.swing.*;
import java.awt.*;
import javax.swing.Timer;

public class Driver {

    public JFrame           mazeWindow;
    public Marker[][]       maze;
    public final int        maxR = 10, maxC = 10;
    public Label            xVal, yVal, result;
    public Label[]          xVals, yVals, instructions;
    public TextField        xField, yField;
    private boolean         foundExit;
    public openButton       oButton;
    public closeButton      cButton;
    public MazeButton       mButton;
    public ClearButton      rButton;
    
    public Driver() {
        
        mazeWindow = new JFrame("Maze");
        mazeWindow.setBounds(20, 50, 732, 550);
        mazeWindow.setLayout(null);
        mazeWindow.setVisible(true);
        mazeWindow.setResizable(false);
        mazeWindow.setBackground(Color.white);
        
        xVal = new Label("X Value", Label.CENTER);
        xVal.setBounds(570, 318, 50, 25);
        mazeWindow.add(xVal);
        
        xField = new TextField();
        xField.setBounds(625, 315, 25, 25);
        mazeWindow.add(xField);
        
        yVal = new Label("Y Value", Label.CENTER);
        yVal.setBounds(570, 348, 50, 25);
        mazeWindow.add(yVal);
        
        yField = new TextField();
        yField.setBounds(625, 345, 25, 25);
        mazeWindow.add(yField);
        
        oButton = new openButton(525, 375, this);
        mazeWindow.add(oButton);
        
        cButton = new closeButton(615, 375, this);
        mazeWindow.add(cButton);
        
        mButton = new MazeButton(525, 175, this);
        mazeWindow.add(mButton);
        
        rButton = new ClearButton(525, 410, this);
        mazeWindow.add(rButton);
        
	maze = new Marker[maxR][maxC];
        createGrid(50, 50);
        createMaze();        
        
	xVals = new Label[maxR + 1];
        yVals = new Label[maxC + 1];
        
        createLabels();
        createInstructions();
        
        result = new Label(new String(), Label.CENTER);
        result.setBounds(525, 270, 180, 25);
        mazeWindow.add(result);
        
        
        
        mazeWindow.repaint();
        
    }
    
    private void createGrid(int x, int y) {
        
        final int index = y;
               
        for (int r = 0; r < maxR; r++) {
            for (int c = 0; c < maxC; c++) {
                maze[r][c] = new Marker(x, y, 45, 45);
                y = y + 45;
                mazeWindow.add(maze[r][c]);
                
            }
            x = x + 45;
            y = index;
        }
    }
    
    private void createMaze() {
        
        maze[1][2].setOpen();
        maze[1][3].setOpen();
        maze[1][4].setOpen();
        maze[1][5].setOpen();
        maze[1][7].setOpen();
        maze[1][8].setOpen();
        maze[2][0].setOpen();
        maze[2][1].setOpen();
        maze[2][2].setOpen();
        maze[2][5].setOpen();
        maze[2][6].setOpen();
        maze[2][7].setOpen();
        maze[3][5].setOpen();
        maze[4][1].setOpen();
        maze[4][4].setOpen();
        maze[4][5].setOpen();
        maze[4][7].setOpen();
        maze[4][8].setOpen();
        maze[4][9].setOpen();
        maze[5][1].setOpen();
        maze[5][2].setOpen();
        maze[5][3].setOpen();
        maze[5][4].setOpen();
        maze[5][8].setOpen();
        maze[6][1].setOpen();
        maze[6][3].setOpen();
        maze[6][6].setOpen();
        maze[6][8].setOpen();
        maze[7][1].setOpen();
        maze[7][3].setOpen();
        maze[7][4].setOpen();
        maze[7][5].setOpen();
        maze[7][6].setOpen();
        maze[7][8].setOpen();
        maze[8][1].setOpen();
        maze[8][2].setOpen();
        maze[8][6].setOpen();
        maze[8][7].setOpen();
        maze[8][8].setOpen();
               
    }
    
    public void createLabels() {
        
        String temp;
        int x = 50, y = 65;
        
        for (int a = 0; a < maxC; a++) {
            temp = Integer.toString(a);
            xVals[a] = new Label(temp, Label.CENTER);
            xVals[a].setBounds(x, 25, 45, 25);
            mazeWindow.add(xVals[a]);
            x = x + 45;
        }
        
        xVals[maxC] = new Label("X", Label.CENTER);
        xVals[maxC].setBounds(260, 5, 30, 25);
        mazeWindow.add(xVals[maxC]);
        
        for (int b = 0; b < maxR; b++) {
            temp = Integer.toString(b);
            yVals[b] = new Label(temp, Label.CENTER);
            yVals[b].setBounds(25, y, 25, 45);
            mazeWindow.add(yVals[b]);
            y = y + 45;
        }
        
        yVals[maxR] = new Label("Y", Label.CENTER);
        yVals[maxR].setBounds(5, 265, 25, 45);
        mazeWindow.add(yVals[maxR]);
    }
    
    private void createInstructions() {
        
        final int i = 4;
        
        instructions = new Label[i];
        
        instructions[0] = new Label("CREATE ANY MAZE YOU WISH", Label.CENTER);
        instructions[0].setBounds(510, 25, 220, 25);
        
        instructions[1] = new Label("There are only 2 rules:");
        instructions[1].setBounds(510, 60, 220, 25);
        
        instructions[2] = new Label("1) The entrance must be in row 0.");
        instructions[2].setBounds(510, 85, 220, 25);
        
        instructions[3] = new Label("2) The exit must be in row 9.");
        instructions[3].setBounds(510, 110, 220, 25);
        
        for(int x = 0; x < i; x++)
            mazeWindow.add(instructions[x]);            
    }
 
    
    public void open() {
        
        int x, y;
        
        x = Integer.parseInt(xField.getText());
        y = Integer.parseInt(yField.getText());
        if((x >= 0) && (x <= 9) && (y >= 0) && (y <= 9))
            maze[x][y].setOpen();
               
        xField.setText(new String());
        yField.setText(new String());
    }
    
    public void close() {
    
        int x, y;
        
        x = Integer.parseInt(xField.getText());
        y = Integer.parseInt(yField.getText());
        if((x >= 0) && (x <= 9) && (y >= 0) && (y <= 9))
            maze[x][y].setClosed();
               
        xField.setText(new String());
        yField.setText(new String());
    }
    
    public void tryMaze() {
        
        int start = findStart();
        boolean flag = false;
		
        if(start == 10) {
            result.setText("No Way In");
        }
        else {
            findNext(start, 0);
            flag = true;
        }
        if (flag) {
            if (foundExit) {
                result.setText("Made It Out");
            }
            else {
                result.setText("No Way Out");
            }
        }
        flag = false;
        mazeWindow.repaint();
    }
    
    public int findStart() {
        
        int s = 10, c = 0;
        boolean foundStart = false;
        
        while ((!foundStart) && (c < maxC)) {
            if(maze[c][0].isOpen) {
                foundStart = true;
                maze[c][0].partOfPath = true;
                s = c;
            }
            c++;
        }
        return s;
    }
    
    public void findNext(int x, int y) {
    
		
		
        maze[x][y].beenTested = true;
        maze[x][y].addSpot();
	mazeWindow.repaint();
		
        if(y == 9) {
            foundExit = true;
        }
        if (x < 9) {
            if ((maze[x+1][y].isOpen) && !(maze[x+1][y].beenTested) && !(foundExit)) {
                findNext(x + 1, y);
            }
        }
        if (y < 9) {
            if ((maze[x][y+1].isOpen) && !(maze[x][y+1].beenTested) && !(foundExit)) {
                findNext(x, y + 1);
            }
        }
        if (x > 0) {
            if ((maze[x-1][y].isOpen) && !(maze[x-1][y].beenTested) && !(foundExit)) {
                findNext(x - 1, y);
            }
        }
        if (y > 0) {
            if ((maze[x][y-1].isOpen) && !(maze[x][y-1].beenTested) && !(foundExit)) {
                findNext(x, y - 1);
            }
        }
        if(!foundExit) {
            maze[x][y].removeSpot();
        }
    }
    
public void clearMaze() {
        
        result.setText(new String());
        for(int r = 0; r < maxR; r++) {
            for(int c = 0; c < maxC; c++) {
                maze[r][c].beenTested = false;
                maze[r][c].partOfPath = false;
                maze[r][c].removeSpot();
            }
        }
        mazeWindow.repaint();
        foundExit = false;
    }
	
	public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
		Driver app = new Driver();
						
		}
		});
	}	
}

i got problem with Marker , it is not reconize by complier. pls hepl thank u

please help me on this issue, i could not complie tis maze. i am waiting ur reply, dun kno where i made mistake

please help me on this issue, i could not complie tis maze. i am waiting ur reply, dun kno where i made mistake

This thread has been marked solved, so people tend not to respond. You should start a new thread.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.