I am trying to check several entries in a game board by iterating over them in a specific order.
Now what I noticed is that when the method is called by my junit test, it is stuck in the first for loop and doesn't continue with the next ones, and just returns false, meaning it jumps to the end of the method.
When I run a test which just needs the first 3 loops, then it works, but another test requires the second loop, which doesn't get executed.
Question: Why is it jumping to the end without first checking the other loops?
public boolean hasDiagonal(Mark m) {
for (int i = 0; i <= dimension-4; i++) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k == 3; k--) {
if (getField(i , j , k ) == m &&
getField(i+1, j+1, k-1) == m &&
getField(i+2, j+2, k-2) == m &&
getField(i+3, j+3, k-3) == m) {
return true;
//Stops here, if this part doesn't yield true,
//it returns false immediately
}
}
}
}
//This doesn't get checked
for (int i = dimension-1; i == 3; i--) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k <= 3; k--) {
if (getField(i , j , k ) == m &&
getField(i-1, j+1, k-1) == m &&
getField(i-2, j+2, k-2) == m &&
getField(i-3, j+3, k-3) == m) {
return true;
}
}
}
}
return false;
}
I suspect that the i == 3 and k == 3 in your loop conditions are at least contributing to your problem. With these conditions the loops will get skipped unless dimension == 4.
The condition part of your loops should be the problem here -
for (int i = 0; i <= dimension-4; i++) {
for (int j = 0; j <= dimension-4; j++) {
for (int k = dimension-1; k == 3; k--)
the innermost loop executes only if dimension == 4 and since there is no modification within the loops to this variable.
The outermost and second loop doesn't even iterate more than once (the block would execute only once) if you do a j++ or i++ and at the same time check if i/j <= dimension(4)-4 resolving as i/j <= 0.
So certainly the loops need better handling with dimension specified and the conditions modified accordingly.
Related
How do I avoid going below 0 with this for loop ? When this loop executes, it checks if both the vehicle and the garage are in the same space. If not, it decrements the vehicle loop by --i to get the next available vehicle. when it reaches to index 0, it is going below index -1 causing the program to crash.
for (int i = vehicles.size() - 1; i >= 0;) {
for (int j = 0; j < garage.size();) {
if (this.garage.get(j).getSpace() == this.vehicles.get(i).getSpace()) {
if (this.garage.get(j).garageRequest(vehicles.get(i).getvehiclesType())
&& this.garage.get(j).getLimit() > 0) {
this.garage.get(j).addvehicles(vehicles.get(i));
this.vehicles.remove(i);
i--;
break;
} else {
j++;
}
} else {
i--;
j = 0;
}
}
i tried the following at the end
else if(i != 0) {
i--;
j = 0;
}
Add a second condition to your inner loop. That is, change
for (int j = 0; j < garage.size();) {
to
for (int j = 0; j < garage.size() && i >= 0;) {
Write a static method printNumbers that takes an integer max as an argument and prints out all perfect numbers that are less than or equal to max.
At first, I kept getting the wrong answer because the inner loop was set to j < max before I changed it to j < i. However, I don't understand why that range would matter, because wouldn't i % j != 0 anyway, even if the range of j were to be larger?
for (int i = 1; i <= max; i++) {
int sum = 0;
for (int j = 1; j < i; j++) {
if (i % j == 0) {
sum += j;
}
}
if (sum == i) {
System.out.print(sum + " ");
}
}
If I changed the inner loop j < max, then printNumbers(6) gives both 1 and 6, but printNumbers(500) gives only 1 and no other number.
If you set j < max in the inner loop, then when j = i, i % j == 0 returns true and skews your result.
This is a good example of a mathematical error to watch out for in coding.
I am wondering how changing this condition will change the way the function works:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i < j) { // This condition
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
Changing it as follows:
public static boolean palindrome(String str) {
int i = 0;
int j = str.length() - 1;
while(i <= j) { // Change is here
if(str.charAt(i) != str.charAt(j)) {
return false;
}
i = i + 1;
j = j - 1;
}
return true;
}
They seem to both detect palindromes. The second one takes one more step. I don't see how this changes anything.
Thank you!
Between while(i < j) and while(i <= j) The difference is that the second one has one additional step because in the end, you are comparing i with j as suppose just everything less than j
Example with input abcba:
// First Code Indices Checked (i and j)
0 < 4
1 < 3
2 < 2 //fails, done
// Second Code Indices Checked (i and j)
0 <= 4
1 <= 3
2 <= 2 //passes, continues
3 <= 1 //fails, done, unneeded comparison
And just like #azurefrog said : "You don't have to check past the
midpoint in palindrome detection"
I am trying to program a method that will use Gauss Elimination on a matrix (2 dimensional array), and I'm trying to debug my method and I've encountered this problem
public int Gauss() {
int i = 1;
int j = 1;
int pivotCol = 0;
while (pivotCol == 0 && j <= cols())
if (i == rows()){
j ++;
i = 1;
}
if (get(i,j) == 1.0){
pivotCol = j;
} else {
i ++;
}
return pivotCol;
}
This is not the final method, but for some reason, this loop never ceases, why?
while (pivotCol == 0 && j <= cols()) {
...
}
You forgot the brackets, so the while is only working with the if statement and therefore its running infinite.
I guess the problem is that your while loop doesn't have curly braces, e.g. it's effectively as follows:
while (pivotCol == 0 && j <= cols()) {
if (i == rows()){
j++;
i = 1;
}
}
If i != rows() this will never terminate.
Hi so I'm building a program to create the classical minesweeper game in Java, and have almost everything down but I cant figure out how to check the sqaures around a mine and to write in the numbers (i.e. if there are one, two, three mines next to it). I only included the method it's under, but I can post the rest of the program if necessary. What should my approach be? Thanks!
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
mineField[i-1][j-1];
mineField[i-1][j];
mineField[i-1][j+1];
mineField[i][j-1];
mineField[i][j+1];
mineField[i+1][j-1];
mineField[i+1][j];
mineField[i+1][j+1];
mineField[i][j].setAdjacentMines(0);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines
Something like this:
private void countAdjacentMines()
{
for (int i = 0; i < mineField.length; i++)
{
for (int j = 0; j < mineField.length; j++)
{
if (!(mineField[i][j].getIsMine()))
{
int count = 0;
for (int p = i - 1; p <= i + 1; p++)
{
for (int q = j - 1; q <= j + 1; q++)
{
if (0 <= p && p < mineField.length && 0 <= q && q < mineField.length)
{
if (mineField[p][q].getIsMine())
++count;
}
}
}
mineField[i][j].setAdjacentMines(count);
}
} // end for loop rows
} // end for loop columns
} // end countAdjacentMines
For each item in that "list", do something like:
if ((i-1) >= 0 && (j-1) >= 0 && mineField[i-1][j-1].getIsMine()) {
numAdjacentMines++;
}
It's probably worth writing a helper function to do all of this, and then you just need to call it 8 times.
You're on the right track. You should be keeping a counter, that represents the count of adjacent mines that return true for .getIsMine().
if (!(mineField[i][j].getIsMine()))
{
counter = 0;
if (i-1 >= 0)
{
if (j-1 >=0 && mineField[i-1][j-1].getIsMine()) counter++;
if (mineField[i-1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i-1][j+1].getIsMine()) counter++;
}
if (j-1 >=0 && mineField[i][j-1].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i][j+1].getIsMine()) counter++;
if (i+1 < mineField.length)
{
if (j-1 >=0 && mineField[i+1][j-1].getIsMine()) counter++;
if (mineField[i+1][j].getIsMine()) counter++;
if (j+1 < mineField.length && mineField[i+1][j+1].getIsMine()) counter++;
}
mineField[i][j].setAdjacentMines(counter);
}
You also need to be checking that all of those values (i-1, j-1, i+1, j+1) don't go outside the bounds of your array (i - 1 > -1, etc)
EDIT:: I think I covered all of the checks.
I'm not sure what you're trying to do. This statement, mineField[i-1][j-1]; and the ones like it just access data and do nothing with it.
I'm assuming that the array stores something that includes a boolean that tells you whether or not there's a mine in that space. If that's true, just make a counter and change those statements to something like if(mineField[i-1][j-1].hasMine()) counter++;. And then change the last statement to mineField[i][j].setAdjacentMines(counter);.
int sum = 0;
sum += mineField[i-1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i-1][j].getIsMine() ? 1 : 0;
sum += mineField[i-1][j+1].getIsMine() ? 1 : 0;
sum += mineField[i][j-1].getIsMine() ? 1 : 0;
sum += mineField[i][j+1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j-1].getIsMine() ? 1 : 0;
sum += mineField[i+1][j].getIsMine() ? 1 : 0;
sum += mineField[i+1][j+1].getIsMine() ? 1 : 0;
mineField[i][j].setAdjacentMines(sum);
This is count up how many are mines and use it properly. It may be more clean to create a loop to perform this calculation, since it is the same thing for each adjacent field.
Try something like:
private static int countAdjacentMines(int x, int y) {
int adjacentMines = 0;
for(int i = -1; i <= 1; i++) {
if((x + i < 0) || (x + i >= width)) {
continue;
}
for(int j = -1; j <= 1; j++) {
if((y + j < 0) || (y + j >= height)) {
continue;
}
if(mineField[x + i][y + j].getIsMine()) {
adjacentMines++;
}
}
}
return adjacentMines;
}
This should count the number of mines neighbouring a block at (x, y).