我的迷宫一直在想第一个正方形有右墙

时间:2019-02-04 04:41:17

标签: java linked-list stack maze

我正在尝试打印一个迷宫,并且还打印正方形的星星,这是迷宫解决方案的一部分(使用堆栈“ LLStack”)。我有两个文件: Maze.java-负责从给定文件中加载迷宫数据,打印出迷宫,并打印出其解决方案。包含一个私有内部类MazeSquare,该类将txt数据文件中的每个字符都移到嵌套的迷宫行的ArrayList中。 LLStack.java-这是我用来执行堆栈算法并为整个LLStack解决方案添加潜在平方的堆栈类。包含Stack ADT中描述的方法,并在Maze.java中使用这些方法。

由于某种原因,我的代码可以正确打印迷宫,但不会打印出解决方案(星星)。我认为问题在于该程序认为迷宫的第一个正方形有右墙,而该文本不在我的txt数据文件中。这是我在Maze.Java中的代码:

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

/**
 * Maze.java
 */
public class Maze {
    private ArrayList<ArrayList<MazeSquare>> rowList;
    private int w, h;
    private int startRow, startCol, endRow, endCol;

    // MazeSquare is implemented as an inner class
    // to simplify the file structure a little bit.
    private class MazeSquare {
        private int r, c;
        private boolean top, bottom, left, right,
                start, end, visited;

        private MazeSquare(int r, int c,
                           boolean top, boolean bottom, boolean left, boolean right,
                           boolean start, boolean end) {
            this.r = r;
            this.c = c;
            this.top = top;
            this.bottom = bottom;
            this.left = left;
            this.right = right;
            this.start = start;
            this.end = end;
            this.visited = false;
        }

        boolean hasTopWall() {
            return top;
        }
        boolean hasBottomWall() {
            return bottom;
        }
        boolean hasLeftWall() {
            return left;
        }
        boolean hasRightWall() {
            return right;
        }
        boolean isStart() {
            return start;
        }
        boolean isEnd() {
            return end;
        }
        int getRow() {
            return r;
        }
        int getCol() {
            return c;
        }
        boolean visit() {  // changes visit instance variable to true.
            return this.visited = true;
        }
        boolean isVisited() { // checks to see if MazeSquare has been visited.
            if (this.visited == true) {
              return true;
            }
            return false;
        }
    }
    /**
     * Construct a new Maze
     */
    public Maze() {
        rowList = new ArrayList<ArrayList<MazeSquare>>();
    }

    /**
     * Load Maze in from given file
     *
     * @param fileName the name of the file containing the Maze structure
     */

     public void load(String fileName) {

         // Create a scanner for the given file
         Scanner scanner = null;
         try {
             scanner = new Scanner(new File(fileName));
         } catch (FileNotFoundException e) {
             System.err.println(e);
             System.exit(1);
         }

         // First line of file is "w h"
         String[] lineParams = scanner.nextLine().split(" ");
         w = Integer.parseInt(lineParams[0]);
         h = Integer.parseInt(lineParams[1]);

         // Second line of file is "startCol startRow"
         lineParams = scanner.nextLine().split(" ");
         startCol = Integer.parseInt(lineParams[0]);
         startRow = Integer.parseInt(lineParams[1]);

         // Third line of file is "endCol endRow"
         lineParams = scanner.nextLine().split(" ");
         endCol = Integer.parseInt(lineParams[0]);
         endRow = Integer.parseInt(lineParams[1]);

         // Read the rest of the lines (L or | or _ or -)
         String line;
         int rowNum = 0;
         boolean top, bottom, left, right;
         boolean start, end;
         while (scanner.hasNextLine()) {
             line = scanner.nextLine();
             rowList.add(new ArrayList<MazeSquare>());

             // Loop through each cell, creating MazeSquares
             for (int i = 0; i < line.length(); i++) {
                 // For top, check row above, if there is one
                 if (rowNum > 0) {
                     top = rowList.get(rowNum-1).get(i).hasBottomWall();
                 } else {
                     top = true;
                 }

                 // For right, check cell to the right, if there is one
                 if (i < line.length() - 1 ) {
                     char nextCell = line.charAt(i+1);
                     if (nextCell == 'L' || nextCell == '|') {
                         right = true;
                     } else {
                         right = false;
                     }
                 } else {
                     right = true;
                 }

                 // For left and bottom, switch on the current character
                 switch (line.charAt(i)) {
                     case 'L':
                         left = true;
                         bottom = true;
                         break;
                     case '_':
                         left = false;
                         bottom = true;
                         break;
                     case '|':
                         left = true;
                         bottom = false;
                         break;
                     case '-':
                         left = false;
                         bottom = false;
                         break;
                     default:
                         left = false;
                         bottom = false;
                 }

                 // Check to see if this is the start or end spot
                 start = startCol == i && startRow == rowNum;
                 end = endCol == i && endRow == rowNum;

                 // Add a new MazeSquare
                 rowList.get(rowNum).add(new MazeSquare(rowNum, i, top, bottom, left, right, start, end));
             }

             rowNum++;
         }
     }


    /**
     * Print the Maze to the Console
     */
    public void print() {
            ArrayList<MazeSquare> currRow;
            MazeSquare currSquare;
            LLStack<MazeSquare> solution = getSolution();

            // Print each row of text based on top and left
            for (int r = 0; r < rowList.size(); r++) {
                currRow = rowList.get(r);

                // First line of text: top wall
                for (int c = 0; c < currRow.size(); c++) {
                    System.out.print("+");
                    if (currRow.get(c).hasTopWall()) {
                        System.out.print("-----");
                    } else {
                        System.out.print("     ");
                    }
                }
                System.out.println("+");

                // Second line of text: left wall then space
                for (int c = 0; c < currRow.size(); c++) {
                    if (currRow.get(c).hasLeftWall()) {
                        System.out.print("|");
                    } else {
                        System.out.print(" ");
                    }
                    System.out.print("     ");
                }
                System.out.println("|");

                // Third line of text: left wall, then space, the nstart/end/sol, then space
                for (int c = 0; c < currRow.size(); c++) {
                    currSquare = currRow.get(c);

                    if (currSquare.hasLeftWall()) {
                        System.out.print("|");
                    } else {
                        System.out.print(" ");
                    }

                    System.out.print("  ");


                    if (currSquare.isStart() && currSquare.isEnd()) {
                        System.out.print("SF ");
                    } else if (currSquare.isStart() && !currSquare.isEnd()) {
                        System.out.print("S  ");
                    } else if (!currSquare.isStart() && currSquare.isEnd()) {
                        System.out.print("F  ");
                     } else if (solution.contains(currSquare) == true) {
                         System.out.print("*  ");
                    } else {
                        System.out.print("   ");
                    }
                }
                System.out.println("|");

                // Fourth line of text: same as second
                for (int c = 0; c < currRow.size(); c++) {
                    if (currRow.get(c).hasLeftWall()) {
                        System.out.print("|");
                    } else {
                        System.out.print(" ");
                    }
                    System.out.print("     ");
                }
                System.out.println("|");
            }

            // Print last row of text as straight wall
            for (int c = 0; c < rowList.get(0).size(); c++) {
                System.out.print("+-----");
            }
            System.out.println("+");
        }


    public LLStack<MazeSquare> getSolution() {
      ArrayList<MazeSquare> currRow;
      MazeSquare currSquare = null;
      int rowIndex = -1;
      int columnIndex = -1;
      LLStack<MazeSquare> solutionStack = new LLStack<MazeSquare>();
      MazeSquare startSquare;
      for (int r = 0; r < rowList.size(); r++) {
          currRow = rowList.get(r);
          for (int c = 0; c < currRow.size(); c++) {
              currSquare = currRow.get(c);
              boolean startCondition = currSquare.isStart();
              if (startCondition == true) {
                rowIndex = r;
                columnIndex = c;
                solutionStack.push(currSquare);
                startSquare = currSquare;
                currSquare.visit();
              }
            }
      }
      MazeSquare T = solutionStack.peek();
      while (solutionStack.size() > 0 && T.isEnd() != true) {
        currRow = rowList.get(rowIndex);
                if (currSquare.hasTopWall() == false && rowIndex != 0) {
                  MazeSquare neighborTop = getNeighbor(T, "top");
                  if (neighborTop.isVisited() == false) {
                    neighborTop.visit();
                    solutionStack.push(neighborTop);
                    rowIndex--;
                  }
                } else if (currSquare.hasBottomWall() == false && rowIndex != rowList.size()) {
                    MazeSquare neighborBottom = getNeighbor(T, "bottom");
                    if (neighborBottom.isVisited() == false) {
                      neighborBottom.visit();
                      solutionStack.push(neighborBottom);
                      rowIndex++;
                    }
                  } else if (currSquare.hasRightWall() == false && columnIndex != currRow.size()) {
                    System.out.println("no right wall");
                    MazeSquare neighborRight = getNeighbor(T, "right");
                    if (neighborRight.isVisited() == false) {
                      neighborRight.visit();
                      solutionStack.push(neighborRight);
                      columnIndex++;
                    }
                  } else if (currSquare.hasLeftWall() == false && columnIndex != 0) {
                    MazeSquare neighborLeft = getNeighbor(T, "left");
                    if (neighborLeft.isVisited() == false) {
                      neighborLeft.visit();
                      solutionStack.push(neighborLeft);
                      columnIndex--;
                    }
                  }
              solutionStack.pop();
              }
      return solutionStack;
    }

    public MazeSquare getNeighbor(MazeSquare s, String direction) {
        // takes in a given MazeSquare and direction and returns a reference
        // to the MazeSquare in that direction in the maze.
      MazeSquare newSquare = null;

      for (int r = 0; r < rowList.size(); r++) {
        ArrayList<MazeSquare> currentRow = rowList.get(r);
        int indexOfS = currentRow.indexOf(s);
        if (indexOfS == -1) { 
          r++;
        } else {
          System.out.println(r);
          if (direction == "right") {
            newSquare = currentRow.get(indexOfS + 1);
            break;
          }
          else
            if (direction == "left") {
              newSquare = currentRow.get(indexOfS - 1);
              break;
            }
            else
              if (direction == "top") {
                System.out.println(r);
                ArrayList<MazeSquare> previousRow = rowList.get(r-1);
                if (previousRow == null) {
                  break;
                } else {
                  newSquare = previousRow.get(indexOfS);
                  break;
                }
              }
              else
                if (direction == "bottom") {
                  ArrayList<MazeSquare> nextRow = rowList.get(r+1);
                  newSquare = nextRow.get(indexOfS);
                  break;
                }
        }
      }
      return newSquare;
    }
    // This main program acts as a simple unit test for the
    // load-from-file and print-to-System.out Maze capabilities.
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Maze mazeFile");
            System.exit(1);
        }

        Maze maze = new Maze();
        maze.load(args[0]);
        maze.print();
    }
  }

这是LLStack.java,我在其中实现堆栈方法以找到给定迷宫的解决方案:

import java.util.*;

/**
 * LLStack.java
 * A simple linked-list implementation of a Stack.
 */
public class LLStack<E> {
    private Node<E> top;
    private int numItems;

    /**
     * Private Node class for internal linked list
     */
    private static class Node<E> {
    private E data;
    private Node<E> next;

    private Node(E item) {
        data = item;
        next = null;
    }

    private Node(E item, Node nextNode) {
        data = item;
        next = nextNode;
    }
    }

    /**
     * Construct an empty LLStack
     */
    public LLStack() {
    top = null;
    numItems = 0;
    }

    /**
     * Push an item to the top of the LLStack
     *
     * @param item the item to be pushed
     */
    public void push(E item) {
    if (numItems == 0) {
        top = new Node(item);
        } else {
        top = new Node(item, top);
    }

    numItems++;
    }

    /**
     * Return the item at the top of the LLStack
     *
     * @return the top item
     * @throws EmptyStackException if the stack is empty
     */
    public E peek() {
    if (numItems == 0) {
        throw new EmptyStackException();
    }

    return top.data;
    }

    /**
     * Return and remove the item at the top of the LLStack
     *
     * @return the top item (or null if there isn't one)
     * @throws EmptyStackException if the stack is empty
     */
    public E pop() {
    if (numItems == 0) {
        throw new EmptyStackException();
    }

    E temp = top.data;
    top = top.next;
    numItems--;
    return temp;
    }

    /**
     * Return the number of items in the LLStack
     *
     * @return the number of items contained in the LLStack
     */
    public int size() {
    return numItems;
    }

        /**
         * Return whether or not the LLStack is empty
         *
         * @return true if LLStack is empty, false otherwise
         */
        public boolean isEmpty() {
        return numItems == 0;
        }

        /**
         * Get a String representation of LLStack
         * with the top at the left-most spot
         *
         * @return String representation of LLStack
         */
        public String toString() {
        StringJoiner sj = new StringJoiner(", ", "[ ", " ]");
        Node<E> currNode = top;
        for (int i = 0; i < numItems; i++) {
            sj.add(currNode.data.toString());
            currNode = currNode.next;
        }
        return sj.toString();
        }

        /**
         * Check to see whether a given item is contained in the LLStack
         *
         * @param item the item to look for in the LLStack
         * @return true if item is in the LLStack, false otherwise
         */
        public boolean contains(E item) {
        // Traverse list, looking for item
        Node temp = top;
        while (temp != null) {
            if (temp.data.equals(item)) {
            return true;
            }
            temp = temp.next;
        }

        // If we get here without returning, we didn't find it
        return false;
        }

        // Tester code: Remember, this main method won't run
        // unless LLStack is run with the command java LLStack
        public static void main(String[] args) {
        LLStack<String> fab = new LLStack<String>();
        fab.push("John");
        System.out.println(fab);
        fab.push("Ringo");
        fab.push("George");
        fab.push("Paul");
        System.out.println(fab);
        System.out.format("Peek: %s\n", fab.peek());
        System.out.format("Pop:  %s\n", fab.pop());
        System.out.println(fab);
        if (fab.contains("Paul")) {
            System.out.println("Found Paul!");
        }
        if (fab.contains("John")) {
            System.out.println("Found John!");
        }
        }
    }

这是我的数据文件的样子:

6 5
0 0
0 4
L-_|_-
|L--|_
|-_-|_
|L|L||
L__L__

L应该是具有左壁和底壁的MazeSquare,-应该是没有左和底壁的MazeSquare,_应该是具有底壁而不是左壁的MazeSquare ,和|应该是具有左墙而不是底墙的MazeSquare。这就是在Maze.java的load方法中如何处理信息。数据的第一行是列数,行数。数据的第二行是起始正方形的从0开始的坐标(在此打印“ S”,也首先将其压入堆栈,以及问题所在)。数据的第三行是完成正方形的从0开始的坐标。 迷宫应该在控制台中输出如下内容:

+-----+-----+-----+-----+-----+-----+
|                 |                 |
|  S     *        |                 |
|                 |                 |
+-----+     +-----+     +-----+     +
|     |                 |           |
|     |  *     *     *  |           |
|     |                 |           |
+     +-----+     +     +     +-----+
|                       |           |
|  *     *     *     *  |           |
|                       |           |
+     +     +-----+     +     +-----+
|     |     |     |     |     |     |
|  *  |     |     |     |     |     |
|     |     |     |     |     |     |
+     +-----+     +-----+     +     +
|                 |                 |
|  F              |                 |
|                 |                 |
+-----+-----+-----+-----+-----+-----+

...除了我的也没有印刷任何星星(我想是因为这个第一平方有右墙的问题​​)。我为此花了几个小时,无济于事。任何帮助表示赞赏。

0 个答案:

没有答案