I am making game, where I need to check if object`s coordinates meets requirements (Destination coordinates) with permitted +- difference.
Example:
int x; //current object X coordinate
int y; //current object Y coordinate
int destinationX = 50; //example X destination value
int destinationY = 0; //example Y destination value
int permittedDiference = 5;
boolean xCorrect = false;
boolean yCorrect = false;
I am trying to create algorithm, checking
if (x == destinationX + permittedDifference || x == destinationX - permittedDifference)
{
xCorrect = true;
}
if (y == destinationY + permittedDifference || y == destinationY - permittedDifference)
{
yCorrect = true;
}
It sounds like most simply way, but maybe there is better one? Will be grateful for some tips.
You can make use of Math.abs() method here. Get the absolute difference between x and destinationX, and check whether it's less than or equal to permittedDifference:
xCorrect = Math.abs(x - destinationX) <= permittedDifference;
yCorrect = Math.abs(y - destinationY) <= permittedDifference;
Related
I'm programming a little game and I'm having some problems with the intersections. I need an efficient algorithm to check if two objects (which have x and y coords. and also a width and an height) are intersecting.
I tried with the following, but it doesn't always work, sometimes it doesn't recnognize an intersection.
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x >= this.x) && (y < this.y + this.height) && (y >= this.y))
return true;
else
return false;
}
I have an ArrayList containing the objects, and I do the following:
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equalsIgnoreCase("right") && car.contains(walls.get(i).getX() - 1, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("left") && car.contains(walls.get(i).getX() + 30, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("top") && car.contains(walls.get(i).getX(), walls.get(i).getY() + 30))
return true;
if (pDirection.equalsIgnoreCase("down") && car.contains(walls.get(i).getX(), walls.get(i).getY() - 1))
return true;
}
return false;
}
Note that "-1" and "+30" is to avoid the car enter the "walls", there the walls have a width of 30 and an height of 30. The car also has the same dimensions.
Also note that the x and y are the top-left cords of the rectangles. The car and the walls are rectangles.
I would be thankful for your help.
INFO: It doesn't recnognize an intersection at the beginn of a row of walls if I am above the wall and I change the direction to "down" or viceversa.
See picture
EDIT 1 (I tried inverting the objects, but it also doesn't always work):
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equals("right") && walls.get(i).contains(car.getX() + 30, car.getY()))
return false;
if (pDirection.equals("left") && walls.get(i).contains(car.getX() - 1, car.getY()))
return false;
if (pDirection.equals("top") && walls.get(i).contains(car.getX(), car.getY() - 1))
return false;
if (pDirection.equals("down") && walls.get(i).contains(car.getX(), car.getY() + 30))
return false;
}
return true;
}
The flaw in your algorithm is, you are always checking the left-top point of the wall whether it is in the car. However, this is not equivalent to having intersection.
Instead, you should check whether any one of the objects contains (at least) one corner (not necessarily the top left one) of the other object.
Note that you should perform this check for both sides, i.e. either the car contains any corner of the wall or the wall contains any corner of the car.
I solved modifying the contains method in the following way, and it now works perfectly:
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x > this.x-this.width) && (y < this.y + this.height) && (y > this.y-this.height))
return true;
else
return false;
}
I think that I did it involuntarily (checking for non-intersection instead of intersection), but I can optimize it using the answer/suggestion of #samgak and #Gene. So thanks, problem solved.
I have an if statement that looks like this:
if (pan[x + 1][y + 1].getBackground() == TeamColor &&
pan[x + 1][y].getBackground() == TeamColor &&
pan[x + 1][y -1].getBackground() == TeamColor &&
pan[x][y - 1].getBackground() == TeamColor &&
pan[x - 1][y - 1].getBackground() == TeamColor &&
pan[x - 1][y].getBackground() == TeamColor &&
pan[x - 1][y + 1].getBackground() == TeamColor &&
pan[x][y + 1].getBackground() == TeamColor) {
// do something
}
The goal is to check every item (in a 2d array) around the current x and y values and make sure they are the correct color.
I assume there is a simple way to do such. I would assume creating a for loop would solve the problem by iterating through each item but unfortunately was not able to think of a way to do this because the items are not all in sequence.
NOTE: i found many other posts on stackoverflow that where titled "solution for very long if statement" unfortunately they were in different programing languages (such as python, android and javascript)
NOTE 2: this is Not a duplicate of this post. It was a question of strings and regex and unfortunately not the solution to my problem
Hopefully someone will have an answer!
Try something like this:
boolean match = true;
for (int dx = -1; match && (dx < 2); ++dx) {
for (int dy = -1; match && (dy < 2); ++dy) {
if (dx != 0 || dy != 0) {
match = pan[x+dx][y+dy].getBackground() == TeamColour;
}
}
}
if (match) {
// do something
}
Basically, you want to check offsets -1, 0 and 1 in each direction, so we have two for loops, each producing those offsets in one dimension. We then check the array element corresponding to each offset, and keep track using the match variable.
Note though that, like the original code, this will fail near boundaries (e.g. if x == 0). This can be fixed if necessary.
It is possible, of course, to instead have the loops run over the actual indices to check (e.g. for (int x2 = x-1; x2 < x+2; ++x)). It's much the same in the end.
for (int a = x-1;a <= x+1;a++)
{
if (a < 0 || a >= pan.length) continue;
for (int b = y-1; b <= y+1; b++)
{
if (b < 0 || b >= pan[a].length) continue;
if (a == x && b == y) continue;
if (pan[a][b].getBackground() != TeamColor)
return false;
}
}
return true;
I can propose two ways :
1) Full object way
You could introduce a custom class Coordinate that holds two values : the x and y coordinates.
Create a List of Coordinate where you had the Coordinate element you want to test and iterate on it to achieve your need.
public class Coordinate{
private final int x;
private final int y;
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public getX(){
return x;
}
public getY(){
return y;
}
}
And you can use it :
List<Coordinate> coordinates = new ArrayList<>();
coordinates.add(new Coordinate(1,1));
coordinates.add(new Coordinate(1,0));
coordinates.add(new Coordinate(1,-1));
coordinates.add(new Coordinate(0,-1));
coordinates.add(new Coordinate(-1,-1));
coordinates.add(new Coordinate(-1,0));
coordinates.add(new Coordinate(-1,1));
coordinates.add(new Coordinate(0,1));
// you can also init them with a loop
boolean isMatched = true;
for (Coordinate coordinate : coordinates){
if (pan[x + coordinate.getX()][y + coordinate.getY()].getBackground() != TeamColor){
isMatched = false;
break;
}
}
The object way is more verbose but it has the advantage to expose rules.
So you can read and change it easily.
Suppose, the rules to check become more complex, it becomes very valuable.
2) Shorter code way
It is the same logical even by inlining values of Coordinate and by ignoring the specific case that you don't want to test (no change case).
boolean isMatched = true;
for (int xDelta = -1; xDelta <=1; xDelta++){
for (int yDelta = -1; yDelta <=1; yDelta++){
// as you don't want to test if no change
if (yDelta == 0 && xDelta ==0){
continue;
}
if (pan[x + xDelta][y + yDelta ].getBackground() != TeamColor){
isMatched = false;
break;
}
}
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
}
I have a problem with array indexing. The code is supposed to move objects of type Ant around a 20x20 grid.
public class Test {
Organism[][] grid = new Organism[20][20];
public static void main(String[] args) {
for (int i = 0; i < 20; i++){
for (int j = 0; j < 20; j++){
if(grid[i][j] instanceof Ant){
int xpos = i;
int ypos = j;
grid[i][j].move(xpos, ypos);
grid[i][j].breed(xpos, ypos);
}
}
}
}
Class Ant extends Organism, class Organism extends Test.
public class Ant extends Organism{
public void move(int xpos, int ypos){
Random rand = new Random();
int direction = rand.nextInt(3);
if(direction == 0){
if(grid[xpos][ypos + 1] == null && xpos <20 && ypos <20)
{
grid[xpos][ypos] = grid[xpos][ypos];
grid[xpos][ypos] = null;
{
}
}
}
The method move is supposed to choose a random direction on the grid and move the Ant there if the adjoining space is empty. It also cannot go outside the 20x20 grid. (There are three more if loops for the other directions).
If I change the sixth line in the move method to:
if(grid[xpos][ypos] == null && xpos <20 && ypos <20)
Then no error is thrown.
I hesitate to post this because its probably a small error on my part but I have been staring at this for several hours.
Assistance is greatly appreciated.
The operands for an && are evaluated from left to right, and the evaluation stops if one of them evaluates to false. So if one or more of the operands are potentially dangerous (such as an array lookup that might go out of bounds), and some of the other operands are supposed to protect against this, the protection operands need to go first. Also, you need to check the indices you're actually using, namely xpos and ypos + 1, and you forgot to use ypos + 1 in the assignment that moves the ant:
if (xpos < 20 && ypos + 1 < 20 && grid[xpos][ypos + 1] == null) {
grid[xpos][ypos + 1] = grid[xpos][ypos];
grid[xpos][ypos] = null;
}
(And, assuming that xpos and ypos are valid indices, you don't need to check xpos.)
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;
}