Stackoverflow Error when working with larger numbers - java
I'm trying to write the a* path finding algorithm using recursion and am having trouble. The code finds the path to smaller distances but when I try to use it with larger numbers, I get a stack overflow error. I am new to recursion so there is definitely something I am doing wrong but I can't figure it out. I have an exit condition and it works fine on smaller numbers so I don't know what to do unless I have a problem with the algorithm itself. The problem occurs in the findAlgorithm() method where the recursion is being done.
Algorithm:
Node[][]nodes;
ArrayList<Node> options = new ArrayList<Node>();
ArrayList<Node> path = new ArrayList<Node>();
private int x, y, endX, endY;
Node endNode;
public Algorithm(Node[][]nodes) {
this.nodes = nodes;
setStartPosition();
findEndPosition();
}
public ArrayList<Node> getPath() {
Node node = endNode;
while(node.hasParent()) {
path.add(node);
node = node.getParent();
}
return path;
}
public void findPath() {
if(x!=endX || y!=endY) {
getSurroundingNodes();
if(options.size()>0) {
Node lowestVal = options.get(0);
for(Node i : options) {
if(i.getValue()<lowestVal.getValue()) {
lowestVal = i;
}
else if(i.getValue() == lowestVal.getValue()) {
if(i.getEndDistance()<lowestVal.getEndDistance()) {
lowestVal = i;
}
}
}
x = lowestVal.getX();
y = lowestVal.getY();
lowestVal.setTaken();
options.remove(lowestVal);
findPath();
}
}
else {
System.out.println("Made it");
}
}
private void getSurroundingNodes() {
Node parent = nodes[y][x];
for(int i=y-1;i<y+2; i++) {
for(int z=x-1;z<x+2; z++) {
if(i>=0&&z>=0&&i<nodes.length&&z<nodes[i].length) {
Node node = nodes[i][z];
double endDistance = Math.sqrt((i-endY)*(i-endY)+(z-endX)*(z-endX));
double startDistance = parent.getStartDistance()+Math.sqrt((i-y)*(i-y)+(z-x)*(z-x));
double value = endDistance+startDistance;
if(!node.isWall()&&!node.isTaken()) {
if(!options.contains(node)) {
node.setParent(parent);
node.setX(z);
node.setY(i);
node.setStartDistance(startDistance);
node.setEndDistance(endDistance);
node.setValue(value);
options.add(node);
}
else {
if(node.getValue()<value) {
//do nothing
}
else if (node.getValue() == value) {
if(node.getEndDistance()<=endDistance) {
//do nothing
}
else {
node.setParent(parent);
node.setX(z);
node.setY(i);
node.setStartDistance(startDistance);
node.setEndDistance(endDistance);
node.setValue(value);
options.add(node);
}
}
else {
node.setParent(parent);
node.setX(z);
node.setY(i);
node.setStartDistance(startDistance);
node.setEndDistance(endDistance);
node.setValue(value);
options.add(node);
}
}
}
}
}
}
}
private boolean findEndPosition() {
for(Node[] i : nodes) {
for(Node z : i) {
if(z.isEnd()) {
endX = z.getX();
endY = z.getY();
endNode = z;
return true;
}
}
}
return false;
}
private boolean setStartPosition() {
for(Node[] i : nodes) {
for(Node z : i) {
if(z.isStart()) {
z.setTaken();
x = z.getX();
y = z.getY();
return true;
}
}
}
return false;
}
Node:
private int x, y;
private boolean wall, start, end, taken, hasAParent;
private double endDistance, startDistance, value;
private Node parent = null;
public Node() {
wall=false;
start=false;
end=false;
taken=false;
hasAParent = false;
}
public boolean hasParent() {
return hasAParent;
}
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 boolean isWall() {
return wall;
}
public void setWall() {
wall = true;
end = false;
start = false;
}
public boolean isStart() {
return start;
}
public void setStart(int x, int y) {
this.x = x;
this.y = y;
start = true;
end = false;
wall = false;
endDistance=0.0;
startDistance=0.0;
value=0.0;
}
public boolean isEnd() {
return end;
}
public void setEnd(int x, int y) {
this.x = x;
this.y = y;
end = true;
start = false;
wall = false;
hasAParent = true;
}
public boolean isTaken() {
return taken;
}
public void setTaken() {
taken = true;
}
public double getEndDistance() {
return endDistance;
}
public void setEndDistance(double endDistance) {
this.endDistance = endDistance;
}
public double getStartDistance() {
return startDistance;
}
public void setStartDistance(double startDistance) {
this.startDistance = startDistance;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
hasAParent = true;
}
Related
Javafx how to put shape above another shapes
Trying to write a snake game. I want to mark place where the snake bites itself in red ,but the snake body overlaping it. I tried to put the shape from the head over the body with getHead().shape.toFront() command, but it didn't work. Possibly because the snake is added to paneGame.getChildren() as a list and toFront doesn't allow changing the order in which the elements list are drawn. I solved this problem change color overlaping body part. Can somebody advise more simply solution? public class Draw extends Application { Pane paneGame; static Snake snake; static final public int xLField = 50; static final public int yLField = 53; static final public int yLFieldGame = 50; static public int sizeCell = 10; int speed = 100; #Override public void start(Stage stage) { BorderPane borderPane = new BorderPane(); paneGame = new Pane(); borderPane.setCenter(paneGame); Scene scene = new Scene(borderPane, xLField * sizeCell, yLField * sizeCell, Color.GRAY); setOnKey(scene); snake = Snake.generatedSnake(); Timeline timeline = new Timeline( new KeyFrame(Duration.millis(speed), event -> gameProcessing())); timeline.setCycleCount(Timeline.INDEFINITE); timeline.play(); stage.setTitle("Snake"); stage.setScene(scene); stage.show(); } void gameProcessing() { paneGame.getChildren().clear(); snake.move(); if (snake.getHead().hasIntersection(snake.getBody())) { snake.snakeDead(); } paneGame.getChildren().addAll(snake.getBodyShapes()); } public static void main(String[] args) { launch(args); } void setOnKey(Scene scene) { scene.setOnKeyPressed(key -> { if (key.getCode() == KeyCode.UP) snake.setDirection(Direction.UP); if (key.getCode() == KeyCode.DOWN) snake.setDirection(Direction.DOWN); if (key.getCode() == KeyCode.LEFT) snake.setDirection(Direction.LEFT); if (key.getCode() == KeyCode.RIGHT) snake.setDirection(Direction.RIGHT); }); } } enum Direction { UP, DOWN, LEFT, RIGHT } public class Snake { private final ArrayList<Body> body; private Body head; public ArrayList<Shape> getBodyShapes() { ArrayList<Shape> shapeListFromBody = new ArrayList<>(); for (Body body : this.body) { shapeListFromBody.add(body.getShape()); } return shapeListFromBody; } public ArrayList<Body> getBody(){return body;} Body getHead() { return head; } public void move() { int x = head.getX(); int y = head.getY(); switch (direction) { case UP -> y -= 1; case DOWN -> y += 1; case LEFT -> x -= 1; case RIGHT -> x += 1; } body.add(0, new Body(x, y)); Cell.cellPool.remove((body.get(body.size() - 1).cellId)); body.remove(body.size() - 1); head = body.get(0); } public Snake() { direction = Direction.RIGHT; this.body = new ArrayList<>(); for (int i = 0; i < 10; i++) { body.add(new Body(Draw.xLField/2 - i, Draw.yLFieldGame/2)); } head = this.body.get(0); } private Direction direction; public static Snake generatedSnake(){ return new Snake(); } public void snakeDead(){ getHead().shape.setFill(RED); getHead().shape.toFront(); /*for(Body body: body){ if(getHead().hasIntersection(body)) { body.shape.setFill(RED); } }*/ } public void setDirection(Direction direction) { this.direction = direction; } static class Body extends Cell { private final Shape shape; public Body(int x, int y) { super(x, y); shape = new Rectangle(getPixelsX(), getPixelsY(), size, size); shape.setFill(GREEN); } public Shape getShape() { return shape; } } } public class Cell { int x; int y; String cellId; final int size = Draw.sizeCell; public static HashSet<String> cellPool = new HashSet<>(); public int getPixelsX() { return x * size; } public int getPixelsY() { return y * size; } public Cell(int x, int y) { this.x = x; this.y = y; this.cellId = x + "_" + y; Cell.cellPool.add(this.cellId); } public int getX() { return x; } public int getY() { return y; } public boolean hasIntersection(Cell otherCell) { return otherCell != this && this.cellId.equals(otherCell.cellId); } public boolean hasIntersection(List<? extends Cell> cells) { for (Cell otherCell : cells) { if (this.hasIntersection(otherCell)) { return true; } } return false; } } public class Cell { int x; int y; String cellId; final int size = Draw.sizeCell; public static HashSet<String> cellPool = new HashSet<>(); public int getPixelsX() { return x * size; } public int getPixelsY() { return y * size; } public Cell(int x, int y) { this.x = x; this.y = y; this.cellId = x + "_" + y; Cell.cellPool.add(this.cellId); } public int getX() { return x; } public int getY() { return y; } public boolean hasIntersection(Cell otherCell) { return otherCell != this && this.cellId.equals(otherCell.cellId); } public boolean hasIntersection(List<? extends Cell> cells) { for (Cell otherCell : cells) { if (this.hasIntersection(otherCell)) { return true; } } return false; } }
I solved the problem using setViewOrder with -1 parameter (before I used a positive value)
Error in implementing a Red black Tree using a sentinel object, in Java
So, I am trying to implement insertion for a red black tree, using sentinels as described in the "Introduction to Algorithms". I've created a Generic class for a red black node, which has type parameter as its data attribute and the other attributes: parent(node type), leftchild(node type), rightchild(node type) and a color(enum type having red and black values). Red-Back Node Class:- public class RedBlackTreeNode<T extends Comparable<T>> { enum color{ RED, BLACK } private T data; private color color; private RedBlackTreeNode<T> leftChild; private RedBlackTreeNode<T> rightChild; private RedBlackTreeNode<T> parent; public RedBlackTreeNode(T data) { this.data = data; leftChild = null; rightChild = null; parent = null; color = null; } public T getData() { return data; } public void setData(T data) { this.data = data; } public color getColor() { return color; } public void setColor(color color) { this.color = color; } public RedBlackTreeNode<T> getLeftChild() { return leftChild; } public void setLeftChild(RedBlackTreeNode<T> leftChild) { this.leftChild = leftChild; } public RedBlackTreeNode<T> getRightChild() { return rightChild; } public void setRightChild(RedBlackTreeNode<T> rightChild) { this.rightChild = rightChild; } public RedBlackTreeNode<T> getParent() { return parent; } public void setParent(RedBlackTreeNode<T> parent) { this.parent = parent; } } Red Black Tree Class: import redBlackTree.RedBlackTreeNode.color; public class RedBlackTree<T extends Comparable<T>> { private RedBlackTreeNode<T> sentinel ; private RedBlackTreeNode<T> root; public RedBlackTree() { sentinel = new RedBlackTreeNode<>(null); sentinel.setColor(color.BLACK); root = null; } public void redBlackInsert(RedBlackTreeNode<T> z) { RedBlackTreeNode<T> y, x; int temp; y = sentinel; x = this.root; //Getting NullPointerException in the below while loop condition while ((x.getData()) != null) { y = x; temp = z.getData().compareTo(x.getData()); if (temp < 0) { x = x.getLeftChild(); } else { x = x.getRightChild(); System.out.println("Right child of X: " + x); System.out.println("Sentinel: " + x); } } z.setParent(y); if (y.getData() != null) { temp = z.getData().compareTo(y.getData()); if (temp < 0) { y.setLeftChild(z); } else { y.setRightChild(z); } } else { root = z; } z.setLeftChild(sentinel); z.setRightChild(sentinel); z.setColor(color.RED); redBlackInsertFix(z); System.out.println("First node inserted"); } private void redBlackInsertFix(RedBlackTreeNode<T> z) { while (z.getParent().getColor() == color.RED) { if (z.getParent() == z.getParent().getParent().getLeftChild()) { RedBlackTreeNode<T> y; y = z.getParent().getParent().getRightChild(); if (y.getColor() == color.RED) { z.getParent().setColor(color.BLACK); y.setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); z = z.getParent().getParent(); } else if (z == z.getParent().getRightChild()) { z = z.getParent(); leftRotate(z); } z.getParent().setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); rightRotate(z.getParent().getParent()); } else { RedBlackTreeNode<T> y; y = z.getParent().getParent().getLeftChild(); if (y.getColor() == color.RED) { z.getParent().setColor(color.BLACK); y.setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); z = z.getParent().getParent(); } else if (z == z.getParent().getLeftChild()) { z = z.getParent(); rightRotate(z); } z.getParent().setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); leftRotate(z.getParent().getParent()); } } root.setColor(color.BLACK); } private void rightRotate(RedBlackTreeNode<T> y) { RedBlackTreeNode<T> x; x = y.getLeftChild(); y.setLeftChild(x.getRightChild()); if (x.getRightChild() != sentinel) { x.getRightChild().setParent(y); } x.setParent(y.getParent()); if (y.getParent() == sentinel) { root = x; } else if (y == y.getParent().getLeftChild()) { y.getParent().setLeftChild(x); } else { y.getParent().setRightChild(x); } x.setRightChild(y); y.setParent(x); } private void leftRotate(RedBlackTreeNode<T> x) { RedBlackTreeNode<T> y; y = x.getRightChild(); x.setRightChild(y.getLeftChild()); if (y.getLeftChild() != sentinel) { y.getLeftChild().setParent(x); } y.setParent(x.getParent()); if (x.getParent() == sentinel) { root = y; } else if (x == x.getParent().getLeftChild()) { x.getParent().setLeftChild(y); } else { x.getParent().setRightChild(y); } y.setLeftChild(x); x.setParent(y); } public void inOrderTraversal(RedBlackTreeNode<T> x) { if (x.getData() != sentinel.getData()) { inOrderTraversal(x.getLeftChild()); System.out.println(x.getData()); inOrderTraversal(x.getRightChild()); } } public RedBlackTreeNode<T> getRoot() { return root; } } And here is the class having the main method: public class RedBlackTreeDriver { public static void main(String[] args) { RedBlackTreeNode<Integer> one = new RedBlackTreeNode<>(50); RedBlackTreeNode<Integer> two = new RedBlackTreeNode<>(55); RedBlackTreeNode<Integer> three = new RedBlackTreeNode<>(48); RedBlackTree<Integer> rbt = new RedBlackTree<>(); //System.out.println(rbt.getRoot()); //NullPointerException rbt.redBlackInsert(one); System.out.println("ROOT: "+ rbt.getRoot()); rbt.redBlackInsert(two); rbt.redBlackInsert(three); System.out.println(rbt.getRoot()); rbt.inOrderTraversal(rbt.getRoot()); } } I am trying to add a sentinel node(having the data attribute set as "null") after inserting every node with value. So, after adding the first node, I should be able to go down the tree(looking for sentinel) and add the new node to the parent of the sentinel. I'm getting a null pointer exception in the Red Black Tree class. So far,I've tried almost everything I know. Can someone guide me through this?
Ok, so after thinking a bit, I got to this point where I just made sure that for the first time, when we are inserting a node, it should not check for the while loop condition. And here it is, the change in the Red Black Tree Class: package redBlackTree; import redBlackTree.RedBlackTreeNode.color; public class RedBlackTree<T extends Comparable<T>> { private RedBlackTreeNode<T> sentinel; private RedBlackTreeNode<T> root; public RedBlackTree() { sentinel = new RedBlackTreeNode<>(null); sentinel.setColor(color.BLACK); root = null; } public void redBlackInsert(RedBlackTreeNode<T> z) { RedBlackTreeNode<T> y, x; int temp; y = sentinel; x = this.root; System.out.println(x); // Getting NullPointerException in the below while loop condition if (x != null) { while (x.getData() != null) { y = x; temp = z.getData().compareTo(x.getData()); if (temp < 0) { x = x.getLeftChild(); } else { x = x.getRightChild(); System.out.println("Right child of X: " + x); System.out.println("Sentinel: " + sentinel); } } } z.setParent(y); if (y.getData() != null) { temp = z.getData().compareTo(y.getData()); if (temp < 0) { y.setLeftChild(z); } else { y.setRightChild(z); } } else { root = z; } z.setLeftChild(sentinel); z.setRightChild(sentinel); z.setColor(color.RED); redBlackInsertFix(z); System.out.println("First node inserted"); } private void redBlackInsertFix(RedBlackTreeNode<T> z) { while (z.getParent().getColor() == color.RED) { if (z.getParent() == z.getParent().getParent().getLeftChild()) { RedBlackTreeNode<T> y; y = z.getParent().getParent().getRightChild(); if (y.getColor() == color.RED) { z.getParent().setColor(color.BLACK); y.setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); z = z.getParent().getParent(); } else if (z == z.getParent().getRightChild()) { z = z.getParent(); leftRotate(z); } z.getParent().setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); rightRotate(z.getParent().getParent()); } else { RedBlackTreeNode<T> y; y = z.getParent().getParent().getLeftChild(); if (y.getColor() == color.RED) { z.getParent().setColor(color.BLACK); y.setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); z = z.getParent().getParent(); } else if (z == z.getParent().getLeftChild()) { z = z.getParent(); rightRotate(z); } z.getParent().setColor(color.BLACK); z.getParent().getParent().setColor(color.RED); leftRotate(z.getParent().getParent()); } } root.setColor(color.BLACK); } private void rightRotate(RedBlackTreeNode<T> y) { RedBlackTreeNode<T> x; x = y.getLeftChild(); y.setLeftChild(x.getRightChild()); if (x.getRightChild() != sentinel) { x.getRightChild().setParent(y); } x.setParent(y.getParent()); if (y.getParent() == sentinel) { root = x; } else if (y == y.getParent().getLeftChild()) { y.getParent().setLeftChild(x); } else { y.getParent().setRightChild(x); } x.setRightChild(y); y.setParent(x); } private void leftRotate(RedBlackTreeNode<T> x) { RedBlackTreeNode<T> y; y = x.getRightChild(); x.setRightChild(y.getLeftChild()); if (y.getLeftChild() != sentinel) { y.getLeftChild().setParent(x); } y.setParent(x.getParent()); if (x.getParent() == sentinel) { root = y; } else if (x == x.getParent().getLeftChild()) { x.getParent().setLeftChild(y); } else { x.getParent().setRightChild(y); } y.setLeftChild(x); x.setParent(y); } public void inOrderTraversal(RedBlackTreeNode<T> x) { if (x.getData() != sentinel.getData()) { inOrderTraversal(x.getLeftChild()); System.out.println(x.getData()); inOrderTraversal(x.getRightChild()); } } public RedBlackTreeNode<T> getRoot() { return root; } } I hope this was not a very naive question to ask.
How can I have access to one item's variables in another class that is not related with it?
I'm new to java and i was searching about this for a long time. How can I have access to the item's b variables in class Player??(the cod i'm posting is a part of my full programm so don't mind if you see methods or variables that are not declared in the following code) import java.util.Random; public abstract class Player { private int x, y; private String name; private int pNumber; private int mLine; private int tLine; private boolean possession; private int c; private int f = 0; private int i = 0; public int getPlx() { return x; } public void setPlx(int x) { this.x = x; } public int getPly() { return y; } public void setPly(int y) { this.y = y; } public String getPName() { return name; } public void setPName(String name) { this.name = name; } public int getPNum() { return pNumber; } public void setPNum(int pNumber) { this.pNumber = pNumber; } public int getMLine() { return mLine; } public void setMLine(int mLine) { this.mLine = mLine; } public int getLine() { return tLine; } public void setTLine(int tLine) { this.tLine = tLine; } public boolean getPos() { return possession; } public void setPos(boolean possession) { this.possession = possession; } private Random rand = new Random(); public void Move() { //me8odos metakinisis c = rand.nextInt(2); if (c == 0) { y++; } else { y--; } } public void Pass() { if (this.possession == true) { c = rand.nextInt(10); while ((f == 0) && (i < 10)) { if (main.barcelona.get(i).name == this.name) {} } } } public abstract void SpecialMove(); } public class Ball { private int x, y; private Player formerP = null; private Player currentP = null; public Ball(int x, int y, Player formerP, Player currentP) { this.x = x; this.y = y; this.formerP = formerP; this.currentP = currentP; } public int getBX() { return x; } public void setBX(int x) { this.x = x; } public int getBY() { return y; } public void setBY(int y) { this.y = y; } void Assign(Player playerP) { int px = playerP.getPlx(); if (this.currentP == null) { if (((this.x - px <= 1) || (px - this.x) <= 1) && ((this.x - px <= 1) || (px - this.x) = 1)) { this.currentP = playerP; this.formerP.possession = false; playerP.possession = true; if (this.currentP.team == this.formerP.team) { int pass = this.currentP.getPasses(); pass++; this.currentP.setPasses(pass); } else { int mistake = this.currentP.getMistakes(); mistake++; this.currentP.setMistakes(mistake); } } } this.formerP = this.currentP; this.currentP = null; this.formerP = null; } }
try BallClassName.getX(); You may have to make getX static
If you don't want to instantiate the class Ball in the Player class and you would like to ensure that all players are playing with the one and only ball, then consider making Ball a Singleton. In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. public class Ball { private static Ball singletonBall; private int x; private int y; private Player formerP; private Player currentP; public static Ball getSingletonBall() { if(singletonBall == null){ singletonBall = new Ball(); } return singletonBall; } 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 Player getFormerP() { return formerP; } public void setFormerP(Player formerP) { this.formerP = formerP; } public Player getCurrentP() { return currentP; } public void setCurrentP(Player currentP) { this.currentP = currentP; } }
If there is something that you need inside Player that you will be using often that won't change throughout the life of the Player object (or sub object in your case), then you might as well pass it to a local variable through the Player constructor. Let's assume Item B is the Ball and you have a Ball class. So in player (or sub player) declare your object you want access to: class Player { Ball ball; public Player(Ball ball) { this.ball = ball; } Or if it's just something that you'll be using infrequently or something that's value will change (more likely with a ball), then create a method to perform what you need on the Player object. class Player { . . . . . public void dribble(Ball ball) { // do something with the ball ball.setPosition(10, 20); ball.update(); } } Then whatever instantiates Player can access that method. public static void main(String[] args) { Player player = new Player(); Ball ball = new Ball(); player.dribble(ball); }
Please Help:Grid of JButtons in a JPanel shows one JButton instead of 400 when GridLayout(20,20) is used
Thank you for trying to help me. I want to create a grid of 20*20 squares.It is for my A-Star Algorithm Demo. For experiment purpose I wrote the following code: import javax.swing.*; import java.awt.event.*; import java.awt.*; class Node extends JButton { Node(){ super(); setSize(new Dimension(20,20)); } protected void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.white); g.fillRect(0,0,getHeight(),getWidth()); } } public class Map { static final int n = 20; JPanel p; public JPanel init() { p=new JPanel(); p.setLayout(new GridLayout(n, n)); p.setBackground(Color.black); p.setFont(new Font("SansSerif", Font.BOLD, 24)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { p.add(new Node()); } } return p; } } public class Display extends JApplet{ public void init(){ Map m=new Map(); add(m.init()); } }` I got the following output: Please load the code & check.I cannot post image since I lack 10 reputation However,when I am trying to add the experiment code with my original code for the demo it is not showing the desired output.My original code is as follows: import java.util.ArrayList; import javax.swing.*; import java.awt.*; public class Node extends JButton implements Comparable<Node> { /* Nodes that this is connected to */ private Node north; private Node east; private Node south; private Node west; private ArrayList<Node> neighbourList; private boolean visited; private float g; private float h; private Node parent; private int x; private int y; private boolean isObstacle; private boolean isStart; private boolean isGoal; Node(int x, int y) { super(); neighbourList = new ArrayList<Node>(); this.x = x; this.y = y; this.visited = false; this.g = Integer.MAX_VALUE; this.isObstacle = false; this.isStart = false; this.isGoal = false; } public void setNorth(Node north) { //replace the old Node with the new one in the neighbourList if (neighbourList.contains(this.north)) neighbourList.remove(this.north); neighbourList.add(north); //set the new Node this.north = north; } public void setEast(Node east) { //replace the old Node with the new one in the neighbourList if (neighbourList.contains(this.east)) neighbourList.remove(this.east); neighbourList.add(east); //set the new Node this.east = east; } public void setSouth(Node south) { //replace the old Node with the new one in the neighbourList if (neighbourList.contains(this.south)) neighbourList.remove(this.south); neighbourList.add(south); //set the new Node this.south = south; } public void setWest(Node west) { //replace the old Node with the new one in the neighbourList if (neighbourList.contains(this.west)) neighbourList.remove(this.west); neighbourList.add(west); //set the new Node this.west = west; } public ArrayList<Node> getneighbourList() { return neighbourList; } public boolean isVisited() { return visited; } public void setVisited(boolean visited) { this.visited = visited; } public float getG() { return g; } public void setG(float f) { this.g = f; } public Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public float getH() { return h; } public void setH(float h) { this.h = h; } public int getX() { return x; } public int getY() { return y; } public boolean isObstacle() { return isObstacle; } public void setObstacle(boolean isObstacle) { this.isObstacle = isObstacle; } public boolean isStart() { return isStart; } public void setStart(boolean isStart) { this.isStart = isStart; } public boolean isGoal() { return isGoal; } public void setGoal(boolean isGoal) { this.isGoal = isGoal; } public boolean equals(Node node) { return (node.x == x) && (node.y == y); } public int compareTo(Node otherNode) { float thisTotalDistanceFromGoal = h + g; float otherTotalDistanceFromGoal = otherNode.getH() + otherNode.getG(); if (thisTotalDistanceFromGoal < otherTotalDistanceFromGoal) return -1; else if (thisTotalDistanceFromGoal > otherTotalDistanceFromGoal) return 1; else return 0; } protected void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.white); g.fillRect(0,0,getHeight()-1,getWidth()-1); } } public class Map { private int mapWidth; private int mapHeight; private ArrayList<ArrayList<Node>> map; private int startLocationX = 0; private int startLocationY = 0; private int goalLocationX = 0; private int goalLocationY = 0; private int[][] obstacleMap; private JPanel p; private Logger log = new Logger(); Image buffer; Map(int mapWidth, int mapHeight, int[][] obstacleMap) { this.mapWidth = mapWidth; this.mapHeight = mapHeight; this.obstacleMap = obstacleMap; createMap(); log.addToLog("\tMap Created"); registerEdges(); log.addToLog("\tMap Node edges registered"); } private void createMap() { Node node; map = new ArrayList<ArrayList<Node>>(); for (int x=0; x<mapWidth; x++) { map.add(new ArrayList<Node>()); for (int y=0; y<mapHeight; y++) { node = new Node(x,y); if (obstacleMap[x][y] == 1) node.setObstacle(true); map.get(x).add(node); } } } /** * Registers the nodes edges (connections to its neighbours). */ private void registerEdges() { for ( int x = 0; x < mapWidth-1; x++ ) { for ( int y = 0; y < mapHeight-1; y++ ) { Node node = map.get(x).get(y); if (!node.isObstacle()){ if (!(y==0)) node.setNorth(map.get(x).get(y-1)); if (!(x==mapWidth)) node.setEast(map.get(x+1).get(y)); if (!(y==mapHeight)) node.setSouth(map.get(x).get(y+1)); if (!(x==0)) node.setWest(map.get(x-1).get(y)); } } } } public ArrayList<ArrayList<Node>> getNodes() { return map; } public void setObstacle(int x, int y, boolean isObstacle) { map.get(x).get(y).setObstacle(isObstacle); } public Node getNode(int x, int y) { return map.get(x).get(y); } public void setStartLocation(Node start) { map.get(startLocationX).get(startLocationY).setStart(false); map.get(start.getX()).get(start.getY()).setStart(true); startLocationX = start.getX(); startLocationY = start.getY(); } public void setStartLocation(int x, int y) { map.get(startLocationX).get(startLocationY).setStart(false); map.get(x).get(y).setStart(true); startLocationX = x; startLocationY = y; } public void setGoalLocation(Node goal) { map.get(goalLocationX).get(goalLocationY).setGoal(false); map.get(goal.getX()).get(goal.getY()).setGoal(true); goalLocationX = goal.getX(); goalLocationY = goal.getY(); } public void setGoalLocation(int x, int y) { map.get(goalLocationX).get(goalLocationY).setGoal(false); map.get(x).get(y).setGoal(true); goalLocationX = x; goalLocationY = y; } public int getStartLocationX() { return startLocationX; } public int getStartLocationY() { return startLocationY; } public Node getStartNode() { return map.get(startLocationX).get(startLocationY); } public int getGoalLocationX() { return goalLocationX; } public int getGoalLocationY() { return goalLocationY; } public Node getGoalLocation() { return map.get(goalLocationX).get(goalLocationY); } public float getDistanceBetween(Node node1, Node node2) { //if the nodes are on top or next to each other, return 1 if (node1.getX() == node2.getX() || node1.getY() == node2.getY()){ return 1; } else { //if they are diagonal to each other return diagonal distance: sqrt(1^2+1^2) return (float) 1.4; } } public int getMapWidth() { return mapWidth; } public int getMapHeight() { return mapHeight; } public JPanel init(){ int n=20; p=new JPanel(); p.setLayout(new GridLayout(n, n)); p.setSize(400,400); p.setFont(new Font("SansSerif", Font.BOLD, 24)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { p.add(map.get(j).get(i)); } } return p; } public void clear() { startLocationX = 0; startLocationY = 0; goalLocationX = 0; goalLocationY = 0; createMap(); registerEdges(); } } public class Display extends JApplet { private static int[][] M = {{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}, {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0}, {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0}, {0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,1,1,0,0,0}, {0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0}, {0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0}, {1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0}, {0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0}, {0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0}, {0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; public void init() { JRootPane rootPane = this.getRootPane(); rootPane.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); Map m=new Map(20,20,M); add(m.init()); } } This is the output that I got from the above code: Please load the code & check.I cannot post image since I lack 10 reputation
Within the Node class, the methods getParent, getX, and getY are overriding methods in the super class JButton. When the layout manager calls getX and getY your methods get called which confuses the layout manager. Rename your three methods to anything else, for example nodeGetParent, nodeGetX, and nodeGetY. The lesson to learn here is that you must be careful when extending a class that you don't accidentally override the super class' methods.
Backtracking maze algorithm
I'm having some issues implementing backtracking for solving a maze, the issue I'm having is that if the player gets to a dead end, it doesn't go back to where it have another solution. In the case i developed just by coincidence at first it worked because of the order of the methods, but if i put that the player moves first east, it reaches a dead end and doesn't backtrack. Here is the code: import java.util.ArrayList; public class Laberinto { int posicionX = 0; int posicionY = 0; int largo = 6; int ancho = 6; int solX = 5; int solY = 4; boolean[][] cordenadas = new boolean[largo][ancho]; int[] bloqueadasX = {1,2,3,4,5,5,0,2,3,4,5,0,2,3,4,5,3,0,1,5}; int[] bloqueadasY = {0,0,0,0,0,1,2,2,2,2,2,3,3,3,3,3,4,5,5,5}; public ArrayList<Coordenada> recorridas = new ArrayList<Coordenada>(); public Laberinto(int xo,int yo) { posicionX = xo; posicionY = yo; recorridas.add(new Coordenada(posicionX,posicionY)); } public void recorrer() { if(posicionX==solX && posicionY == solY) { System.out.println("Solucion encontrada"); } else { if(este(posicionX,posicionY)) recorrer(); if(norte(posicionX,posicionY)) recorrer(); if(sur(posicionX,posicionY)) recorrer(); if(oeste(posicionX,posicionY)) recorrer(); volver(new Coordenada(posicionX,posicionY)); } } public void armarLaberinto() { for(int i=0;i<ancho;i++) { for(int j=0;j<largo;j++) { cordenadas[j][i] = estaBloqueada(j,i); } } } public boolean estaBloqueada(int x,int y) { for(int i=0;i<bloqueadasX.length;i++) { if(x==bloqueadasX[i] && y==bloqueadasY[i]) { return true; } } return false; } public boolean norte(int x,int y) { if(dentroTablero(x,y-1)) { if(!yaRecorrido(new Coordenada(x,y-1))) { if(estaBloqueada(x,y-1)) { return false; } posicionY = posicionY-1; recorridas.add(new Coordenada(x,y)); return true; } return false; } return false; } public boolean sur(int x,int y) { if(dentroTablero(x,y+1)) { if(!yaRecorrido(new Coordenada(x,y+1))) { if(estaBloqueada(x,y+1)) { return false; } posicionY = posicionY+1; recorridas.add(new Coordenada(x,y)); return true; } return false; } return false; } public boolean este(int x,int y) { if(dentroTablero(x+1,y)) { if(!yaRecorrido(new Coordenada(x+1,y))) { if(estaBloqueada(x+1,y)) { return false; } posicionX = posicionX+1; recorridas.add(new Coordenada(x,y)); return true; } return false; } return false; } public boolean oeste(int x,int y) { if(dentroTablero(x-1,y)) { if(!yaRecorrido(new Coordenada(x-1,y))) { if(estaBloqueada(x-1,y)) { return false; } posicionX = posicionX-1; recorridas.add(new Coordenada(x,y)); return true; } return false; } return false; } public boolean dentroTablero(int x, int y) { if((x >=0 && x<=ancho) && (y>=0 && y<=largo) ) { return true; } return false; } public boolean yaRecorrido(Coordenada a) { for(int i=0;i<recorridas.size();i++) { if(recorridas.get(i).getX() == a.getX() && recorridas.get(i).getY() == a.getY()) { return true; } } return false; } public void volver(Coordenada a) { recorridas.remove(a); } public void bloqueadas() { armarLaberinto(); for(int i=0;i<ancho;i++) { for(int j=0;j<largo;j++) { if(!cordenadas[j][i]) { if(j==solX && i==solY) { System.out.print("M"); } else { System.out.print(" "); } } else { System.out.print("◘"); } } System.out.println(); } } public void mostrarRecorrido() { armarLaberinto(); for(int i=0;i<ancho;i++) { for(int j=0;j<largo;j++) { if(!cordenadas[j][i]) { if(j==solX && i==solY) { System.out.print("M"); } else { if(yaRecorrido(new Coordenada(j,i))) { System.out.print("•"); } else { System.out.print(" "); } } } else { System.out.print("◘"); } } System.out.println(); } } public static void main(String[] args) { Laberinto laberinto = new Laberinto(0,0); laberinto.armarLaberinto(); laberinto.bloqueadas(); laberinto.recorrer(); laberinto.mostrarRecorrido(); System.out.println(laberinto.posicionX); System.out.println(laberinto.posicionY); } }
One possible bug is you have a global for your position. This would confuse your search a lot, once the first call fails to find the solution. Try to keep posicionX,posicionY as local to that function if possible.