0

Hi I have started to write a console monster game for my A Level CS Class. I have hit a road block because sometimes when I run my game, some objects are not appearing and I have deduced that is due to the objects having the same coordinates. So I have attempted to write a function to check if all of the game objects don't have the same position. All objects have a position (x,y) and the allObjects is a 2d array that I have assigned all of the objects starting positions.

private static boolean checkObjects(int[][] allObjects){
        int upperBound = allObjects.length;
        for(int i = 0; i < upperBound -1 ; i++){
            if(allObjects[i] == allObjects[i+1]){
                return true;
            }
        }
        return false;
    }
user207421
  • 305,947
  • 44
  • 307
  • 483
EpicAshman
  • 23
  • 4
  • I am also trying not to use a massive inefficient else-if statement – EpicAshman Oct 07 '21 at 08:57
  • 3
    Two `int[]` arrays with the same values will not compare equal with `==`. See [Comparing two integer arrays in Java](https://stackoverflow.com/q/14897366/3890632) – khelwood Oct 07 '21 at 09:00
  • @khelwood So in theory would be able to make multiples of the Array.equals() statements to make it work or can I use all of the indexes as parameters at once? – EpicAshman Oct 07 '21 at 09:06
  • Wouldn't it be just better to hold all your _game objects_ in a `List` and before you spawn your object, check if any object already has the position *[x, y]*? – AP11 Oct 07 '21 at 09:09
  • 2
    Your current loop only compares each `allObject` element to the next element. You could use a nested loop to compare every int[] to every other int[] with Arrays.equals(). That's O(N²) unless you want to change your data structure. – khelwood Oct 07 '21 at 09:11

1 Answers1

0

Arrays in java are quite low-level things. You should probably use them here (it's a game, and List<Integer> is vastly less efficient than int[]. Maybe Project Valhalla will change that, but it'll be quite a few years before PV makes it into main java, so that's no solution and probably you can't afford to wait until it is). But, be aware of that.

They are objects. Thus, allObject[i], which returns the int[] at position i, is an object reference, and == between object references just compares the reference.

Imagine a newspaper. I'm the paperboy and I thus have 2 identical newspapers in my hands. I show you both of them and ask you: Hey, are these two equal?

Philosophically, two answers are available, both are equally correct, it's just a matter of perspective:

  • Yes: Both newspapers have the same number of pages and each page has the same letters. They are identical.
  • No: They are two different objects. Had you given me a newspaper right now and then later asked me: Hey, is this newspaper the same one as what I showed you before - then I might say 'yes', but 2 different newspapers clearly aren't identical.

In java, == is like the latter one. Let's see it in practice: (Copy this code over, compile it, run it, play around with it):

int[] a = new int[] {1, 2, 3};
int[] b = new int[] {1, 2, 3};
System.out.println(a == b); // prints false
System.out.println(Arrays.equals(a, b)); // prints true

The utility method equals(int[] a, int[] b) from the java.util.Arrays class will get you the first notion (2 separate int arrays are equal if they are the same size and contain the same int at every position).

Presumably you want Arrays.equals(allObjects[i], allObjects[i + 1]) here.

Also note that your method does this:

  • It goes through each adjacent pair of objects, where 'an object' is defined by an int array. So, if you have [A, B, C, D] where each letter is an int array, your code first compares A/B, then compares B/C, and then compares C/D.
  • The moment it hits a pair that is equal, it returns true.
  • It returns false only if every consecutive pair is non-equal.
  • In particular, if A and B are equal but B and C are not, it still returns true.
  • It never compares A and C.

This doesn't appear to match what you wrote. You said:

So I have attempted to write a function to check if all of the game objects don't have the same position.

If you want to check if all objects are identical, flip the loop around. You want to return false immediately if any consecutive pair is non-equal, and return true; at the end of the loop, which you only get to if every pair-wise comparison concluded: These 2 are equal.

If you want to check merely if any 2 objects are identical, then your code as written doesn't work either. What if A and C are identical, after all?

Doing a cross-cut comparison gets pricey if you have a lot of objects (if you have 100 objects, you need 100+99+98+97+.... comparisons, i.e. 0.5 * n * n objects. The time you need to do this grows squared relative to the number of objects in the system). There are efficient ways to do this, for example, if you can establish a strict sorting order, or using hashmaps. However, int[] is not a suitable data type on its own for such jobs, as int[] does not have a hashCode() implementation that is suitable for this task, and doesn't have an equals() that is suitable either. You'd have to do quite a bit more work.

If you never have more than, say, 1000 objects, a double loop is probably okay.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72