I don't know what's wrong - java

if(handler.obj.isEmpty())
handler.addObject(new Box(x, y, ID.Box));
else{
for(int i = 0; i < handler.obj.size(); i++){
Object tempObj = handler.obj.get(i);
if (tempObj.getX() == x && tempObj.getY() == y && tempObj.getId() == ID.Box)
handler.removeObect(tempObj);
else
handler.addObject(new Box(x, y, ID.Box));
}
}
the handler.addObject() in the else statement seems unreachable or doesn't work
From comment:
public class Handler {
LinkedList<Object> obj = new LinkedList<Object>();
public void tick(){
for (int i = 0; i < obj.size();i++){
Object tempObj = obj.get(i);
tempObj.tick();
}
}
public void render(Graphics g){
for (int i = 0; i < obj.size(); i++){
Object tempObj = obj.get(i);
tempObj.render(g);
}
}
public void addObject(Object obj){
this.obj.add(obj);
}
public void removeObect(Object obj){
this.obj.remove(obj);
}
}

Let's see. Assume first time it runs, x,y is 1,1. So you add Box(1,1).
Next time is run, let's assume x,y is 2,3. So, enter for loop:
i = 0: Not same x,y, so enter else, and add Box(2,3).
i = 1: Same as x,y (yeah, we just added it), so enter if and remove Box(2,3).
Result: Box added and removed again.
Oh yeah, a debugger would have told you the same thing.

Your problem is that your for loop ends in the wrong place. This causes two undesirable symptoms.
Firstly, you're adding your new Box once for every element in your list that doesn't match the box, instead of adding it just once.
Secondly, you're removing some of those new Box objects that you just added, once you get to the end of the loop.
I would recommend rewriting the method like this. Notice how the for loop ends before the new object is added - this makes sure that the object is added at most once. Also notice the return statement after an object is removed - this can be done because once the object is removed, the method has no more work to do.
public void addOrRemoveBox(int x, int y) {
for(int i = 0; i < handler.obj.size(); i++){
Object tempObj = handler.obj.get(i);
if (tempObj.getX() == x && tempObj.getY() == y && tempObj.getId() == ID.Box) {
handler.removeObect(tempObj);
return;
}
}
handler.addObject(new Box(x, y, ID.Box));
}
Lastly, you appear to have written your own class called Object (otherwise this code wouldn't compile). This is probably a bad idea, because it will cause you to get confused between your Object class, and the Object class that's built into Java. I suggest you rename that class.

Related

" == " change results of getClass()?

I implemented equals() method like this
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
and I test this method using
Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial.equals(initial2));
However, the result is false. I found after the line y == null, the class of y change from Board to string. Why does this happen?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Edit:
Here is a MVCE.
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import java.util.Arrays;
public final class Board {
private int[][] newblocks;
public Board(int[][] blocks) // construct a board from an n-by-n array of newblocks
{
newblocks = new int[blocks.length][blocks.length];
// this.blocks = new int[blocks.length][blocks.length];
for (int i = 0; i < blocks.length; i++)
for (int j = 0; j < blocks.length; j++)
newblocks[i][j] = blocks[i][j];
}
public int dimension() // board dimension n
{ return newblocks.length; }
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
public String toString() // string representation of this board (in the output format specified below)
{
StringBuilder s = new StringBuilder();
s.append(dimension());
s.append("\n");
for (int i = 0; i < dimension(); i++) {
for (int j = 0; j < dimension(); j++) {
s.append(newblocks[i][j]);
s.append("\t");
}
s.append("\n");
}
return s.toString();
}
public static void main(String[] args) // unit tests (not graded)
{
In in = new In(args[0]);
int n = in.readInt();
int[][] newblocks = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
newblocks[i][j] = in.readInt();
Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial);
StdOut.println(initial.equals(initial2));
}
}
The test document is a txt file like
3
1 2 3
0 4 8
7 6 5
The first "3" shows it is a 3x3 matrix, and the next nine numbers belong to the matrix.
I found after the line y == null, the class of y change from Board to string.
I can state categorically that you are wrong about that. What you are describing / proposing is impossible in Java. An object's fundamental type (as returned by this.getClass()) will not change. Not ever1.
What must be going on is that y is not an instance of Board in the first place.
Alternatively, there is a mismatch between the code that you have shown us and reality2.
If you want us to understand / explain what is actually going on, you will need to write an MVCE and share it with us. (And I suspect that the process of doing that will reveal ... to you ... what the real problem is.)
1 - Since y is a local variable, not even a memory visibility anomaly could do this. The only way that this could happen is if you wrote some native code that trampled on object headers from a different thread. If you do that kind of stuff, your JVM is liable to crash horribly.
2 - For example, you could be calling a different overload of equals, OR you could have transcribed or simplified the code incorrectly, OR you could be running a different version of the code.
UPDATE
When I debug your program, it is clear that the code is not returning false at this line:
if (this.getClass() != y.getClass()) return false;
It is actually the call to Arrays.equals that is returning false.
And the reason is that Arrays.equals(Object[], Object[]) does not compare a pair of int[][] objects in the way that you think. (Read the javadoc carefully, thinking about what the elements of the Object[] instances actually are ... and what their equals methods will do.)
Hint: Arrays.equals won't work for what you are trying to do.
The == operator never changes anything, let alone a class.
Your bug hides elsewhere (most likely in code you have not posted).
Arrays.equals() compares each element using equals(). Since, in your case, those elements are themselves arrays, the equality check is failing. The solution is to use Arrays.deepEquals(), which will compare array elements at any depth.

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;
}

NullPointerExceptions on arraylist

I am trying to make a snake-type game in Java.
To do so, I am using lists to keep hold every of the snake's body parts with
ArrayList<SnakeBodyPart> snakeBodyParts = new ArrayList<SnakeBodyPart>();.
I declare and initiate a variable, SnakeBodyPart SnakeBodyPart = null;.
I then add a body part to the snake with snakeBodyParts.add(SnakeBodyPart);.
(Not the most efficient way, I guess, but it'll have to do.)
But for some reason, whenever I run the script, I get
Exception in thread "main" java.lang.NullPointerException,
and that the error is
at game.Snake.<init>(Snake.java:60)
in the Java console.
I want to know what the problem is. Here is the code for the SnakeBodyPart.
class SnakeBodyPart{
int x,y,direction;
void move(){
if(direction == 0){
y -= 50;
}
if(direction == 1){
x += 50;
}
if(direction == 2){
y += 50;
}
if(direction == 3){
x -= 50;
}
}
}
Thanks in advance!
EDIT:
Line 60 is snakeBodyParts.get(0).direction = 0;.
You have done this:
SnakeBodyPart snakeBodyPart = null;
Create the object
SnakeBodyPart snakeBodyPart = new SnakeBodyPart();
Since snakeBodyPart is null, you are getting NullPointerException in Line 60. You are calling get() method on null as snakeBodyParts.get(0).direction = 0;

Getting a NullPointerException when trying to pass an ArrayList to another class

In my current project I have an ArrayList of PVectors that store xyz coordinates for 3d points. I'm passing the ArrayList to another class that manipulates it, however, I'm getting a NullPointerException when doing so. I'm assuming that one of the PVectors is null, but I checked for this by assigning any null objects to (0,0,0) and I'm still getting the error. Also, is it more effecient to have an array of PVectors or an ArrayList of PVectors? Either way I'm still getting the error. Here is the line that produces it.
trip.pass(pointCoordinates);
And here is the main class
import org.openkinect.*;
import org.openkinect.processing.*;
Kinect kinect;
Trip trip;
boolean tripOn;
int w = 640;
int h = 480;
int distance = 5;
float[] depthLookUp = new float[2048];
ArrayList pointCoordinates = new ArrayList();
float factor = 400;
float a = 0;
float angle = 0;
float frequency = .05;
void setup() {
size(800,600,P3D);
kinect = new Kinect(this);
kinect.start();
kinect.enableDepth(true);
kinect.processDepthImage(false);
stroke(255);
for (int i = 0; i < depthLookUp.length; i++) {
depthLookUp[i] = rawDepthToMeters(i);
}
for(int i = 0; i < 31920; i++) {
pointCoordinates.add(new PVector(0, 0, 0));
}
}
void draw() {
background(0);
pushMatrix();
translate(width/2 + width/3,height/2, -200);
//add 1/3 width to account for rule of thirds
popMatrix();
int[] depth = kinect.getRawDepth();
calculate(depth);
if(!tripOn) {
for(int i = 0; i < pointCoordinates.size(); i++) {
PVector temp = (PVector) pointCoordinates.get(i);
point(temp.x, temp.y, temp.z);
}
}
if(frameCount % 10 == 0) {
if(tripOn) {
tripOn = false;
trip.clear();
}
else {
tripOn = true;
trip.pass(pointCoordinates);
}
}
if(tripOn) trip.run();
}
void stop() {
kinect.quit();
super.stop();
}
I can paste more classes if it helps to clarify the problem. Thanks!
You are not initializing your "trip" variable and therefore a call to trip.pass(..) would throw the NullPointerException.
You never seem to assign a value to the variable trip. That would certainly cause a NullPointerException at the line that you've shown.
From your code snippet its hard to get the source of your problem. But my first guess is a threading issue.
You are trying to use the trip.pass(pointCoordinates); in a worker thread. Although it appears that ArrayList pointCoordinates = new ArrayList(); is not part of that thread.
A possible solution could be:
check whether the pointCoordinates is initialized or not. If not then wait for it to get initialized.
Update
My bad. I have missed out the initialization of the trip object. :(
My +1 to Dan Breslau and jerluc

Dealing with ArrayLists in java...all members of the arraylist updating themselves?

I have a function that shrinks the size of a "Food bank" (represented by a rectangle in my GUI) once some of the food has been taken. I have the following function check for this:
public boolean tryToPickUpFood(Ant a)
{
int xCoord = a.getLocation().x;
int yCoord = a.getLocation().y;
for (int i = 0; i < foodPiles.size(); i++)
{
if (foodPiles.get(i).containsPoint(xCoord, yCoord))
{
foodPiles.get(i).decreaseFood();
return true;
}
}
return false;
}
Where decreaseFood shrinks the rectangle..
public void decreaseFood()
{
foodAmount -= 1;
shrinkPile();
}
private void shrinkPile()
{
WIDTH -=1;
HEIGHT = WIDTH;
}
However, whenever one rectangle shrinks, ALL of the rectangles shrink. Why would this be?
edit:
Food piles are being added like such:
addFoodPile(new Food(new Point(200,200)));
addFoodPile(new Food(new Point(400,340)));
public void addFoodPile(Food fp)
{
foodPiles.add(fp);
}
Because the same food pile is in each element of the array? If you are populating it like
FoodPile foodPile = new FoodPile();
for (int i = 0; i < count; i++) {
foodPiles.add(foodPile)
}
you should do this instead:
for (int i = 0; i < count; i++) {
FoodPile foodPile = new FoodPile();
foodPiles.add(foodPile)
}
also, this loop:
for (int i = 0; i < foodPiles.size(); i++)
{
if (foodPiles.get(i).containsPoint(xCoord, yCoord))
{
foodPiles.get(i).decreaseFood();
return true;
}
}
can be more readable if you use foreach syntax:
for (FoodPile foodPile : foodPiles)
{
if (foodPile.containsPoint(xCoord, yCoord))
{
foodPile.decreaseFood();
return true;
}
}
This might be your problem -
private void shrinkPile()
{
WIDTH -=1;
HEIGHT = WIDTH;
}
In the standard Java naming convention, all uppercase names are used for static variables - since you haven't shown their declaration, I can't be sure - but it's certainly suspicious and a place to look.
I'm guessing you thought you were adding lots of separate piles into the List but actually you were adding a reference to the same one over and over. Check that part of your code.
From the code you have shown, it seems like the problem lies in where and how often the tryToPickUpFood() is used. Unless you've used the same reference of foodPiles, as pointed in the other answers

Categories

Resources