Why is this giving a out of bounds exception? - java

I have been trying to trouble shoot this section for a while now and can't seem to understand why this keeps throwing an out of bounds exception. Trouble shooting seems to say that I shouldn't be I shouldn't be going out of bounds however the results produced seem inconsistent. For instance, here is a result from a test. I can't really understand how something like this would happen. Is there anything obviously wrong with this method for setting neighbors of objects in an ArrayList? I just want to know if there are any glaring logical errors here, if not I will just have to test more on my own. Thank you for the help.
public void setNeighbors(ArrayList<ArrayList<Objects>> arrayList) //sets the neighboring tiles for each tile
{
//arrayList is an multi dimensional array of Objects with a variable size. It is created in another method
for(int i = 0; i < arrayList.size(); i++)
{
for(int x = 0; x < arrayList.get(i).size(); x++)
{
// 1 2 3
// 4 # 6
// 7 8 9
if((i>0&&x>0) && x<arrayList.get(i).size()-1 && i<arrayList.size()-1)
{ //goes 1 3 7 9
System.out.println("Max X:"+(arrayList.get(i).size()-1));
System.out.println("Max Y:"+(arrayList.size()-1));
System.out.println("X:"+x);
System.out.println("Y:"+i);
// A Floor is a type of Object and addNeighbor adds a Floor object to an ArrayList of Floor Objects within a Floor
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x+1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x+1));
}
if (x>0 && x<arrayList.get(i).size()-1)
{ // 4 6
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i).get(x+1));
}
if (i>0 && i<arrayList.size()-1)
{ // 2 8
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x));
}
}
}
}

Since the code seems to be blowing up on the value of x+1, either the line
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x+1));
or the line
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x+1));
are at fault. In either case, it suggests that the individual ArrayLists are not of a constant length.

In your if-statement you have:
if((i>0&&x>0) && x<arrayList.get(i).size()-1 && i<arrayList.size()-1)
So you check to make sure that x is in the bounds for the arrayList in the ith position. However you change i. So while x could be in bounds for arrayList(i) it might not be in bounds for arrayList(i + 1)

When either i or x are already at their maximum valid values, your code can still try to add 1 to them and use the result for indexing.

the cause are the following lines regarding the x+1 and i+1
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x+1));
Your if clause have to check for size()-2 on the x and i variable not -1.
Without knowing what your are exactly doing this should work. Think the algorithm will not work in the right manner , you have to check
for(int x = 0; x < arrayList.get(i).size(); x++)
{
// 1 2 3
// 4 # 6
// 7 8 9
if((i>0&&x>0) && x<arrayList.get(i).size()-2 && i<arrayList.size()-2)
{ //goes 1 3 7 9
System.out.println("Max X:"+(arrayList.get(i).size()-1));
System.out.println("Max Y:"+(arrayList.size()-1));
System.out.println("X:"+x);
System.out.println("Y:"+i);
// A Floor is a type of Object and addNeighbor adds a Floor object to an ArrayList of Floor Objects within a Floor
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x+1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x+1));
}
if (x>0 && x<arrayList.get(i).size()-2)
{ // 4 6
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i).get(x-1));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i).get(x+1));
}
if (i>0 && i<arrayList.size()-2)
{ // 2 8
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i-1).get(x));
((Floor)arrayList.get(i).get(x)).addNeighbor((Floor)arrayList.get(i+1).get(x));
}
}
}

Related

After generating an array, how to filter out specific numbers I need?

I have an assignment that I can´t solve for a couple of days. I am very frustrated and feel too dumb for java. The Problem is the extract of the code below (my Professor wrote it). My task is to complete the code. So that when I write in my terminal for example "java Yahtzee 1 1 1 2 3" I should receive "sum of ones: 3".
Why did I stick to this problem? - because I don´t really understand these brackets [i] and how to deal with them.
import java.util.Arrays;
public class Yahtzee {
/**
* ones
* #param dice rolled numbers, sorted in ascending order
* #return the sum of the numbers on all dice showing a 1
*/
private static int aces(int[] dice) {
return -1;
}
public static void main(String[] args) {
// it is allowed to change the main method
if(args.length != 5) {
// the array length should be 5
System.out.println("ERROR: nicht genau 5 Zahlen übergeben");
return;
}
// read the passed numbers
int[] dice = new int[args.length];
for(int i = 0; i < args.length; i++) {
dice[i] = Integer.parseInt(args[i]);
if(dice[i] < 1 || dice[i] > 6) {
System.out.println("Error: invalid number " + dice[i]);
return;
}
}
System.out.println("sum of ones: " + aces(dice));
}
}
I think I should filter out the three ones. My first thought is to make an if-statement in main-method that could look like this: if(dice[i] == 1) and find only those ones. But I dont have idea how to work further. Can some one explain how to solve this problem or give an idea?
I started first programming 1 month ago and learned already some about loops and booleans and arrays. I red other questions like mine, but I do not understand what they do (I only worked with integers and doubles). I think I should work with loops or something like that.
To begin with, it's helpful to know how Yahtzee is played and this link. As you can see in the links, the game of Yahtzee is played with five dice which a player rolls. The value of each dice is held within a int[] Array as an integer element value:
Knowing this and once the dice array is filled, you can iterate through the dice[] Array and sum whatever you like within the aces() method. Obviously, because the method is named aces, it would be any dice[] element that has a value of 1 that is summed, for example:
private static int aces(int[] dice) {
int sum = 0;
/* Read each element of the supplied dice[] Array...
We start `i` at 0 because the first element in any
array is at index 0 (not 1) and we will iterate
through until we reach the array length which is
a literal value. There is no index 5 which is why
it will keep looping for as long as `i` is less
than (<) dice.length. */
for (int i = 0; i < dice.length; i++) {
// Does the current array element contain a value of 1?
if (dice[i] == 1) {
//Yes ... then sum it
sum += dice[i]; // Same as: sum = sum + {value in dice[i] (which is 1)}
}
// No...continue looping.
}
/*
// Can also be done this way with an Enhanced `for` loop:
for (int v : dice) {
if (v == 1) { sum += v; }
}
*/
return sum; // Return the sum of 1's.
}
If you apply the above exampled dice roll to the command-line then the console window should display something like:
Sum of ones: 3
On a side:
When creating your dice[] Array from the command-line arguments (varArgs) you should validate the fact that valid values have been supplied before you add them into the Array. It may not be a big problem in this use-case because the application halts when an invalid value is detected but in the future, this may not always be the situation in another application you develop. Checking for non-numerical (integer) values would be a good idea as well. You application will crash if a letter was supplied in the command-line instead of a integer number. You cover the upper and lower inclusive numerical boundaries but nothing if there is a non-numerical value. This can be solved with a little change to your code:
int[] dice = new int[args.length];
for(int i = 0; i < args.length; i++) {
// If the command-line argument is anything other than 1 to 6...
if(!args[i].matches("[1-6]")) {
System.out.println("Error: Invalid value (" + dice[i]
+ ") in Command-Line arguments!");
return;
}
dice[i] = Integer.parseInt(args[i]);
}
You will notice that the String#matches() method is used for the condition of the if statement and passed to it is a small Regular Expression (regex) of "[1-6]". What this expression does is it will see if the value passed to the current (args[i]) argument it's checking is nothing more than a string representation of a integer numerical value consisting of a inclusive value from 1 to 6. Anything else and the validation fails. You will also note that the NOT operator (!) is used at the beginning of the condition. This would be the same as saying,
"If args[i] does not contain a string representation of a integer value
inclusively between 1 and 6 then, inform the User of an Invalid Argument
and shut down the application, otherwise, add it to the `dice[]` Array."

Java: Sudoku Array not Filling

I've been trying to build a sudoku, starting with a 9x9 array that ensures no numbers in a given column nor row are the same (ie sudoku without the 3x3 boxes). I've set my code as seen below, but I keep running into a runtime error that I think stems from the do-while statement where the array won't finish filling. However, if I add 10 to the new randomized number (within the do-while statement) the array will finish filling. I've also created a lengthy "check" method that checks whether the current cell is the same as any of the others in that column or row and returns true only if the number is original. I have not included that method for simplicity. Is there something I'm missing?
import java.util.Random;
public class S9x9 {
public static void main (String[] args){
int [][] nines = new int [9][9];
Random rand = new Random();
for (int i = 0; i < nines.length; i++) {
for (int j = 0; j < nines.length; j++) {
nines[i][j] = rand.nextInt(9) + 1;
if (!(check(nines,i,j))) {
do
nines[i][j] = rand.nextInt(9) + 1;
while (!(check(nines, i, j)));
}
System.out.print(nines[i][j] + " ");
}
System.out.print("\n");
}
}
}
Your algorithm will end up in a deadlock quite soon. Suppose you have this:
5 2 3 1 8 6 9 7 4
4 3 1 6 9 2 5 8 7
2 1 6 7 3 5 8 9
There is no valid number to put in the last place. I suggest you change your algorithm to weed out all invalid numbers before using random generation. If there are zero candidates, you have to backtrack.
The problem is that you can deadlock yourself when you don't use any backtrack algorithm in finding a sudoku solution. Assume your two for() loops have already found the following grid:
xxx xxx x1x
xxx xxx x2x
xxx xxx x3x
xxx xxx x4x
567 891 2?.
... ... ...
... ... ...
... ... ...
... ... ...
The place with the ? marker, where your current i and j values are, cannot have any valid number since all the digits are already "used". Check other questions like How to solve Sudoku by backtracking and recursion? on how backtrack works for sudokus.

Solving a challenge in JAVA. The challenge is mentioned below in the description. The logical bug I am facing is also in the description below

Lukáš really likes orienteering, a sport that requires locating control points in rough terrain. To entertain the NWERC participants Lukáš wants to organize an orienteering race. However, it would be too harsh for the participants to be outdoors in this cold Swedish November weather, so he decided to jump on the new trend of indoor races, and set the race inside the B building of Linköping University.
Lukáš has already decided on the locations of the control points. He has also decided on the exact length of the race, so the only thing remaining is to decide in which order the control points should be visited such that the length of the total race is as he wishes. Because this is not always possible, he asks you to write a program to help him.
Input Format
The input consists of:
one line with two integers n (2 ≤ n ≤ 14) and L (1 ≤ L ≤ 1015), the number of control points and the desired length of the race, respectively;
n lines with n integers each. The jth integer on the ith line, dij , denotes the distance between control point i and j (1 ≤ dij ≤ L for i 6= j, and dii = 0). For all 1 ≤ i, j, k ≤ N it is the case that dij = dji and dij ≤ dik + dkj .
Output Format
Output one line with “possible” if it is possible to visit all control points once in some order and directly return to the first one such that the total distance is exactly L, and “impossible” otherwise.
Sample Input
3 5
0 1 3
1 0 3
4 1 0
Sample Output
possible
The problem with the code is that the for loop in else loop of function checkscenario() only considers the first iteration and returns false as a result. It doesn't check the next iteration which will return true and thus give the proper solution.
Lets use the sample input for the explanation. Initially, the function gets value of the parameters as follows :-
controlptsleft = {0,1,2,3}
//These are the control pts which haven't been visited.
index = 0;
//This is the control pt that I am at.
controlmatrix =
0 1 3
1 0 3
4 1 0
L = 5
//The desired length.
sum = 0
//Till now we haven't trailed the control pts. So, sum = 0.
public static boolean checkscenario(ArrayList<Integer> controlptsleft, int index, int[][] controlmatrix, int L, int sum){
int row = controlptsleft.get(index);
//row stores the value in the ArrayList controlptsleft at the index.
controlptsleft.remove(index);
//The controlpt is removed. The first time 0 will be removed from arrayList controlptsleft.
if(controlptsleft.isEmpty()){
//When the ArrayList controlptsleft is empty, we have to go back to the first controlflag.
int temp = controlmatrix[row][0];
//temp stores the distance between the control flag where we are at and the starting control flag.
if(L == (sum + temp))
return true;
}
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
//temp stores the distance between the control flag where we are at and the whatever controlflag we get during the iteration.
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
//Here, i is sent so that when it enters the function again the index i (along with the value) in ArrayList tempList will be deleted.
if(finalres)
return true;
}
}
return false;
}
Just in case someone out there wants to know, I figured out the answer for this challenge.
First of all, i would like to thank Hanno Binder for that comment. I realized where I went wrong.
Inside the else loop of the function checkscenario
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
What I did was, I directly copied the reference of controlptsleft to tempList. I realized the bug and I instead initialized tempList and used .addAll to put all the values from controlptsleft to tempList.
The following code illustrates what I meant above.
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(controlptsleft);
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
}
If someone has a better solution in JAVA for the challenge mentioned above. Feel free to post their code, so I could learn how to code better.

Scanning through 2d boolean array to find closest true coordinate

I am using a 2 dimensional boolean array to check where an entity is inside of my 2D side scroller as well as for collision. I know I am not looking for how high or low an entity away is and that is intentional. When I run this code it says the closest entity is 15 cells away. However, when I run my code it says the closest entity away is 15 blocks. Also when I print out distanceX it prints out the following:
9
0
0
2
2
15
9
0
0
2
2
15. I don't know why it won't register 9 as the closest even though that's is the first closest distance it recieves.
I can't post pictures yet however the reason 0,0,2, and 2 get printed is because I have 4 rectangles in all four corners of my player that are considered true in the grid so it detects the two on top of eachother and the other 2 or 2 spots away in the grid. Since I cant upload pictures try to see what I mean with this image i made. https://lh3.googleusercontent.com/OLSDPshjeU0YMahcmc0MDk-NocBMoG-7iN2xFTeFsQ8mAfF-sEPD8NBqXP4ENoN4YWmfUQ=s114
Thanks for any help!!
//Loop through my grid of booleans
for (int x = 0; x < map.getMapGrid().length; x++) {
for (int y = 0; y < map.getMapGrid().length; y++) {
//For comparison
Long distance = Long.MAX_VALUE;
// The second part of the if statement is to make sure it is checking for
// entities that arent the floor, therefor one above the grid position of the player
if (map.getMapGrid()[x][y] && y > ((Player) player).getGridPositionLeft().y - 1){
// distanceX = where something true was found (x) - where the player is in the grid
// Ex: 1 - 4 = |-3|, there is an entity 3 away
distanceX = Math.abs((int)(x - ((Player) player).getGridPositionLeft().x));
// if the distance of the entity from the player is less then the comparison variable,
// the closest entity x coordinate is distanceX
if(distanceX < distance){
closestCoord.x = distanceX;
closestCoord.y = 0;
}
}
}
}
return closestCoord;
}
Long distance = Long.MAX_VALUE;
This variable is never re-assigned, so it will always have the value Long.MAX_VALUE.
Also it is declared inside the innermost loop, so it will reset on each iteration. If you want the value of a variable to be remembered between iterations you need to declare and initialize it outside the loops.

for loop decrementing by 2 to 0 and summing up the values that were generated before getting to 0

I am trying to find a way to count down from the int that is input by a user and then add each second value as i count down to 0
for example.
{user inputs 10
program counts down 8,6,4,2,0
then add 10 + 8 + 6 + 4 +2 +0= 30
}
how can I do this using a nested for loop
so far I have only been able to take user input, and count down by 2 each time. I get to 0 but have no way of adding every second value.
My code:
so far, it just counts to 0
public class Week5b {
static Scanner userVal = new Scanner (System.in);
public static void main(String[] args) {
//printTable();
reverseAddSkip();
public static void reverseAddSkip(){
System.out.println("Please enter an integer");
for (int i = userVal.nextInt(); i >=0; i-=2){
System.out.println(i) ;
}/* this creates a loop where the variable i is equal to user input;
the condition for the loop to continue is whether the input is larger or equal to 0; the update part of the loop takes 2 away each time, as if it were -- (which takes away one each time) */
}
}
How would I write that out mathematically?
Adding the sum of i-=2 to the original value of i.
You type 11 , it counts 9 7 5 3 1 , then adds 11 9 7 5 3 1. and give you the sum.
don't know how to sum every 2 numbers decrementing by 2, from a user value.
You input put 50, it counts down by 2 to 0
you put 51 it counts down by 2 to 0
but I haven't found away to sum all then numbers that were generated before getting to 0
:/
NoGlitching,
You need to look at the control flow of your program - which is to say, the path it takes upon execution.
You should also look at using more variables.
I'll give you the pseudocode I would use, because I think it's important for you to be able to write the code yourself:
Make a new integer called OriginalInput.
Make a new integer called RunningTotal.
Set RunningTotal to 0.
Store the user's input in OriginalInput.
Loop through OriginalInput.
Print the current OriginalInput.
Add the current OriginalInput to RunningTotal.
When the loop is finished:
Print RunningTotal.
I hope this helps.
EDIT:
// First you equalize j with i
input = userVal.nextInt();
j = i; // Put the user input in j first. for instance 11.
for (int i = input; i >=0; i-=2)
{
if (i >= 0) // If i is not below 0
{
j += i; // Add to j what i has now (everytime -2)
// put a system out print here to show what was added
// J starts as 11 and adds 9,7,5,3,1 then nothing. So it ends as 36.
}
}
// outside the For loop after it ends but INSIDE your method, you get the sum from the variable j!

Categories