即使我已检查边界

时间:2020-06-27 05:10:52

标签: java data-structures stack queue maze

我正在编写一个同时使用Stack和Queue解决迷宫的JAVA程序。我快完成了。但是我的代码崩溃,数组索引超出范围。很明显它从我的迷宫中消失了。

enter image description here

我已经制作了一种方法,可以检查索引是否在范围之内,但似乎无法正常工作,仍然给我一个错误。

也许解决方案正盯着我,但我似乎无法找出问题所在 抱歉,我的业余代码练习...我正在学习。 如果有人可以帮助我,我将不胜感激。 谢谢。

/*
The input is a simple text file: 
And this is what the output should look like. 

Please enter the input file name (.txt only):
sample1.txt
Processing sample1.txt...
The initial maze is:
#######
#...#S#
#F#...#
#######
The path found using a stack is:

#######
#***#S#
#F#***#
#######

Path from start to finish: (1, 5) (2, 5) (2, 4) (2, 3) (1, 3) (1, 2) (1, 1) (2, 1)
The path found using a queue is:

#######
#***#S#
#F#***#
#######

Path from start to finish: (1, 5) (2, 5) (2, 4) (2, 3) (1, 3) (1, 2) (1, 1) (2, 1)
Processing terminated normally.
*/
// this'll test the type of square
enum SquareType{
    START,
    FINISH,
    PATH,
    WALL,

}

// This will represent one location in the maze, it will stores information about
// that location, and update whether it is a path or a wall and whether it is
// a start/origin or finish/destination.
public class Position {
    // instance variables
    // these are the coordinates
    private int row;
    private int col;
    private SquareType type;
    private boolean visited;
    private Position prev; // reference to the previous position on the path

    // getters and setters
    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getCol() {
        return col;
    }

    public void setCol(int col) {
        this.col = col;
    }

    public SquareType getType() {
        return type;
    }

    public void setType(SquareType type) {
        this.type = type;
    }

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public Position getPrev() {
        return prev;
    }

    public void setPrev(Position prev) {
        this.prev = prev;
    }



    private static final String wall = "#";
    private static final String start = "S";
    private static final String finish = "F";
    private static final String path = ".";


    // reference to the previous position


    // Constructor accepts row, col and type
    public Position(int row, int col, SquareType type) {
        this.row = row;
        this.col = col;
        this.type = type;
        // the constructor should set the other fields to default values
        this.visited = false;
        this.prev = null;
    }

    // checks and indicates whether the position has been visited


    // displays the maze or lists the path
    public String pathString() {
        String myString = null;
        if (type == SquareType.WALL) {
            myString = wall;
        }
        if (type == SquareType.FINISH) {
            myString = finish;
        }
        if (type == SquareType.PATH) {
            myString = path;
        }
        if (type == SquareType.START) {
            myString = start;
        }
        return myString;
    }

    public String printCoordinates() {
        String str = "";
        str += " (";
        str += row;
        str += ", ";
        str += col;
        str += ") ";

        return str;
    }
}

// This class will store Positions,
// Queue will be implemented using Linked List
// this will be a circular linked list with end pointer

public class Queue {
    public class Node{
        public Position item;
        public Node next;

        public Node(Position item, Node next) {
            this.item = item;
            this.next = next;
        }
    }

    private Node last; // a pointer to the last node in the queue

    // Constructor
    public Queue() {
        last = null;
    }

    // checks if my list is empty
    public boolean isEmpty() {
        return last == null;
    }

    // inserts at the end of the list
    public void enqueue(Position item) {
        // last nodes's next pointer will point at new node
        // then point the new node to the first node
        // make the last point at new node
        if (!isEmpty()) {
            last.next = new Node(item, last.next);
            last = last.next;
        } else {
            // if it is the only node then make it point to itself
            last = new Node(item, null);
            last.next = last;
        }
    }

    // remove the front item and return it
    public Position dequeue() {
        // the first node has to be removed
        // i.e. last's next node
        // and last points at the end

        Position pos = null;
        if (isEmpty()) {
            System.out.println("Queue list is empty");
        } else {
            pos = last.next.item;
            // if there's more than one node
            if (last.next != last) {
                last.next = last.next.next;
            }else {
                // if there's only 1 node, delete it
                last = null;
            }
        }
        return pos;
    }

    // returns the front item
    // i.e. the last item's next item
    public Position front() {
        Position result = null;
        if (isEmpty()) {
            System.out.println("Queue list is empty");
        } else {
            result = last.next.item;
        }
        return result;
    }

}

// This class will store Positions
// Stack will be implemented using an array
public class Stack {
    private int top; // index of the top item (if any)
    private Position[] stack;

    // Constructor
    public Stack(int size){
        stack = new Position[size];
        top = -1;
    }

    // Pushes on top of the list
    public void push(Position data) {
        // check if the stack is full
        if (isFull()) {
            System.out.println("Stack is full");
        }else{
            top++; // increment top first
            stack[top] = data;
        }
    }

    // remove top item from stack and return it
    public Position pop() {
        Position topItem = null;
        if (isEmpty()) {
            System.out.println("Stack is empty");
        } else {
            // store the top item of the stack in topItem
            topItem = stack[top];
            stack[top] = null;
            top--;
        }
        return topItem;
    }

    // returns the top item of the stack
    public Position peek() {
        Position result = null;

        if (!isEmpty()) {
            result = stack[top];
        } else {
            System.out.println("ERROR: Stack is empty");
        }
        return result;
    }

    // returns the size
    public int size() {
        return top + 1;
    }

    // checks if my stack is empty
    // if my top index is -1 then stack is empty
    public boolean isEmpty() {
        return top == -1;
    }

    public boolean isFull() {
        return top == stack.length - 1;
    }

}

Position,Stack和Queue类很好。问题出在迷宫课上。

import java.io.*;
import java.util.Scanner;

public class Maze {
    // 2D array of Positions
    private Position[][] posArray;
    private int row;
    private int col;
    private Position start;
    private Position finish;

//    private static final String wall = "#";
//    private static final String start = "S";
//    private static final String finish = "F";
//    private static final String path = ".";

    //Maze constructor
    // read input file, create 2D array of appropriate size
    // then fill the array

    public Maze(String inputfile) {
        FileReader fileReaderIn;
        BufferedReader fileIn;
        String inputLine;
        try {
            fileReaderIn = new FileReader(inputfile);
            fileIn = new BufferedReader(fileReaderIn);
            String stringArray; // array to store words
            inputLine = fileIn.readLine();
            System.out.println("Processing line: " + inputfile);
            System.out.println();
            String size[];
            while (inputLine != null) {
                size = inputLine.split(" "); // splits the first line by space.
                //size[0] is the row
                // size[1] is the col
                row = Integer.parseInt(size[0]);
                col = Integer.parseInt(size[1]);
                posArray = new Position[row][col]; // create an array of size row x col

                // we have created the array reading the first line
                // now we have to read the next lines
                // and fill the array with what we have read.

                // read the next line till the number of rows
                for (int i = 0; i < row; i++) {
                    //inputLine = fileIn.readLine();
                    String nextLine = fileIn.readLine(); // keep reading the next line
                    String[] charArray = nextLine.split("");
                    for (int j = 0; j < col; j++) {
                        SquareType type = null;
                        if (charArray[j] .equals("#")) { // checking if the character read is equal to #
                            type = SquareType.WALL;
                        } else if (charArray[j] .equals( ".")) { // checking if the character read is equal to .
                            type = SquareType.PATH;
                        }else if (charArray[j]. equals("F")) { // checking if the character read is equal to F
                            type = SquareType.FINISH;
                            finish=new Position(i,j,SquareType.FINISH); // save Finish position when found, don't need the search method
                        }else if (charArray[j].equals("S")) { // checking if the character read is equal to S
                            type = SquareType.START;
                            start= new Position(i,j,SquareType.START); // saves the start position when found, don't need the search method
                        }
                        posArray[i][j] = new Position(i, j,type ); // creating our position type and filling the array
                    }
                    // now you have to separete the string line into characters
                    // and insert them into columns.
                }
                // read the next line and then store it in a string
                // separate the string into characters then put those characters in the array

                inputLine = fileIn.readLine(); // might not need this. you already have a loop for row

            }
            fileIn.close();

            //stackPath(start, finish, posArray);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }


    // This method searches using Stack
    // returns true if the search is successful
    public void stackSearch() {
        //Boolean result = false;
        Position current; // tracker

        // add start position to data structure
        Stack myStack = new Stack(row * col); // size of stack
        // add start position to stack
        myStack.push(start);
        // mark start position as visited
        start.isVisited();
        // while(stack not empty)
        while (!myStack.isEmpty()) {
                current = myStack.pop(); // curr = remove position from stack
                Position neighbour;
                if (current.equals(finish)) { // if (current is the finish)
                    //result = true;
                    // exit search
                    break; // maze is solved
                }

                // for (each neighbour of current that is an unvisited path)
                // while !neighbour.isVisited
                // if (!posArray[current.getRow() - 1][current.getCol()].equals("#") && !isVisited)

                else {
                    Position up = posArray[current.getRow() - 1][current.getCol()];    // UP
                    Position down = posArray[current.getRow() + 1][current.getCol()];  // DOWN
                    Position left = posArray[current.getRow()][current.getCol() - 1];   // LEFT
                    Position right = posArray[current.getRow()][current.getCol() + 1];  // RIGHT


                    if (isInMaze(up) && !up.equals("#") && !(up.isVisited())) { // if UP has .

                        neighbour = up; // UP is neighbour
                       // neighbour.isVisited();
                        neighbour.setVisited(true); // set UP to visited
                        // UP neighbour = current.getRow() - 1][current.getCol()
                        myStack.push(neighbour); // add neighbour to stack
                        // prev = current;
                        neighbour.setPrev(current); // we need to keep track of the previous node

                    }

                    if (isInMaze(down) && !down.equals("#") && !(down.isVisited())) { // if DOWN has .
                        neighbour = down; // DOWN is neighbour
                        neighbour.setVisited(true); // set DOWN to visited
                        myStack.push(neighbour); // add neighbour to stack
                        neighbour.setPrev(current); // we need to keep track of the previous node
                    }
                    if (isInMaze(left) && !left.equals("#") && !(left.isVisited())) { // if LEFT has .
                        neighbour = left; // LEFT is neighbour
                        neighbour.setVisited(true); // set LEFT to visited
                        myStack.push(neighbour);
                        neighbour.setPrev(current); // we need to keep track of the previous node

                    }
                    if (isInMaze(right) && !right.equals("#") && !right.isVisited()) { // if RIGHT has .
                        neighbour = right;
                        neighbour.setVisited(true); // set RIGHT to visited
                        myStack.push(neighbour);
                        neighbour.setPrev(current); // we need to keep track of the previous node
                    }
                }

            //result = true;
        }
        printMaze();
        //return result;
    }

    // This method searches using Queue
    // returns true if the search is successful
    public void queueSearch() {
        //Boolean result = false;
        Position current = null; // tracker
        Position neighbour = null;

        // add start position to data structure
        Queue myQueue = new Queue();
        // add start position to queue
        myQueue.enqueue(start);

        // mark start position as visited
        start.isVisited();
        // while(stack not empty)
        while (!myQueue.isEmpty()) {
            current = myQueue.dequeue(); // removes and returns the first node

            //neighbour.setPrev(null);
            if (current.equals(finish)) { // if (current is the finish)
                //result = true;
                // exit search
                break; // maze is solved
            }

            // for (each neighbour of current that is an unvisited path)
            // while !neighbour.isVisited
            // if (!posArray[current.getRow() - 1][current.getCol()].equals("#") && !isVisited)
            else {
                Position up = posArray[current.getRow() - 1][current.getCol()];    // UP
                Position down = posArray[current.getRow() + 1][current.getCol()];  // DOWN
                Position left = posArray[current.getRow()][current.getCol() - 1];   // LEFT
                Position right = posArray[current.getRow()][current.getCol() + 1];  // RIGHT

                if (isInMaze(up) && !up.equals("#") && !(up.isVisited())) { // if UP has .
                    neighbour = up; // UP is neighbour
                    neighbour.setVisited(true); // set UP to visited
                    myQueue.enqueue(neighbour); // add neighbour to Queue
                    // prev = current;
                    neighbour.setPrev(current); // we need to keep track of the previous node
                }
                if (isInMaze(down) && !down.equals("#") && !(down.isVisited())) { // if DOWN has .
                    neighbour = down; // DOWN is neighbour
                    neighbour.setVisited(true); // set DOWN to visited
                    myQueue.enqueue(neighbour); // add neighbour to Queue
                    neighbour.setPrev(current); // we need to keep track of the previous node
                }
                if (isInMaze(left) && !left.equals("#") && !(left.isVisited())) { // if LEFT has .
                    neighbour = left; // LEFT is neighbour
                    neighbour.setVisited(true); // set LEFT to visited
                    myQueue.enqueue(neighbour); // add neighbour to Queue
                    neighbour.setPrev(current); // we need to keep track of the previous node
                }
                if (isInMaze(right) && !right.equals("#") && !(right.isVisited())) { // if RIGHT has .
                    neighbour = right;
                    neighbour.setVisited(true); // set RIGHT to visited
                    myQueue.enqueue(neighbour); // add neighbour to Queue
                    neighbour.setPrev(current); // we need to keep track of the previous node

                }
                // mark here if VISITED
                // I have the coordinates for Position and I can set the type to *
                // neighbour.setMarked() or current as visited
                // mark that position
                // mark(neighbour.getRow(), neighbour.getCol(), "*");
                // set neighbour to marked, return a boolean with that position
                // then in the print statement check which ones are marked
                // print the ones that are marked with *
                // i already marked the visited ones as true
            }

            //result = true;
        }
        printMaze();
       // return result;

    }

    //true if cell is within maze
    public boolean isInMaze(int i, int j) {
        if (i >= 0 && i<this.row && j>= 0 && j<this.col) {
            return true;
        }
        else {
            return false;
        }
    }
    //true if cell is within maze
    public boolean isInMaze(Position pos) {
        return isInMaze(pos.getRow(), pos.getCol());
    }


    // print the maze
    public void printMaze() {
        for (int i=0; i<row; i++) {
            for (int j=0; j<col; j++) {
                System.out.print(posArray[i][j].pathString());
                //System.out.print(' ');
            }
            System.out.println();
        }
    }

    // clear all visited cells
    // resetMaze() : reset all Positions in the maze to unvisited
    public void resetMaze() {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                posArray[i][j].setVisited(false); // clear visited to not visited
            }
        }
    }
    // marks the visited position to *
    public void mark(int i, int j, SquareType type) {
        Position temp = posArray[i][j];
        temp.setType(type);
    }

//    public Position[][] array(int i, int j, Position[][] posArray) { // keep track of positions that are .
//        Position[][] dot = new Position[1][4];
//
//        if (!posArray[i - 1][j].equals("#")) {// up}
//            dot[0][0] = posArray[i - 1][j];
//        }
//            if (!posArray[i + 1][j].equals("#")) {
//                dot[0][1] = posArray[i+1][j];
//            }  // down
//
//            if (!posArray[i][j - 1].equals("#")) {
//                dot[0][2] = posArray[i][j - 1];
//            }; // left
//            if (!posArray[i][j + 1].equals("#")) {
//                ; // right}
//                dot[0][3] = posArray[i][j + 1];
//            }
//        return dot;
//    }



}

0 个答案:

没有答案