How to use an array in an IF statement? - java

I have created this program where an array of bubble objects will be created in the constructor, and then the bubbles will float accross the canvas and once the bubbles touch each other they will disappear and reveal the words "POP!". My method called noneLeft() should return true if all the bubbles have been popped and then another method called redisplayAll() will be called and the bubbles will reset and redisplay again. However, I am not sure what to write for my if statement to return true once the last bubble has been popped. How do I write down if the last bubble in the array has been popped, then return true. Would I have to use bubbles.length?
public Mover(double width, double height, int numberOfBubbles) {
canvasWidth = width;
canvasHeight = height;
bubbles = new Bubble[numberOfBubbles];
for (int i = 0; i < numberOfBubbles; i ++){
bubbles[i] = new Bubble();
bubbles[i].showBubble(width, height);
}
count = 0;
}
public boolean noneLeft() {
if (bubbles[].isPopped() == true){
return true;
}
return false;
}

The code should be
public boolean noneLeft() {
for (Bubble b : bubbles) {
if (!b.isPopped()) {
return false;
}
}
return true;
}
Iterate over the bubbles and as soon as you find one that has not popped return false since at least one bubble is left.

Related

Is there something wrong with these simple java methods (filling a boolean array, checking if said array is full)

I have to write a program that figures out if certain people can buy certain pieces of land, represented by an array. To do this, I created another boolean array that, from the start, is filled with all falses. When somebody "purchases" that piece of land, this boolean array is filled with "true" in places where the land has been purchased. Hence, if another person would want to buy land where somebody has already done so, my program should know that this land is already taken.
However, I'm encountering problems. Are these methods written OK?
private static boolean IsItFree (boolean [][] boolArray, int y, int x, int h, int w) {
if (!boolArray[y][x]) {
for (int i=0; i<h; i++) {
if (boolArray[y+i][x]) {
return false;
}
}
for (int i=0; i<w; i++) {
if (boolArray [y][x+i]) {
return false;
}
}
return true;
}
return false;
}
private static boolean[][] fillItUp (boolean[][] boolArray, int y, int x, int h, int w) {
for (int i=y; i<y+h; i++) {
for (int j=x; j<x+w; j++) { //mogoce minus 1
boolArray[i][j] = true;
}
}
return boolArray;
}
the "land" is given with y and x variables that indicate array indexes where the land will start. H indicates how many spaces the (always square) piece of land should occupy vertically (down, 1 means only the boolArray [y][x], with no horiz. movement) and W is the same for vertical movement.
This is how I reference this in the main method:
`
...
boolean isFree = isItFree (boolArray, y, x, h, w);
if (free) {
boolArray = fillItUp(boolArray, y, x, h, w);
}
Could the problem be that I'm referencing boolArray in fillItUp, because I'm using it in a static context?
No, your code is not correct.
In your IsItFree you are checking wether or not some fields to be purchased are already purchased. But your current code logic only checks first if the fields along one axis are purchased and then checks the other axis, it does not check a mix of both. Visually your code checks only two sides of the rectangle but misses the other two sides and the inner area:
######
#OOO##
#O####
#O####
######
(no guarantee those are the actual sides which are getting checked in your coordinate system).
A fix for that is easy: you basically already wrote the logic in the fillItUp. Basically do the exact same loops but change the action inside:
private static boolean isItFree (boolean [][] boolArray, int y, int x, int h, int w) {
for (int i=y; i<y+h; i++) {
for (int j=x; j<x+w; j++) {
if (boolArray[i][j]) // already purchased
return false;
}
}
return true;
}
Further notes:
please name the method isItFree (starting with a lower case letter)
no need to return the / an array in the fillItUp method

How do you return a zero if there is nothing in the grid where you checked?

To start things off, I am making a game. You fight on a 3x3 Grid (using a 2 Dimensional-Array), and if the "Lane#" (Lane# = Row + Col) ahead of you is blank then you get a -15% Damage Reduction, and this stacks for every blank lane.
This means if you are on [0][0] then you are in Lane# 0, and therefore, cannot possibly have anyone ahead of you, and you will always take 100% of Damage (this is of course without defense and yadda yadda else that modifies)
And if you are on [2][2] then you are in Lane# 4, and if every lane ahead of you has atleast one space in it taken, then you will take 15*4 = 60, 100-60 = 40% of actual damage.
Now that that is out of the way. I am having difficulty returning 0... I keep getting an Error that says that you cannot return a Void value...
'cannot return a value from method whose result type is void'
public Blanks(int l) { //l = Lane
int x = 0; //The Return
for (int i = 0; i < 6; i++) //The loop
if (l=0){ //Here I keep getting an error saying 'incompatible types'
x = 0;
return x; //Here is the 'cannot return a void value' error
break;
}
if (l>=1){
x++;
}
if (l>=2){
x++;
}
if (l>=3){
x++;
}
if (l>=4){
x++;
}
return x; //for some odd reason, this is also a void value
}
}
I still have yet to add the Checking the Array / Grid part as I am stumped about that one as well.. but another problem, another question.. the actual array itself..
you should modify the method header to public int Blanks(int l) {
and you should remove break; keyword because you return method value before it and will be unreached statement.
In order to return an integer value you have to mention a return type in the method. Also, in the first if statement you have used assignment operator instead of comparing.
Also why you have used break after return. I think you have to do first break and then return in the end.
One more thing to add. Your for loop should contain braces. Only the first if statement will get executed according to your code.
public int Blanks(int l) { //l = Lane
int x = 0; //The Return
for (int i = 0; i < 6; i++) //The loop
if (l==0){ //Here I keep getting an error saying 'incompatible types'
x = 0;
break;
}
if (l>=1){
x++;
}
if (l>=2){
x++;
}
if (l>=3){
x++;
}
if (l>=4){
x++;
}
return x; //for some odd reason, this is also a void value
}
}
I haven't stepped into your logic. Comment if you face any problem after this.
I don't understand why you are using the for loop here, but this is a way to do it:
public int Blanks(int l) {
int x = 0;
for (int i = 0; i < 6; i++)
if (l==0){
x = 0;
}else {
x++;
}
return x;
}
But in case that l==0 your method will return 5;
If you want to return 0 or 1 then you need to remove the for loop
public int Blanks(int l) {
if (l==0) return 0;
else return 1;
}
And the method with true-false:
public boolean Blanks(int l) {
if (l==0) return false;
else return true;
}

3D bin packing algorithm?

I wrote a 3D bin packing algorithm but I am still not sure if it is correct or not.
I did not follow any code or pseudo-code that's why I would like to know if it is an efficient algorithm for the 3D bin packing problem or not.
each container has a length, height and breadth
each item has a length , height and breadth.
This is the code I wrote to pack items one by one without exceeding the container's length, height or breadth:
private double x,y,z=0;
private double[] remainingLength;
private double[] remainingHeight;
private double[] remainingBreadth;
//----initialize the remaining dimensions' arrays
public void init(int n) {
remainingLength=new double[n];
remainingHeight=new double[n];
remainingBreadth=new double[n];
for (int i=0; i<n; i++) {
remainingLength[i]=length;
remainingHeight[i]=height;
remainingBreadth[i]=breadth;
}
}
public boolean put3D(ItemsUnit item, int p,int n) {
init(n);
if(x<length){
if(putL(item,p)) {
packedItems.add(item); // if item fits add it to the packedItems into the container
return true;
}
}
if(y<breadth) {
if(putB(item,p)){
packedItems.add(item); // if item fits add it to the packedItems into the container
return true;
}
}
if(z<height){
if(putH(item,p)){
packedItems.add(item); // if item fits add it to the packedItems into the container
return true;
}
}
return false;
}
public boolean putL(ItemsUnit item, int p) {
//remaining dimensions arrays already initialized in the optimization algorithm
double minRemL=remainingLength[0];
int i=0;
for (int j=0; j<remainingLength.length; j++){
if ((remainingLength[j]!=0)&&(minRemL>=remainingLength[j])&&(remainingLength[j]>=item.getLength())){
i=j; //choosing the item to which we should put the new packed item next to
minRemL=remainingLength[j]; //minimum length left
}else {
return false;
}
}
remainingLength[p]=remainingLength[i]-item.getLength();
remainingBreadth[p]-=item.getBreadth();
remainingHeight[p]-=item.getHeight();
remainingLength[i]=0;
x+=item.getLength(); //increment x
return true;
}
public boolean putB(ItemsUnit item, int p) {
//remaining dimensions arrays already initialized in the optimization algorithm
double minRemB=remainingBreadth[0];
int i=0;
for (int j=0; j<remainingBreadth.length; j++){
if ((remainingBreadth[j]!=0)&&(minRemB>=remainingBreadth[j])&&(remainingBreadth[j]>=item.getBreadth())){
i=j; //choosing the item to which we should put the new packed item next to
minRemB=remainingBreadth[j]; //minimum length left
}
else {
return false;
}
}
remainingBreadth[p]=remainingBreadth[i]-item.getBreadth();
remainingHeight[p]-=item.getHeight();
remainingLength[p]-=item.getLength();
remainingBreadth[i]=0;
y+=item.getBreadth(); //increment y
return true;
}
public boolean putH(ItemsUnit item, int p) {
//remaining dimensions arrays already initialized in the optimization algorithm
double minRemH=remainingHeight[0];
int i=0;
for (int j=0; j<remainingHeight.length; j++){
if ((remainingHeight[j]!=0)&&(minRemH>=remainingHeight[j])&&(remainingHeight[j]>=item.getHeight())){
i=j; //choosing the item to which we should put the new packed item next to
minRemH=remainingHeight[j]; //minimum length left
}
else {
return false;
}
}
remainingHeight[p]=remainingHeight[i]-item.getHeight();
remainingBreadth[p]-=item.getBreadth();
remainingLength[p]-=item.getLength();
remainingHeight[i]=0;
z+=item.getHeight(); //increment z
return true;
}
I tested the algorithm and it worked fine without exceeding the dimensions of the container but I am not fully certain if the code is correct.
Can anyone read the code and tell me if it has a problem somewhere or if it is correct?

Possible reason for ConcurrentModificationException

I know what a ConcurrentModificationException is. I had them before, I solved them before and I can get away with a Iterator.
However, In this case I don't understand why it's being thrown.
public boolean pointOnEdgeBlob(int x, int y, float edgeHitEpsilon) {
init();
for (int i = 0; i < nOfBlobs; i++) {
Blob b = blobs.get(i);
// >>>>>>>>>>>>>>>>>>>>> here it calls the method where it goes wrong
if (b.edgeHit(x, y, edgeHitEpsilon)) return true;
}
return false;
}
Here is the edgeHit method that it in the blob:
public boolean edgeHit(float x, float y, float edgeHitEpsilon) {
// quick test if it's worth it
if (x < getMinX()-edgeHitEpsilon || x > getMaxX()+edgeHitEpsilon || y < getMinY()-edgeHitEpsilon || y > getMaxY()+edgeHitEpsilon) {
return false;
}
// the last one should be connected to the first
// >>>>>>>>>>>>>>> if i comment the part in the for loop then this get's the problem.
PVector pre = cornerVectors.get(cornerVectors.size() -1);
PVector cur;
for (int i = 0; i < cornerVectors.size(); i++) {
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> on this line it throws
cur = cornerVectors.get(i);
if(Blob.onLine(pre, cur, x, y, edgeHitEpsilon)) {
return true;
}
pre = cur;
}
return false;
}
Update:
cornerVectors is a list view:
List<PVector> cornerVectors;
It get's set with:
list.subList(fromIndex, toIndex);
There are no other threats running.
Here is the stack trace:
Exception in thread "Animation Thread"
java.util.ConcurrentModificationException at
java.util.SubList.checkForComodification(AbstractList.java:752) at
java.util.SubList.size(AbstractList.java:625) at
nl.doekewartena.contour.scanner.Blob.edgeHit(Blob.java:229) at
nl.doekewartena.contour.scanner.BlobData.pointOnEdgeBlob(BlobData.java:333)
at
nl.doekewartena.contour.scanner.ContourFinder.scan(ContourFinder.java:555)
at
nl.doekewartena.contour.scanner.ContourFinder.scan(ContourFinder.java:469)
at exclude.T04_ContourFinder.draw(T04_ContourFinder.java:38) at
processing.core.PApplet.handleDraw(PApplet.java:2386) at
processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:240)
at processing.core.PApplet.run(PApplet.java:2256) at
java.lang.Thread.run(Thread.java:695)
Once you do
x = list.subList(fromIndex, toIndex);
the list should not be modified or it will throw CME when accesing x
From the .subList javadocs:
The semantics of the list returned by this method become undefined if
the backing list (i.e., this list) is structurally modified in any way
other than via the returned list. (Structural modifications are those
that change the size of this list, or otherwise perturb it in such a
fashion that iterations in progress may yield incorrect results.)

comparing and creating Point 2D arrays

So i am still trying to get this to work... I need it to tell me with the users position matches the position of one of the walls in the array.
I output all the coordinates into the console and everything looks right except that when they equal it doesn't work. (this has worked before... it seems if i don't create the walls in the loop it will work but once i declare too many walls it seems to quit working(not exactly sure but i set the map without the loop and it didn't work consistently i couldn't figure out a reason..
The GameObject(user).position is Point2D and `setPosition set the posiion,
public class Map {
public ArrayList<Wall> theseWalls = new ArrayList<Wall>();
private boolean isSomethingThere;
public Boolean somethingIsThere(GameObject user){
for(int i = 0; i < theseWalls.size(); i++){
GameObject a = (Wall) theseWalls.get(i);
if( user.returnPosition().equals(a.returnPosition())){
isSomethingThere= true;
} else {
isSomethingThere= false;
}
}
return isSomethingThere;
}
}
so that checks if they hit a wall
and this makes the walls
public void makeWallWE(double starty, double endy, double x ){
double length = endy - starty;
for(int i = 1; i<=(int)length;i++){
Wall Wallie= new Wall();
Wallie.setPosition(x,starty+i);
Wallie.showPosition();
theseWalls.add(Wallie);
}
}
You have:
public Boolean somethingIsThere(GameObject user){
for(int i = 0; i < theseWalls.size(); i++){
GameObject a = (Wall) theseWalls.get(i);
if( user.returnPosition().equals(a.returnPosition())){
isSomethingThere= true;
} else {
isSomethingThere= false;
}
}
return isSomethingThere;
}
Even if the user's position matches one of the walls, you continue checking through the rest of the walls and end up setting isSomethingThere to false. The only time this works is if the last wall in theseWalls is the one that matches.
You'll want to break out of that loop as soon as you find a wall that matches, to avoid resetting isSomethingThere to false when you check walls later in the list that don't match.

Categories

Resources