Java code - maze path search based on breadth first traversal

Keywords: Java

The previous article demonstrated that the shortest maze path can not be obtained by searching maze path through depth first traversal, so the best maze path information can be found through breadth first traversal and layer by layer outward expansion. The idea of breadth first traversal layer outward expansion can be realized with a queue, and then the walking information of nodes can be printed with an array. The code runs as follows: Next:

Please enter the number of rows and columns in the maze: 5 5
 Please enter maze path
0 0 1 1 1 
1 0 0 0 0
1 0 0 0 0
1 1 0 1 1
1 1 0 0 0
 The maze path search results are as follows:
* * 1 1 1 
1 * 0 0 0 
1 * * 0 0 
1 1 * 1 1 
1 1 * * * 

Constant definition

/**
 * Description: define all constants in the code uniformly here
 * @Author administrator
 * @Date 5/18
 */
public interface Constant {
    // Right direction
    int RIGHT = 0;
    // Downward direction
    int DOWN = 1;
    // Left direction
    int LEFT = 2;
    // Upper direction
    int UP = 3;
}

Maze node type definition

The maze uses stack to realize non recursive path search. You can directly use Java set LinkedList. Here is a custom chain stack structure. The code is as follows:

/**
 * Description: chain stack structure for maze path search
 */
public class Stack<T> {
    // Top points to the head node, which is followed by the stack top node
    private Entry<T> top;

    public Stack(){
        this.top = new Entry<>(null, null);
    }

    /**
     * Stack operation
     * @param val
     */
    public void push(T val){
        Entry<T> node = new Entry<>(val, this.top.next);
        this.top.next = node;
    }

    /**
     * Stack operation
     * @return
     */
    public T pop(){
        T val = null;
        if(this.top.next != null){
            val = this.top.next.data;
            this.top.next = this.top.next.next;
        }
        return val;
    }

    /**
     * View top of stack elements
     * @return
     */
    public T peek(){
        T val = null;
        if(this.top.next != null){
            val = this.top.next.data;
        }
        return val;
    }

    /**
     * Judge stack space
     * @return
     */
    public boolean isEmpty(){
        return this.top.next == null;
    }

    /**
     * Node type definition
     * @param <T>
     */
    static class Entry<T>{
        T data;
        Entry<T> next;

        public Entry(T data, Entry<T> next) {
            this.data = data;
            this.next = next;
        }
    }
}

Maze class definition

Maze node class MazeNode and maze type maze are mainly included here. The code is as follows:

/**
 * Description: type definition of maze
 */
public class Maze {
    // All paths of maze are stored in two-dimensional array
    private MazeNode[][] maze;
    // The queue structure of maze path node is stored, and the way of layer by layer expansion is used to find the optimal path information of maze
    private LinkQueue<MazeNode> queue;
    // Lines of maze
    private int row;
    // Number of columns in maze
    private int col;
    // Record the walking information of maze path node
    private MazeNode[] pathrecord;

    /**
     * Maze initialization
     * @param row
     * @param col
     */
    public Maze(int row, int col) {
        this.row = row;
        this.col = col;
        this.maze = new MazeNode[row][col];
        this.queue = new LinkQueue<>();
        this.pathrecord = new MazeNode[row*col];
    }

    /**
     * Initialize maze node at specified location
     * @param data
     * @param i
     * @param j
     */
    public void initMazeNode(int data, int i, int j) {
        this.maze[i][j] = new MazeNode(data, i, j);
    }

    /**
     * Modify the walking status information of all nodes in maze in four directions
     */
    public void initMazeNodePathState() {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {

                if(j<col-1 && this.maze[i][j+1].val == 0){
                    this.maze[i][j].state[Constant.RIGHT] = true;
                }

                if(i<row-1 && this.maze[i+1][j].val == 0){
                    this.maze[i][j].state[Constant.DOWN] = true;
                }

                if(j>0 && this.maze[i][j-1].val == 0){
                    this.maze[i][j].state[Constant.LEFT] = true;
                }

                if(i>0 && this.maze[i-1][j].val == 0){
                    this.maze[i][j].state[Constant.UP] = true;
                }
            }
        }
    }

    /**
     * Find maze path
     */
    public void findMazePath() {
        if(maze[0][0].val == 1){
            return;
        }

        queue.offer(maze[0][0]);
        while(!queue.isEmpty()){
            MazeNode top = queue.peek();
            int x = top.x;
            int y = top.y;
            if(x == row-1 && y == col-1){
                return;
            }

            // Go right
            if(maze[x][y].state[Constant.RIGHT]){
                maze[x][y].state[Constant.RIGHT] = false;
                maze[x][y+1].state[Constant.LEFT] = false;
                queue.offer(maze[x][y+1]);
                pathrecord[x*col+y+1] = maze[x][y];
            }

            // Go down
            if(maze[x][y].state[Constant.DOWN]){
                maze[x][y].state[Constant.DOWN] = false;
                maze[x+1][y].state[Constant.UP] = false;
                queue.offer(maze[x+1][y]);
                pathrecord[(x+1)*col+y] = maze[x][y];
            }

            // Go left
            if(maze[x][y].state[Constant.LEFT]){
                maze[x][y].state[Constant.LEFT] = false;
                maze[x][y-1].state[Constant.RIGHT] = false;
                queue.offer(maze[x][y-1]);
                pathrecord[x*col+y-1] = maze[x][y];
            }

            // Go up
            if(maze[x][y].state[Constant.UP]){
                maze[x][y].state[Constant.UP] = false;
                maze[x-1][y].state[Constant.DOWN] = false;
                queue.offer(maze[x-1][y]);
                pathrecord[(x-1)*col+y] = maze[x][y];
            }

            queue.poll();
        }
    }

    /**
     * Print maze path search results
     */
    public void showMazePath() {
        System.out.println("The maze path search results are as follows:");
        if(pathrecord[row*col-1] == null){
            System.out.println("Maze does not have a valid path");
        } else {
            int x = row-1;
            int y = col-1;
            for(;;){
                maze[x][y].val = '*';
                MazeNode node = pathrecord[x*col+y];
                if(node == null){
                    break;
                }
                x = node.x;
                y = node.y;
            }

            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if(maze[i][j].val == '*'){
                        System.out.print('*' + " ");
                    } else {
                        System.out.print(maze[i][j].val + " ");
                    }
                }
                System.out.println();
            }
        }
    }

    /**
     * Description: define maze node type
     */
    private static class MazeNode {
        // Node value
        int val;
        // x and y coordinates of nodes
        int x;
        int y;
        // The walking state of the node in four directions. true means it can walk, false means it can't walk
        boolean[] state;

        /**
         * Maze path initialization
         * @param data
         * @param i
         * @param j
         */
        public MazeNode(int data, int i, int j){
            this.state = new boolean[4];
            this.val = data;
            this.x = i;
            this.y = j;
        }
    }
}

Test function

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.print("Please enter the number of rows and columns in the maze:");
    int row, col, data;
    row = in.nextInt();
    col = in.nextInt();

    Maze maze = new Maze(row, col);

    System.out.println("Please enter maze path");
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            data = in.nextInt();
            maze.initMazeNode(data, i, j);
        }
    }

    // Modify the walking status information of all nodes in maze in four directions
    maze.initMazeNodePathState();
    // Find maze path
    maze.findMazePath();
    // Print maze path search results
    maze.showMazePath();
}

Posted by monkey72 on Fri, 08 Nov 2019 12:44:12 -0800