Avoid out of bounds exception in 2D array - java

I'm trying to solve a problem which uses a 2D array, the problem of a rat in a maze.
While checking the conditions trying to compile, it finds an Array index out of bounds exception... how can I check the values so it doesn't go out of the array bounds?
static void solveMaze(){
int nSteps = 0; // Number of steps.
int x = 0; int y = 0; // Starting point.
boolean mazeCompleted = false;
while (!mazeCompleted){
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
mazeCompleted = true;
else if(maze.mazeMatrix[x+1][y] == 0){ // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
else if(maze.mazeMatrix[x-1][y] == 0){ // Move left.
maze.mazeMatrix[x-1][y] = 2;
x--; nSteps++;
}
else if(maze.mazeMatrix[x][y+1] == 0){ // Move down.
maze.mazeMatrix[x][y+1] = 2;
y++; nSteps++;
}
else if(maze.mazeMatrix[x][y-1] == 0){ // Move up.
maze.mazeMatrix[x][y-1] = 2;
y--; nSteps++;
}
}
maze.printMatrix();
System.out.println("Maze COMPLETE! - With a total of " + nSteps + " steps.");
}
Tried before with two "for" loops to prevent the out of bounds but I just can't go diagonal in this problem.

You have a pretty crucial bug in your program. You will never reach the end of the maze!
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
references indices that are out of bounds! It should be
if(x == maze.mazeMatrix.length - 1 && y == maze.mazeMatrix.length - 1)
You also need to check to see whether you can & should move before you try to move there. I.E. :
while (!mazeCompleted){
boolean moveRight = (x + 1 < mazeMatrix.length && maze.mazeMatrix[x+1][y] == 0 ? true : false);
boolean moveLeft = (x - 1 >= 0 && maze.mazeMatrix[x-1][y] == 0 ? true : false);
boolean moveUp = (y + 1 < mazeMatrix[x].length && maze.mazeMatrix[x][y+1] == 0 ? true : false);
boolean moveDown = (y - 1 >= 0 && maze.mazeMatrix[x][y-1] == 0 ? true : false);
And:
else if(moveRight) { // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
etc. Although it does seem like this is something that should be solved recursively, as if there are any loops in the maze you will end up getting stuck and infinite looping.

Related

How does one put a ternary operator inside the parenthesis of a for loop

I've recently learnt ternary operators and was practising them by making some old code i wrote a while back nicer. When trying to do this to a for loop in many different ways I can't seem to figure out how to do it. Ive tried:
for (hotbarFirst ? (x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) :
(x = mc.player.inventoryContainer.getInventory().size(); x > 0; x--)) {
and
for (hotbarFirst ? (x = 0) : (x = mc.player.inventoryContainer.getInventory().size());
hotbarFirst ? (x < mc.player.inventoryContainer.getInventory().size()) : (x > 0);
hotbarFirst ? (x++) : (x--)){
}
The first way gives me unexpected token errors and the second one gives me not a statement errors. It seems like I should be able to do this in some way or another, so am I just approaching it wrong or is there another way to do this without making two for loops.
(ignore the functions, they're for a game I made the mod in)
(Also incase you didnt notice I'm trying to iterate over a set of numbers two either back to front or front to back depedning on whether the bool is true or false)
original code:
public static int getItem(Item itemofChoice, boolean hotbarFirst) {
if (mc.player == null) return -1;
for (int x = 0; x < mc.player.inventoryContainer.getInventory().size(); x++) {
if ((x == 0 || x == 5 || x == 6 || x == 7 || x == 8)) continue;
ItemStack s = mc.player.inventoryContainer.getInventory().get(x);
if (s.isEmpty()) continue;
if (s.getItem().equals(itemofChoice)) return x;
}
return -1;
}
Im trying to make it iterate the opposite way if the bool param is true
Here is one way to do it:
int size = mc.player.inventoryContainer.getInventory().size();
for (int x = (hotbarFirst ? 0 : size-1); (hotbarFirst ? x < size : x >= 0) ; x += (hotbarFirst ? 1 : -1)) {
...
}

Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException: / by zero in part of the program where it should divide numbers

I tried searching stackoverflow for answer but i could not find it. i figured out when i remove part of the program that divides numbers:
if(znak == 0) {
Resenje = x + y;
}else if(znak == 1) {
Resenje = x - y;
}else if(znak == 2) {
Resenje = x/y;
} else if(znak == 3) {
Resenje = x*y;
}else {
System.out.println("Greska u programu");
}
that error does not appear. i think the problem maybe if number is float but it is stored in int... Thank you, if you need any additional information im here to provide it.. :)
PS code is messy because i made it long time ago.. sorry, i cant figure out how to properly format it, i posted it on pastebin, i hope you dont mind it.. :)
https://pastebin.com/sfG9JEbR link for code
while(vece = true) {
// System.out.println(Odabir1);
x = random.nextInt(Odabir1);
// System.out.println(x);
y = random.nextInt(Odabir1);
// System.out.println(y);
//if(x == (int)x) {
if(x-y >= 0 && x+y <= Odabir1 && x+y!=0 && x-y!=0 && x/y >= 0 && x/y == (int)x && x*y >= 0 && x*y <= Odabir1) {
System.out.println(x + " " + y);
break;
}
}
when i try adding && y == 0; i get same error in every possibility

What is a good way to output why an object won't go through all of the "if" statements?

I am making a program that checks to see if an elements positive and negative charges are able to combine to make 0. A thing i want to do is output the reasons why the two elements are not able to combine. But it is more difficult than i expected. for example if sodium were trying to combine with copernicium, it would output this:
Sodium doesn't combine with Copernicium:
Both valence charges have same polarity.
One or more elements is man-made.
but i can not think of a way to implement this into my code.
here is my code:
public void combine(Element element){
if ((element.getValence() > 0 && valence < 0) || (element.getValence() < 0 && valence > 0)) { //one element needs a positive valence, and one needs a negative valence
if (valence != 0 && element.getValence() != 0) { //checks to see if valence is not equal to 0
if (natural == true && element.isNatural() == true) { //checks to see if both elements are natural
for (int x = 1; x <= 4; x++) {//bruteforce the atoms to see if they both add up to 0.
for (int y = 1; y <= 4; y++) {
if ((valence * x) + (element.getValence() * y) == 0) {
System.out.println(name + " combines with " + element.getName() + " to form " + symbol + "" + x + "" + element.getSymbol() + "" + y);
}
}
}
}
}
}
}
Thanks for any help!
The way to do this is to add else clauses for each if that return an appropriate message.
if ((element.getValence() > 0 && valence < 0) || (element.getValence() < 0 && valence > 0)) { //one element needs a positive valence, and one needs a negative valence
{
// the inner tests
}
else
{
System.out.println("The elements are both positive or both negative");
}
}
This should get you started in the right direction.

Java Monopoly Game

I made a Board and I set the board's layout to null. So I position my token's by moving them pixel by pixel. But when turning the corners I am having a trouble. After first 10 position token can make the turn and continue for the next 10 position. But it is impossible for my token to make the 2. turn.
Can anyone advice me a better code for this problem. I think I make things get more complicated than it is.
if(g.getPosx() <= 650 && g.getPosx() >= 50 && g.getPosy()==650) {
if(g.getPosx()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosx() - 50);
g.setPosx(50);
g.setPosy(g.getPosy()-temp);
}
else {
g.setPosx(g.getPosx()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosy() <= 650 && g.getPosy() >= 50 && g.getPosx()==650) {
if(g.getPosy()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosy() - 50);
g.setPosy(50);
g.setPosx(g.getPosx()-temp);
}
else {
g.setPosy(g.getPosy()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosx() <= 650 && g.getPosx() >= 50 && g.getPosy()==50) {
if(g.getPosx()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosx() - 50);
g.setPosx(50);
g.setPosy(g.getPosy()-temp);
}
else {
g.setPosx(g.getPosx()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosy() <= 650 && g.getPosy() >= 50 && g.getPosx()==50) {
if(g.getPosy()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosy() - 50);
g.setPosy(50);
g.setPosx(g.getPosx()-temp);
}
else {
g.setPosy(g.getPosy()-unitChange*d.getDice());
temp = 0;
}
}
Instead of using the current X and Y positions to track which location the piece is stopped on, try tracking which property the piece has landed on instead. so property 1 would be the first stop on the board after GO all the way up to boardwalk at position 39. Then you can have a function like
movePlayerToLocation(Player player, int location){
// calculate your x and y based on the property locatoin
if(locatoin < 11){
// on first edge
} else if (location < 21) {
// on second edge
} else if (location < 31)
// on third edge
} else {
// on fourth edge of the board
}
// do your g.setPos-ing
}

How to end my recursion

I need to program a method to solve a maze (2-dimensional array). I need to stay directly left of the wall at all times and my method should end when either I've reached the exit point (which is always at the same position) or when there is no solution possible (and, after running through the maze I'm back at the entry point).
I was able to do all that, no problems, I can visually ensure that it's doing what I want it to do (we've got some other methods from our instructor which output the visuals) and my console debug output is right as well.
This is the relevant code:
public static void main(String[] args) {
maze = generateMaze(10,10);
walk(1,0,0);
}
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
draw(x,y,maze); //draws current position
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
if (direction == 0) { //go down
if (maze [x][y+1]) {
walk(x,y,1);
}
walk(x,y+1,2);
}
if (direction == 1) { //go right
if(maze [x+1][y]) {
walk(x,y,3);
}
walk(x+1,y,0);
}
if (direction == 2) { //go left
if(maze [x-1][y]) {
walk(x,y,0);
}
walk(x-1,y,3);
}
if (direction == 3) { //go up
if(maze[x][y-1]) {
walk(x,y,2);
}
walk(x,y-1,1);
}
}
There's just one problem: how do I end my recursion correctly? This is what I get form the console:
x = 1 y = 0
x = 1 y = 1
x = 1 y = 1
x = 1 y = 2
and so on...
x = 8 y = 8
x = 9 y = 8
Geschafft!
x = 8 y = 9
x = 8 y = 9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
at maze.MazeSolution.walk(MazeSolution.java:26)
at maze.MazeSolution.walk(MazeSolution.java:39)
and some more of that
I do understand the error, the recursion obviously doesn't end where I want it to and x or y are increased and try to use an index in the array that isn't there.
Why doesn't the recursion end with the return statement, when either of these situations come true:
if (x == maze.length-1 && y == maze[1].length-2) { //terminate when reached exit
System.out.println("Geschafft!");
return;
}
if (x == 1 && y == 0 && direction == 3) { //terminate when at starting point again (no solution)
System.out.println("Keine Lösung möglich.");
return;
}
What do I need to do to end it correctly?
I greatly appreciate your help, show some love for a beginner and tell me what to do.
Add to the beginning
public static void walk(int x, int y, int direction) {
System.out.println("x = " + x + " y = " + y); //debug output
if (x >= 10 || x < 0 || y >= 10 || y < 0) return;
Look at your returns and where you may return to. You can return in the middle of your enclosing function which has other calls to walk, without the guards to ensure they're not called.
I recommend re-implementing your logic; think about having if/else pairs to ensure mutual exclusion.
Why don't you simply return true or false and react on it?
So basically you add to your two end cases return true; for code ended.
if(walk(...)) return true;

Categories