我已经在这里工作了2个小时而且在我的生活中不能找出为什么这个方法会返回一个无限循环。我知道这种实施在效率方面并不是最好的,对此的任何建议都很好:)
Driver.java
import java.util.Scanner;
public class Driver {
static Board b;
public static void main(String[] args){
while(init()){
init();
}
System.out.println("Thanks for testing out the A* program");
}
private static boolean init(){
System.out.println("Would you like to play? (\"y\",\"n\")");
Scanner s = new Scanner(System.in);
String input = s.nextLine();
if(!input.equals("y")){
return false;
}
b = new Board(3,3);
System.out.print(b.toString());
while(getStartValue() == false){
getStartValue();
}
while(getDestinationValue() == false){
getDestinationValue();
}
System.out.print(b.toString());
b.setHValueAllNodes();
b.createPath(b.getStartPosition());
System.out.print(b.toString());
return true;
}
private static boolean getStartValue() {
Scanner s = new Scanner(System.in);
System.out.println("Please enter a starting X position");
int startX = s.nextInt();
System.out.println("Please enter a starting Y position");
int startY = s.nextInt();
if(b.getBoard()[startX][startY].getStatus() == 'X'){
System.out.println("Please enter a position that is not an obstacle");
return false;
}
else{
b.getBoard()[startX][startY].setStatus('S');
b.setStartPosition(startX, startY);
return true;
}
}
private static boolean getDestinationValue() {
Scanner s = new Scanner(System.in);
System.out.println("Please enter an ending X position");
int endX = s.nextInt();
System.out.println("Please enter a ending Y position");
int endY = s.nextInt();
if(b.getBoard()[endX][endY].getStatus() == 'X'){
System.out.println("Please enter a position that is not an obstacle");
return false;
}
else if(b.getBoard()[endX][endY].getStatus() == 'S'){
System.out.println("Please enter a postition that is not the starting value");
return false;
}
else{
b.getBoard()[endX][endY].setStatus('E');
b.setEndPosition(endX, endY);
return true;
}
}
}
Node.java
public class Node {
private int x;
private int y;
//Controls if transversable
private char status;
//f = g+h
private int f;
private int g;
private int h;
private Node parent;
Node(char status, int x, int y){
this.status = status;
this.x = x;
this.y = y;
this.g=0;
this.h=0;
this.f=0;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public char getStatus() {
return status;
}
public void setStatus(char status) {
this.status = status;
}
public int getF() {
return f;
}
public void setF(int f) {
this.f = f;
}
public int getG() {
return g;
}
public void setG(int g) {
this.g = g;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
@Override
public String toString() {
if(this.getStatus() == 'O'){
return "O (" + this.getX() + ", " + this.getY() + ", " + this.getH() + ", " + this.getG() + ", " +this.getF() + ")";
}
else if(this.getStatus() == 'S'){
return "S (" + this.getX() + ", " + this.getY() + ")";
}
else if(this.getStatus() == 'E'){
return "E (" + this.getX() + ", " + this.getY() + ")";
}
else{
return "X (" + this.getX() + ", " + this.getY() + ")";
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if( !(obj instanceof Node)) return false;
Node nodeObj = (Node) obj;
return (nodeObj.getX() == this.getX() && nodeObj.getY() == this.getY());
}
}
Board.java
import java.util.ArrayList;
import java.util.Random;
public class Board {
private int length;
private int width;
private Node[][] board;
private ArrayList<Node> openList = new ArrayList<>();
private ArrayList<Node> closedList = new ArrayList<>();
private Node startPosition;
private Node endPosition;
public Node[][] getBoard() {
return board;
}
public void setBoard(Node[][] board) {
this.board = board;
}
Board(int length, int width){
board = new Node[length][width];
Random rand = new Random();
for(int row=0; row < board.length; row++){
for(int col=0; col < board[row].length; col++){
int randomNum = rand.nextInt(10);
if(randomNum == 0){
board[row][col] = new Node('X',row,col);
}
else{
board[row][col] = new Node('O',row,col);
}
}
}
}
public Node getStartPosition() {
return this.startPosition;
}
public void setStartPosition(int x, int y) {
board[x][y].setStatus('S');
board[x][y].setParent(null);
startPosition = new Node('S', x, y);
}
public Node getEndPosition() {
return endPosition;
}
public void setEndPosition(int x, int y) {
board[x][y].setStatus('E');
endPosition = new Node('E', x, y);
}
public void setHValueAllNodes(){
for(int row=0; row < board.length; row++){
for(int col=0; col < board[row].length; col++){
int xDistance = Math.abs(endPosition.getX() - board[row][col].getX());
int yDistance = Math.abs(endPosition.getY() - board[row][col].getY());
board[row][col].setH(xDistance + yDistance);
}
}
}
public void createPath(Node n){
Node minimum;
System.out.println("RUNNING WITH NODE " + n.getX() + n.getY());
//1. Add the starting square to open list
if(n.getStatus() == 'S'){
openList.add(n);
}
//d1. Stop when the open list is empty
if(openList.isEmpty() ){
return;
}
//d4. Add the target square to the closed list
if(n.equals(endPosition)){
return;
}
//2a. Find lowest F score in our list
int index = 0;
int indexMin = 0;
minimum = openList.get(0);
for(Node node: openList){
if(node.getF() < minimum.getF()){
minimum = node;
indexMin = index;
}
index++;
}
//2b. Switch minimum node to closed list
//Remove node from openlist
openList.remove(indexMin);
//Add to close list
closedList.add(minimum);
//c. For each of the 8 squares adjacent to this square
addToOpenList(minimum);
createPath(minimum);
System.out.println("OUR OPEN LIST CONTAINS: ");
for(Node n1 : openList){
System.out.print("X: " + n1.getX() + "Y: " + n1.getY());
}
System.out.println("OUR CLOSED LIST CONTAINS: ");
for(Node n2 : closedList){
System.out.print("X: " + n2.getX() + "Y: " + n2.getY());
}
System.out.println();
}
private void addToOpenList(Node n) {
boolean inClosedList = false;
boolean inOpenList = false;
for(int i= -1; i < 2; i++){
for(int j = -1; j < 2; j++){
inClosedList = false;
inOpenList = false;
//c1. If it is not walkable or it is in closed list ignore it
int xPos = n.getX() + i;
int yPos = n.getY() + j;
if(xPos == -1 || yPos == -1){
System.out.println("OUR NODE IS OUT OF BOUNDS: " + "X: " + xPos + "Y: " + yPos);
}
else{
for(Node node : closedList){
if(node.equals(board[xPos][yPos])){
inClosedList = true;
System.out.println("OUR NODE IS IN THE CLOSED LIST: " + "X: " + xPos + "Y: " + yPos);
}
}
if(inClosedList == false){
//c2. If it isnt on the open list, add it to the open list. Make the current square the parent of this square. Record F, G, H of the square
System.out.println("OUR NODE IS NOTTTTTTTT IN THE CLOSED LIST: " + "X: " + xPos + "Y: " + yPos);
int gCounter = (i + j == 1)? 10 : 14;
int g = n.getG() + gCounter;
int f = g + board[xPos][yPos].getH();
for(Node node1 : openList){
System.out.println("OUR NODE IN FOR LOOP: " + "X: " + xPos + "Y: " + yPos);
if(node1.equals(board[xPos][yPos])){
System.out.println("OUR NODE IS IN THE OPEN LIST: " + "X: " + xPos + "Y: " + yPos);
inOpenList = true;
//c3.If it is in the open list already, check to see if this path to the square is better, using g cost as the measure
if(g < board[xPos][yPos].getG()){
board[xPos][yPos].setG(g);
board[xPos][yPos].setF(f);
board[xPos][yPos].setParent(n);
}
}
}
if(inOpenList == false){
System.out.println("WE ARE HERE WITH" + "X: " + xPos + "Y: " + yPos);
board[xPos][yPos].setG(g);
board[xPos][yPos].setF(f);
board[xPos][yPos].setParent(n);
openList.add(board[xPos][yPos]);
}
}
}
}
}
}
@Override
public String toString() {
String output = "";
for(int row=0; row < board.length; row++){
for(int col=0; col < board[row].length; col++){
output += board[row][col].toString() + "\t";
}
output += "\n";
}
return output;
}
}
答案 0 :(得分:1)
乍一看有两个错误,我不知道我的建议是否在语义上是正确的,但我不会深入研究这个问题。
看看: https://stackoverflow.com/help/how-to-ask
并尝试再次提出这个问题,以获得进一步的帮助并恢复投票。
错误:
错误:
while(init()){
init();
}
右:
while(init());
错误:
while(getStartValue() == false){
getStartValue();
}
while(getDestinationValue() == false){
getDestinationValue();
}
右:
while(!getStartValue());
while(!getDestinationValue());
答案 1 :(得分:0)
问题实际上在我的createPath类中......
我递归调用createPath而不是执行while循环检查打开的列表是否为空。