Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So I tried this program which was supposed to find out what position these doors are in. They start out closed, and then you toggle every door. The next time you toggle every second, then every third, fourth, so on. I got the coding right but it seems really inefficient. If I tried this with larger numbers, then the program would take too long. Is there any way to do this more efficiently? Here is my coding:
public class doors
{
public static void main(String [] args)
{
int x, y = 1;
boolean [] doors = new boolean[100];
for (int a = 0; a < doors.length; a++)
doors[a] = false; //false means closed
do
{
for (x = 0; x < doors.length - 1; x++)
{
if ((x+1) % y == 0)
{
if (doors[x] == true)
doors[x] = false;
else if (doors[x] == false)
doors[x] = true;
}
}
y++;
}while (y <= doors.length);
for (boolean b : doors)
System.out.println(b);
}
}
// Thanks!!!
Let's simplify the code one step at a time.
1) When an array is allocated, all elements are initialized to their default value, which means 0, false, or null. In your case that means false, so no need to loop through and do that.
// before
boolean [] doors = new boolean[100];
for (int a = 0; a < doors.length; a++)
doors[a] = false; //false means closed
// after
boolean[] doors = new boolean[100];
2a) Since the array is not a zero-length array, the do-while loop might as well be a normal while loop (it will execute at least once).
2b) As a normal while loop, with an initializer right before the loop, and the increment at the end of the loop, it is the same as a for loop.
2c) Since y is not used after the loop, it can be declared in the loop.
// before
int x, y = 1;
do
{
//code
y++;
}while (y <= doors.length);
// after
int x;
for (int y = 1; y <= doors.length; y++)
{
//code
}
3a) doors[x] == true is the same as doors[x]. doors[x] == false is the same as ! doors[x].
3b) if (x) {} else if (! x) {} is the same as if (x) {} else {}. The test after else is redundant.
3c) if (x) x = false; else x = true; is the same as x = ! x;.
3d) You can skip the double evaluation by doing ^= true (XOR).
// before
if (doors[x] == true)
doors[x] = false;
else if (doors[x] == false)
doors[x] = true;
// after
doors[x] = ! doors[x];
// skip double evaluation of index lookup
doors[x] ^= true;
4a) (x+1) % y == 0 will only be true for x values of y-1, 2*y-1, 3*y-1, and so on, so make loop start at y-1 and increment by y, eliminating the need for the if statement.
4c) Since x is not used after the loop, it can be declared in the loop.
// before
int x;
for (x = 0; x < doors.length - 1; x++)
{
if ((x+1) % y == 0)
{
//code
}
}
// after
for (int x = y - 1; x < doors.length - 1; x += y)
{
//code
}
Result so far (after also removing unnecessary braces)
boolean[] doors = new boolean[100];
for (int y = 1; y <= doors.length; y++)
for (int x = y - 1; x < doors.length - 1; x += y)
doors[x] ^= true;
for (boolean b : doors)
System.out.println(b);
5a) Limiting x to < doors.length - 1 means that last value of the array will never be used/updated. Drop the - 1.
// before
for (int x = y - 1; x < doors.length - 1; x += y)
// after
for (int x = y - 1; x < doors.length; x += y)
6a) Printing the array with one boolean true/false value per lines is not very human readable. Print is as a binary number on one line.
// before
for (boolean b : doors)
System.out.println(b);
// after
for (boolean b : doors)
System.out.print(b ? '1' : '0');
System.out.println();
7a) Move the printing inside the outer loop, and you'll see an interesting pattern.
boolean[] doors = new boolean[100];
for (int y = 1; y <= doors.length; y++) {
for (int x = y - 1; x < doors.length; x += y)
doors[x] ^= true;
for (boolean b : doors)
System.out.print(b ? '1' : '0');
System.out.println();
}
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010
1000111000111000111000111000111000111000111000111000111000111000111000111000111000111000111000111000
1001111100101001111100101001111100101001111100101001111100101001111100101001111100101001111100101001
1001011101101011111000100001101100001000111110101101110100111001011101101011111000100001101100001000
1001001101111011101000110001111100011000101110111101100100101001001101111011101000110001111100011000
1001000101111111101010110000111100111000111110110101100000101011001100111011001000100001110100011100
1001000001111110101010100000111000111001111110100101100100101010001100101011001100100000110100001100
1001000011111110111010100010111000101001111100100101110100101000001100111011001110100000100100001110
1001000010111110111110100010101000101000111100100001110100111000001101111011001010100000110100001111
1001000010011110111111100010101010101000111000100001111100111000011101111011101010100001110100001101
1001000010001110111111110010101010111000111000110001111100101000011101101011101010110001110100011101
1001000010000110111111110110101010111010111000110000111100101000111101101011111010110001111100011101
1001000010000010111111110111101010111010101000110000111000101000111100101011111010100001111100011001
1001000010000000111111110111111010111010101010110000111000111000111100101001111010100001101100011001
1001000010000001111111110111111110111010101010100000111000111001111100101001111110100001101100001001
1001000010000001011111110111111111111010101010100010111000111001111000101001111110101001101100001001
1001000010000001001111110111111111101010101010100010101000111001111000111001111110101001111100001001
1001000010000001000111110111111111101110101010100010101010111001111000111000111110101001111100101001
1001000010000001000011110111111111101111101010100010101010101001111000111000111010101001111100101000
1001000010000001000001110111111111101111111010100010101010101011111000111000111010111001111100101000
1001000010000001000000110111111111101111111110100010101010101011101000111000111010111000111100101000
1001000010000001000000010111111111101111111111100010101010101011101010111000111010111000111000101000
1001000010000001000000000111111111101111111111110010101010101011101010101000111010111000111000111000
1001000010000001000000001111111111101111111111110110101010101011101010101010111010111000111000111001
1001000010000001000000001011111111101111111111110111101010101011101010101010101010111000111000111001
1001000010000001000000001001111111101111111111110111111010101011101010101010101000111000111000111001
1001000010000001000000001000111111101111111111110111111110101011101010101010101000101000111000111001
1001000010000001000000001000011111101111111111110111111111101011101010101010101000101010111000111001
1001000010000001000000001000001111101111111111110111111111111011101010101010101000101010101000111001
1001000010000001000000001000000111101111111111110111111111111111101010101010101000101010101010111001
1001000010000001000000001000000011101111111111110111111111111110101010101010101000101010101010101001
1001000010000001000000001000000001101111111111110111111111111110111010101010101000101010101010101011
1001000010000001000000001000000000101111111111110111111111111110111110101010101000101010101010101011
1001000010000001000000001000000000001111111111110111111111111110111111101010101000101010101010101011
1001000010000001000000001000000000011111111111110111111111111110111111111010101000101010101010101011
1001000010000001000000001000000000010111111111110111111111111110111111111110101000101010101010101011
1001000010000001000000001000000000010011111111110111111111111110111111111111101000101010101010101011
1001000010000001000000001000000000010001111111110111111111111110111111111111111000101010101010101011
1001000010000001000000001000000000010000111111110111111111111110111111111111111100101010101010101011
1001000010000001000000001000000000010000011111110111111111111110111111111111111101101010101010101011
1001000010000001000000001000000000010000001111110111111111111110111111111111111101111010101010101011
1001000010000001000000001000000000010000000111110111111111111110111111111111111101111110101010101011
1001000010000001000000001000000000010000000011110111111111111110111111111111111101111111101010101011
1001000010000001000000001000000000010000000001110111111111111110111111111111111101111111111010101011
1001000010000001000000001000000000010000000000110111111111111110111111111111111101111111111110101011
1001000010000001000000001000000000010000000000010111111111111110111111111111111101111111111111101011
1001000010000001000000001000000000010000000000000111111111111110111111111111111101111111111111111011
1001000010000001000000001000000000010000000000001111111111111110111111111111111101111111111111111111
1001000010000001000000001000000000010000000000001011111111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001001111111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000111111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000011111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000001111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000111111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000011111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000001111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000111110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000011110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000001110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000110111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000010111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000000111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001111111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001011111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001001111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000111111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000011111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000001111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000111111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000011111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000001111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000111111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000011111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000001111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000111101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000011101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000001101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000101111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000001111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000011111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010111111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010011111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010001111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000111111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000011111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000001111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000111111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000011111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000001111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000111111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000011111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000001111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000111110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000011110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000001110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000110
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000010
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000000
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000001
Now, when you look at the pattern of the result (last line), you'll see that your code could be reduced to (very fast):
boolean[] doors = new boolean[100];
for (int idx = 0, incr = 1; idx < doors.length; idx += (incr += 2))
doors[idx] = true;
//print here
1001000010000001000000001000000000010000000000001000000000000001000000000000000010000000000000000001
First, the default value in your doors array is false (but you could use Arrays.fill to fill it if you needed to). Next you only need to increment your loop by y. Then you can toggle with doors[x] = !doors[x];. Something like,
int y = 1;
boolean[] doors = new boolean[100];
// Arrays.fill(doors, false);
do {
for (int x = y - 1; x < doors.length; x += y) {
doors[x] = !doors[x];
}
y++;
} while (y <= doors.length);
System.out.println(Arrays.toString(doors));
or using nested for loops like
boolean[] doors = new boolean[100];
// Arrays.fill(doors, false);
for (int y = 1; y < doors.length; y++) {
for (int x = y - 1; x <= doors.length; x += y) {
doors[x] = !doors[x];
}
}
System.out.println(Arrays.toString(doors));
As the guys have mentioned above there is a bunch of things you could do to simplify the code. By doing that you will start to better see the algorithms being used and therefore see where they can be improved.
With code like this, simplifying things like if statements is usually more about clarifying code than improving performance. The reason I say that is compilers these days and very good as optimising code and whilst a few instructions may be dropped the performance difference is likely to be minimal.
Where you are more likely to gain noticeable improvement is where there are loops. Reducing the number of iterations in a loop will often have a dramatic effect on overall time. To that end I can see two possible places you can improve things.
Firstly the initial setup loop may not be required. I haven't checked, but the array of doors may be false by default, so looping through to initialise could possibly be dropped.
Secondly, the inner loop increments by 1 and tests if that door matches y. You can short circuit a lot of this by simply incrementing the inner loop by y. That way you will always be on a door you want to flip. Which means you can drop the test for the correct door, and just flip it. As y increases, the number of iterations of the x loop would decrease. Meaning that it would speed up each time y increased.
Finally when I see code like this I always recommend one thing. Always put brackets on your if statements. Subtle bugs are easy to introduce when brackets are not used.
instead of using for statement , use foreach and switch instead
example
for(boolean i:doors){
//do something
}
Related
currently my program is only always giving me 4, how can I determine how many steps the ant took to cover the whole board? The ant can walk up down left right, but can't walk off the board, and then do this simulation 4 times.
public static void main(String args[]) {
int[][] grid = new int[8][8];
int count = 0;
int x = 0;
int y = 0; // arrays are 0 based
while(true)
{
int random = (int)Math.random()*4+1;
if (random == 1)
{
x--; // move left
}
else if (random == 2)
{
x++; // move right
}
else if (random == 3)
{
y--; // move down
}
else if (random == 4)
{
y++; // move up
}
if(x < 0 || y < 0 || x >= grid.length || y >= grid[x].length) break;
count++;
grid[x][y]++;
}
System.out.println("Number of Steps in this simulation: " + count); // number of moves before it fell
}
}
The problem is this expression:
int random = (int)Math.random()*4+1;
Through the explicit cast, only Math.random() ist casted to int. But since Math.random() returns a dobule < 1, it is casted to 0 and thus random is always 1 and the method always returns 0.
The problem can be fixed by casting Math.random() * 4:
int random = (int) (Math.random() * 4) + 1;
The parenthesis enforce that the value of Math.random() * 4 (which will be a value in the interval [0, 3)) will be casted to int.
Two remarks on your code:
I would recommend introducing an enum Direction with four values (one for each direction) and choose a random Direction by calling Direction.values()[(int) (Math.random() * 4)];
I would recommend to use a switch instead of the if-else-if cascade.
Ideone demo
The program will exit the while(true) loop once one of the 4 conditions is true. My suggestion is to move these conditions in your if(random == value) checks like this:
if( random == 1 )
{
x--;
if (x < 0 )
{
x++;
}
}
Now to exit your while(true) loop you need to have an extra condition. I would suggest to think about your board in terms of 0's and 1's. Everytime the ant cross a cell, you set the grid[x][y] = 1.
int stepsTaken = 0;
int cellsToCover = grid.length * grid[0].length ;
int coveredCells = 0;
while(true)
{
//your code here
if( random == 1 )
{
stepsTaken++;
x--;
if (x < 0 )
{
x++;
}
}
// the other if's with "stepsTaken" incremented too.
if ( grid[x][y] == 0 )
{
grid[x][y] = 1;
coveredCells++;
}
if (coveredCells == cellsToCover )
break;
}
But please notice the many ifs statements inside a while(true) loop. If you have to fill a board of 10 rows x 10 columns it would take too much until the board is filled. Instead I would suggest you to use some more efficient algorithms like backtracking, dynamic programming etc.
Edit : Added step counter.
So I was in class writing a nested while loop to calculate the value of z. I need to output both z and time it takes to get it.
Here is the result
public class TimeWhile {
public static void main(String[] args) {
int n = 100000;
int z = 1;
long startTime = System.currentTimeMillis();
int x = 0;
while (x <= n) {
int y = 0;
while (y <= n) {
z = x * y;
y++;
}
x++;
}
long endTime = System.currentTimeMillis();
long elapsed = endTime - startTime;
System.out.println("The time is " + elapsed);
System.out.println("The number is " + z);
}
}
Second while loop
public class TimeWhile {
public static void main(String[] args) {
int n = 100000;
int z = 1;
long startTime = System.currentTimeMillis();
int x = 0;
int y = 0;
while (x <= n) {
while (y <= n) {
z = x * y;
x++;
y++;
}
}
long endTime = System.currentTimeMillis();
long elapsed = endTime - startTime;
System.out.println("The time is " + elapsed);
System.out.println("The number is " + z);
}
}
Why does the second run much faster? The output "z" is the same.
I believe there are many things that are wrong with this code.
First of all there is no need to calculate z = x * y inside the loop as each but the last iteration overwrites the value. So your code is effectively the same as:
heatTheUniverseForSomeTime();
int z = n*n;
It means that the fact that the output of z is the same actually means almost nothing about how the loops work.
Secondly int is not sufficiently large type to hold the value of 100000*100000. That's why you have 1410065408 instead of more expected 10000000000. long would help (but beware you should cast at least one argument to long on the right as well!). If you need even bigger values, consider BigInteger.
Third point is that your first example could be re-written in a much more usual and thus understandable form by using the for loop as in:
for(int x = 0; x <= n; x++) {
for(int y = 0; y <= n; y++) {
z = x * y;
}
}
This code clearly needs to run n*n iterations in total.
Also I believe that now point #1 becomes even more clear.
Finally your second code is not equivalent to this in 2 different aspects:
as was pointed out you never reset the y so after the first time the inner run loop runs it never runs again
moreover since you do x++; in the inner loop as well, it means it always holds that x == y, so the outer loop never runs after the first iteration as well.
You second code is effectively the same as
for(int x = 0, y = 0; y <= n && x <= n; x++, y++) {
z = x * y;
}
This code clearly needs to run only n times instead of n*n which is much much faster.
In the first loop the value of y is always assigned to zero on every iteration, making it take more time and steps to reach n while in the second loop, y isn't resetted to zero thus it reaches n faster and in less steps.
loop1
while (x <= n) {
int y = 0;
loop2
while (x <= n) {
while (y <= n) {
z = x * y;
x++;
y++;
}
The second runs much faster because you increment x in the nested while loop, rather than in the outer while loop. The nested while loop runs many more times than the outer loop because it will keep repeating until the outer loop's condition is false. If you put x in the nested loop, it will repeat more times successively, making the outer loop's condition false quicker.
I am trying to save the method outOfBounds which is called inside the lengthOfColor method more than once to a local variable, so that less processing power is used. I provided the lengthOfColor method in which I want to store the variable, and I also provided the outOfBounds method. As you can see the outOfBounds method is a boolean and I am not sure how to store it with integer parameters.
private Integer[] lengthOfColor(int col, boolean color, int pattern, int row) {
int x = 0;
int y = 0;
if (pattern == 1) {
// vertical pattern
y = 1;
} else if (pattern == 2) {
// horizontal pattern
x = 1;
} else if (pattern == 3) {
// diagonal slope left pattern
x = 1;
y = 1;
} else {
// diagonal slope right pattern
x = 1;
y = -1;
}
// length = how many neighbor slots are of same color
// possible equals number of slots, that you can play off of.
// whichSide = left or right if horizontal and top or bottom if vertical.
int length = 0;
int possible = 0;
Integer[] whichSide = new Integer[]{1, -1};
for (int side : whichSide) {
int i = 1;
boolean complete = false;
//while complete is false continue the loop
while (!complete) {
//mainX == horizontal pattern distance
//mainY == vertical pattern distance
int mainX = x * i * side;
int mainY = y * i * side;
//if still inbounds and if the same slot is filled and it matches the color, increment length
if (!outOfBounds(col, mainX, mainY, row) && getIsFilled(col, mainX, mainY, row) &&
checkColor(col, mainX, mainY, row) == color)
{
length++;
}
//if still inbounds and if the same slot is empty, increment possible number of spots and change complete to true
else if (!outOfBounds(col, mainX, mainY, row) && !getIsFilled(col, mainX, mainY, row) &&
getLowestEmptyIndex(myGame.getColumn(col + mainX)) == getLowestEmptyIndex(myGame.getColumn(col)) + mainY - row)
{
possible++;
complete = true;
}
//finish the statement to avoid a infinite loop if neither conditions are met.
else
{
complete = true;
}
// If not complete, then check one slot further.
i = i + 1;
}
}
return new Integer[] {length, possible};
}
private boolean outOfBounds(int col, int x , int y, int row)
{
int currentX = col;
int currentY = getLowestEmptyIndex(myGame.getColumn(col)) - row;
return currentX + x >= myGame.getColumnCount() || currentY + y >= myGame.getRowCount() || currentX + x < 0 || currentY + y < 0;
}
I see that mainX and mainY change values so there isn't any real optimization that can be done outside of the for and while loop besides creating a boolean value that holds the result of outOfBounds before the if check is called which would reduce the number of operations you need to do. To be honest, the optimization is so insignificant that it wouldn't really matter but would be good coding practice I suppose (JIT might optimize for you as well depending on your code). More importantly the method reduces the extra lines of code you need to type and does not necessarily mean that there is less computing.
So something like this before any outOfBounds call but inside the while loop,
boolean outOfBounds = outOfBounds(col, mainX, mainY, row);
and change your current if(!outOfBounds(col, mainX, mainY, row) && ....) into if (!outOfBounds && ...)
Also the #1 rule to optimization is to not optimize until you are done with your project and notice a significant performance dip. In which case you would start with the biggest bottleneck until the optimal performance is gained. Of course this does not mean coding in an incorrect way which would of course create unnecessary performance losses. In those cases it would also be wise to consider whether or not you are looking at the problem the right way rather than micro-optimizing.
Here's a snippet of what I would do to micro-optimize the code shown.
private Integer[] lengthOfColor(int col, boolean color, int pattern, int row) { // consider changing Integer[] into
// int[] if you don't need a boxed integer. It will increase performance
int x = 0;
int y = 0;
// length = how many neighbor slots are of same color
// possible equals number of slots, that you can play off of.
// whichSide = left or right if horizontal and top or bottom if vertical.
int length = 0;
int possible = 0;
switch (pattern) { // switch may be a tad faster but insignificant. More importantly it provides clarity.
case 1:
y = 1;
break;
case 2:
x = 1;
break;
case 3:
x = 1;
y = 1;
break;
default:
x = 1;
y = -1;
break;
}
//int[] whichSide = new int[]{1, -1}; // changed to int[] because you don't need a boxed primitive from what is
// shown
// nevermind, this line isn't needed and you will be able to avoid an instantiation.
for (int i = 1; i != -3; i-=2) {
int count = 1;
int mainX; // bring this to a higher scope. (honestly this is micro optimization but a habit of mine if this is
// can be considered in scope)
int mainY;
boolean outOfBounds = false;
//boolean complete = false; // removed as its unnecessary to break out of the while loop.
//while complete is false continue the loop
while (true) {
//mainX == horizontal pattern distance
//mainY == vertical pattern distance
mainX = x * count * i;
mainY = y * count * i;
outOfBounds = outOfBounds(col, mainX, mainY, row);
//if still inbounds and if the same slot is filled and it matches the color, increment length
if (!outOfBounds && getIsFilled(col, mainX, mainY, row) &&
checkColor(col, mainX, mainY, row) == color) {
length++;
}
//if still inbounds and if the same slot is empty, increment possible number of spots and change complete to
// true
else if (!outOfBounds && !getIsFilled(col, mainX, mainY, row) &&
getLowestEmptyIndex(myGame.getColumn(col + mainX)) == getLowestEmptyIndex(myGame.getColumn(col)) + mainY -
row) {
possible++;
break;
}
//finish the statement to avoid a infinite loop if neither conditions are met.
else {
break;
}
// If not complete, then check one slot further.
count++;
}
}
return new Integer[]{length, possible}; // once again consider whether or not you need a boxed integer
}
private boolean outOfBounds(int col, int x, int y, int row) {
//int currentX = col; this is an unnecessary line
int currentY = getLowestEmptyIndex(myGame.getColumn(col)) - row;
return col + x >= myGame.getColumnCount() || currentY + y >= myGame.getRowCount() || col + x < 0 ||
currentY + y < 0;
}
I've been researching "dead code" and "unreachable code" for awhile now and I still can't seem to figure out what's going on with this problem in my program. This is a snippet of what I have; the method "gameEnd()" which checks for winners in Tic Tac Toe:
private boolean gameEnd() {
// Setting local variables
int x = xMouseSquare;
int y = yMouseSquare;
int[][] g = gameBoard;
int c = CPU;
int h = HUMAN;
// Checking for a winner
/* Checking columns (xMouseSquare)
* Enter the y value, the vertical value, first; then x, the horizontal value, second
*/
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Set CPU c equal to 0
c = 0;
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Add CPU's value to the game board
c += g[x][y];
// If statement returning the absolute value of CPU
if (Math.abs(c) == 3) {
// If these values are correct, return true; the game ends with CPU win horizontally
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// This time, however, set HUMAN h equal to 0
h = 0;
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Then add HUMAN's value to the game board
h += g[x][y];
// If statement returning the absolute value of HUMAN
if (Math.abs(h) == -3) {
// If these values are correct, return true; the game ends with HUMAN win horizontally
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
{
/* Checking rows (yMouseSquare)
* Enter the x value, the horizontal value, first; then y, the vertical value, second
*/
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Set CPU equal to 0
c = 0;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Add CPU's value to the game board, but with y and then x
c += g[y][x];
// If statement returning the absolute value of CPU
if (Math.abs(c) == 3) {
// If these values are correct, return true; the game ends with CPU win vertically
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
{
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// This time, however, set HUMAN h equal to 0
h = 0;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Then add HUMAN's value to the game board
h += g[x][y];
// If statement returning the absolute value of HUMAN
if (Math.abs(h) == -3) {
// If these values are correct, return true; the game ends with CPU win vertically
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
}
}
}
} // error on this bracket; but when I remove it, some of the code above becomes unreachable. Can anyone point to what I'm doing wrong?
If it was indented properly, I think it would show that the first occurrence of 'return false' will always be executed if the first instance of 'return true' was not hit, hence all remaining code is never reached.
Here is your problem right here
// If not, return false; game continues until all marks are filled
return false; <-- code exits here, everything below will not run.
{
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
...
I'm making a game for a class and one element of the game is displaying a number of cabbages, which are stored in an ArrayList. This ArrayList must be a fixed number of 20, 10 of Good Cabbage and 10 of Bad Cabbage.
As the cabbages are created, I want to make sure they don't overlap when they are displayed. Where I'm running into trouble with this is that when I find a cabbage that overlaps, I'm not sure how to go back and create a new cabbage in its place. So far when the code finds an overlap, it just stops the loop. I guess I'm having trouble properly breaking out of a loop and restarting at the index that goes unfilled.
Here's what I have so far for this. Any suggestions would be much appreciated.
// Initialize the elements of the ArrayList = cabbages
// (they should not overlap and be in the garden) ....
int minX = 170 ;
int maxX = 480;
int minY = 15;
int maxY = 480;
boolean r = false;
Cabbage cabbage;
for (int i = 0; i < N_GOOD_CABBAGES + N_BAD_CABBAGES; i++){
if (i % 2 == 0){
cabbage = new GoodCabbage((int)(Math.random()* (maxX-minX + 1))+ minX,
(int)(Math.random()*(maxY-minY + 1))+ minY,window);
}
else {
cabbage = new BadCabbage((int)(Math.random()* (maxX-minX + 1))+ minX,
(int)(Math.random()*(maxY-minY + 1))+ minY,window);
}
if (i >= cabbages.size()){
// compares the distance between two cabbages
for (int j = 0; j < cabbages.size(); j++){
Point c1 = cabbage.getLocation();
Cabbage y = (Cabbage) cabbages.get(j);
Point c2 = y.getLocation();
int distance = (int) Math.sqrt((Math.pow((c1.x - c2.x), 2) + Math.pow((c1.y - c2.y),2)));
if (distance <= (CABBAGE_RADIUS*2) && !(i == j)){
r = true;
}
}
if (r){
break;
}
cabbage.draw();
cabbages.add(i, cabbage);
}
}
The easiest way to do this is probably to add another loop.
A do...while loop is suited to cases where you always need at least one iteration. Something like:
boolean overlapped;
do {
// create your new cabbage here
overlapped = /* check whether it overlaps another cabbage here */;
} while (overlapped);
cabbage.draw();
cabbages.add(i, cabbage);
It looks like you are making cabbage objects and then throwing them away, which is a (trivial) waste.
Why not pick the random X and Y, check if there is room at that spot, then make the cabbage when you have a good spot? You'll just churn through numbers, rather than making and discarding entire Objects. Plus you won't have to repeat the random location code for good and bad cabbages.
int x, y
do {
// pick x and y
} while (cabbageOverlaps(x,y,list)
// create a cabbage at that x,y, and add it to list
boolean cabbageOverlaps(int x, int y, ArrayList existingCabbages)