Hallo zusammen,
ich versuche seit ein paar Wochen für mich mit dem A* Algorithmus auseinander zu setzten. Leide tritt bei mir nun ein Fehler auf, welchen ich nicht erklären kann. Ich bitte um eure Hilfe. Hier ist der Code von dem Panel wo der Algorithmus läuft.
Hier ist noch die dazu gehörende Node Klasse:
Folgender Fehler wird dann nach einigem Drücken der Enter Taste, welche die Methode search() Triggert ausgegeben.
ich versuche seit ein paar Wochen für mich mit dem A* Algorithmus auseinander zu setzten. Leide tritt bei mir nun ein Fehler auf, welchen ich nicht erklären kann. Ich bitte um eure Hilfe. Hier ist der Code von dem Panel wo der Algorithmus läuft.
Java:
package net.tim;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class DemoPanel extends JPanel {
//screen Settings
final int maxCol = 15;
final int maxRow = 10;
final int NodeSize = 75;
final int screenWidth = maxCol * NodeSize;
final int screenHeight = maxRow * NodeSize;
//nodes
Node[][] node = new Node[maxRow][maxCol];
Node startNode, goalNode, currentNode;
List<Node> openList = new ArrayList<>();
List<Node> checkedList = new ArrayList<>();
//other
boolean goalReached = false;
public DemoPanel() {
setPreferredSize(new Dimension(screenWidth, screenHeight));
setBackground(Color.BLACK);
setLayout(new GridLayout(maxRow, maxCol));
addKeyListener(new KeyHandler(this));
setFocusable(true);
//create nodes
int col = 0;
int row = 0;
while (col < maxCol && row < maxRow) {
node[row][col] = new Node(col, row);
this.add(node[row][col]);
col++;
if (col == maxCol) {
col = 0;
row++;
}
}
//set start and goal nodes
setStartNode(3, 6);
setGoalNode(11, 3);
//set solid nodes
setSolidNode(10,2);
setSolidNode(10,3);
setSolidNode(10,4);
setSolidNode(10,5);
setSolidNode(10,6);
setSolidNode(10,7);
setSolidNode(6,2);
setSolidNode(7,2);
setSolidNode(8,2);
setSolidNode(9,2);
setSolidNode(11,7);
setSolidNode(12,7);
setSolidNode(6,1);
//set costs on nodes
setCostOnNodes();
}
public void search(){
if (goalReached == false) {
int col = currentNode.col;
int row = currentNode.row;
currentNode.setAsChecked();
checkedList.add(currentNode);
openList.remove(currentNode);
//open the node above
if (row -1 >= 0) {
openNode(node[col][row - 1]);
}
//open the left node
if (col -1 >= 0) {
openNode(node[col - 1][row]);
}
//open the node below
if (row + 1 < maxRow) {
openNode(node[col][row + 1]);
}
//open the right node
if (col + 1 < maxCol) {
System.out.println("col: " + col + " row: " + row);
openNode(node[col + 1][row]);
}
int bestNodeIndex = 0;
int bestNodeFCost = 999;
for (int i = 0; i < openList.size(); i++) {
if (openList.get(i).fCost < bestNodeFCost) {
bestNodeFCost = openList.get(i).fCost;
bestNodeIndex = i;
} else if (openList.get(i).fCost == bestNodeFCost) {
if (openList.get(i).gCost < openList.get(bestNodeIndex).gCost) {
bestNodeIndex = i;
}
}
}
currentNode = openList.get(bestNodeIndex);
if (currentNode == goalNode) {
goalReached = true;
}
}
}
private void setStartNode(int col, int row) {
node[row][col].setAsStart();
startNode = node[row][col];
currentNode = startNode;
}
private void setGoalNode(int col, int row) {
node[row][col].setAsGoal();
goalNode = node[row][col];
}
private void setSolidNode(int col, int row) {
node[row][col].setAsSolid();
}
private void setCostOnNodes() {
int col = 0;
int row = 0;
while (col < maxCol && row < maxRow) {
getCost(node[row][col]);
col++;
if (col == maxCol) {
col = 0;
row++;
}
}
}
private void getCost(Node node){
//gCost
int xDistance = Math.abs(node.col - startNode.col);
int yDistance = Math.abs(node.row - startNode.row);
node.gCost = xDistance + yDistance;
//hCost
xDistance = Math.abs(node.col - goalNode.col);
yDistance = Math.abs(node.row - goalNode.row);
node.hCost = xDistance + yDistance;
//fCost
node.fCost = node.gCost + node.hCost;
//display costs
if (node != startNode && node != goalNode) {
node.setText("<html>F: " + node.fCost + "<br>G: " + node.gCost + "</html>");
}
}
private void openNode(Node node) {
if (!node.open && !node.checked && !node.solid) {
node.setAsOpen();
node.parent = currentNode;
openList.add(node);
}
}
}
Hier ist noch die dazu gehörende Node Klasse:
Code:
package net.tim;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class DemoPanel extends JPanel {
//screen Settings
final int maxCol = 15;
final int maxRow = 10;
final int NodeSize = 75;
final int screenWidth = maxCol * NodeSize;
final int screenHeight = maxRow * NodeSize;
//nodes
Node[][] node = new Node[maxRow][maxCol];
Node startNode, goalNode, currentNode;
List<Node> openList = new ArrayList<>();
List<Node> checkedList = new ArrayList<>();
//other
boolean goalReached = false;
public DemoPanel() {
setPreferredSize(new Dimension(screenWidth, screenHeight));
setBackground(Color.BLACK);
setLayout(new GridLayout(maxRow, maxCol));
addKeyListener(new KeyHandler(this));
setFocusable(true);
//create nodes
int col = 0;
int row = 0;
while (col < maxCol && row < maxRow) {
node[row][col] = new Node(col, row);
this.add(node[row][col]);
col++;
if (col == maxCol) {
col = 0;
row++;
}
}
//set start and goal nodes
setStartNode(3, 6);
setGoalNode(11, 3);
//set solid nodes
setSolidNode(10,2);
setSolidNode(10,3);
setSolidNode(10,4);
setSolidNode(10,5);
setSolidNode(10,6);
setSolidNode(10,7);
setSolidNode(6,2);
setSolidNode(7,2);
setSolidNode(8,2);
setSolidNode(9,2);
setSolidNode(11,7);
setSolidNode(12,7);
setSolidNode(6,1);
//set costs on nodes
setCostOnNodes();
}
public void search(){
if (goalReached == false) {
int col = currentNode.col;
int row = currentNode.row;
currentNode.setAsChecked();
checkedList.add(currentNode);
openList.remove(currentNode);
//open the node above
if (row -1 >= 0) {
openNode(node[col][row - 1]);
}
//open the left node
if (col -1 >= 0) {
openNode(node[col - 1][row]);
}
//open the node below
if (row + 1 < maxRow) {
openNode(node[col][row + 1]);
}
//open the right node
if (col + 1 < maxCol) {
System.out.println("col: " + col + " row: " + row);
openNode(node[col + 1][row]);
}
int bestNodeIndex = 0;
int bestNodeFCost = 999;
for (int i = 0; i < openList.size(); i++) {
if (openList.get(i).fCost < bestNodeFCost) {
bestNodeFCost = openList.get(i).fCost;
bestNodeIndex = i;
} else if (openList.get(i).fCost == bestNodeFCost) {
if (openList.get(i).gCost < openList.get(bestNodeIndex).gCost) {
bestNodeIndex = i;
}
}
}
currentNode = openList.get(bestNodeIndex);
if (currentNode == goalNode) {
goalReached = true;
}
}
}
private void setStartNode(int col, int row) {
node[row][col].setAsStart();
startNode = node[row][col];
currentNode = startNode;
}
private void setGoalNode(int col, int row) {
node[row][col].setAsGoal();
goalNode = node[row][col];
}
private void setSolidNode(int col, int row) {
node[row][col].setAsSolid();
}
private void setCostOnNodes() {
int col = 0;
int row = 0;
while (col < maxCol && row < maxRow) {
getCost(node[row][col]);
col++;
if (col == maxCol) {
col = 0;
row++;
}
}
}
private void getCost(Node node){
//gCost
int xDistance = Math.abs(node.col - startNode.col);
int yDistance = Math.abs(node.row - startNode.row);
node.gCost = xDistance + yDistance;
//hCost
xDistance = Math.abs(node.col - goalNode.col);
yDistance = Math.abs(node.row - goalNode.row);
node.hCost = xDistance + yDistance;
//fCost
node.fCost = node.gCost + node.hCost;
//display costs
if (node != startNode && node != goalNode) {
node.setText("<html>F: " + node.fCost + "<br>G: " + node.gCost + "</html>");
}
}
private void openNode(Node node) {
if (!node.open && !node.checked && !node.solid) {
node.setAsOpen();
node.parent = currentNode;
openList.add(node);
}
}
}
Folgender Fehler wird dann nach einigem Drücken der Enter Taste, welche die Methode search() Triggert ausgegeben.
Code:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
at net.tim.DemoPanel.search(DemoPanel.java:102)
at net.tim.KeyHandler.keyPressed(KeyHandler.java:24)
at java.desktop/java.awt.Component.processKeyEvent(Component.java:6579)
at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2905)
at java.desktop/java.awt.Component.processEvent(Component.java:6398)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1146)
at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4877)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)