Minimax
Minimax

Reputation: 131

Comparing 2D boolean array values?

I'm making this program which is basically a Connect 4 game. As you can see below, I have a set of set circles c0,c1,c2 etc. and a duplicate circle c0d which spawns on every button click and comes down to an available slot. In the "background" I made a 2d matrix, a boolean array, which helps me decide to tell when the game is won (by having a the same color 4 times in the row. Of course, I have 6 other rows with the same function too but they basically do the same.

Circle c0d = new Circle(64, 32, 32);

    TranslateTransition translate = new TranslateTransition(
            Duration.millis(750), c0d);
    translate.setToX(0);
    FadeTransition fade = new FadeTransition();
    fade.setDuration(Duration.seconds(1));

    GridPane.setConstraints(c0d, 0, 0);
    GridPane.setHalignment(c0d, HPos.CENTER);
    grid.getChildren().add(c0d);
    if (c0.getFill() == Color.YELLOW) {
        c0.setFill(Color.RED);
        c1.setFill(Color.RED);
        c2.setFill(Color.RED);
        c3.setFill(Color.RED);
        c4.setFill(Color.RED);
        c5.setFill(Color.RED);
        c6.setFill(Color.RED);
        c0d.setFill(Color.YELLOW);
        switch (x0) {
        case 0:
            translate.setToY(432);
            x0++;
            wl[5][0] = true;
            break;
        case 1:
            translate.setToY(360);
            x0++;
            wl[4][0] = true;
            break;
        case 2:
            translate.setToY(288);
            x0++;
            wl[3][0] = true;
            break;
        case 3:
            translate.setToY(216);
            x0++;
            wl[2][0] = true;
            break;
        case 4:
            translate.setToY(144);
            x0++;
            wl[1][0] = true;
            break;
        case 5:
            translate.setToY(72);
            x0++;
            wl[0][0] = true;
            butt0.setDisable(true);
            break;
        }
    } else {
        c0.setFill(Color.YELLOW);
        c1.setFill(Color.YELLOW);
        c2.setFill(Color.YELLOW);
        c3.setFill(Color.YELLOW);
        c4.setFill(Color.YELLOW);
        c5.setFill(Color.YELLOW);
        c6.setFill(Color.YELLOW);
        c0d.setFill(Color.RED);
        switch (x0) {
        case 0:
            translate.setToY(432);
            x0++;
            wl[5][0] = false;
            break;
        case 1:
            translate.setToY(360);
            x0++;
            wl[4][0] = false;
            break;
        case 2:
            translate.setToY(288);
            x0++;
            wl[3][0] = false;
            break;
        case 3:
            translate.setToY(216);
            x0++;
            wl[2][0] = false;
            break;
        case 4:
            translate.setToY(144);
            x0++;
            wl[1][0] = false;
            break;
        case 5:
            translate.setToY(72);
            x0++;
            wl[0][0] = false;
            butt0.setDisable(true);
            break;
        }
    }

    for (i = 5; i <= 0; i--) {
        if (wl[i][0] == wl[i - 1][0] == wl[i - 2][0] == wl[i - 3][0]) {
            System.out.println("WON");
            break;
        }

Now as you can see, the last for-loop decides when the game is won by comparing the the positions in a row with each other, if they all are "false" which means RED or true which is YELLOW, WON should be output on the console. It doesn't show for some reason. Am I missing something?

Upvotes: 0

Views: 617

Answers (2)

Andy Brown
Andy Brown

Reputation: 19171

Your for loop never executes as the condition i <= 0 is always false, given that you initialise i with the value 5.

But, even if you fix this, you're going to find a problem with the statement as it doesn't do what you think (and it will throw an ArrayIndexOutOfBoundsException anyway)

if (wl[i][0] == wl[i - 1][0] == wl[i - 2][0] == wl[i - 3][0]) { ...

Even if you fix the ArrayIndexOutOfBoundsException, the only reason it compiles is because wl is a boolean[]. This statement would not compile with any other type of array (e.g. int[][]). This is because it is evaluated as:

if (((wl[i][0] == wl[i - 1][0]) == wl[i - 2][0]) == wl[i - 3][0]) ...

So it actually:

  1. evaluates wl[i][0] == wl[i - 1][0]
  2. takes the boolean result of that comparison and compares it to wl[i - 2][0]
  3. and does this for until it reaches the end of the block

Therefore it isn't actually comparing each element to the next in the way you want. In this way the following statement (slightly different to your array, but the same principle) returns true, even though you want it to return false:

boolean arr[] = {false, false, true}; // note they are not all the same
System.out.println(arr[0] == arr[1] == arr[2]); // outputs true

What you actually want is to check if all elements are the same. I suggest using a function to do this such as:

public static boolean fourInALine(boolean[][] arr, int index2)
{
  for (int j = 0; j <= arr.length - 4; j++) {
    boolean allSame = true;
    boolean firstValue = arr[j][index2];
    for (int i = 1; allSame && i < 4; i++) {
      allSame = (arr[j+i][index2] == firstValue);
    }
    if (allSame) return true;
  }
  return false;
}    ...
// used like:
if (fourInALine(wl, 0)) {
  System.out.println("WON");      
}

Upvotes: 0

James_D
James_D

Reputation: 209684

First, your for loop never executes. You initialize with i=5, and the condition is i <= 0. Since the condition is false on initialization, the loop exits without ever executing.

Second, the condition in the if is not doing what you think it is doing. You need some boolean logic here: you want something along the lines of

if (wl[i][0]==wl[i-1][0] && wl[i-1][0]==wl[i-2][0] && wl[i-2][0]==wl[i-3][0]) {
   // ...
}

The way this is actually evaluated as it stands is that wl[i][0]==wl[i-1][0] is evaluated, and evaluates to true or false. That value is then compared to wl[i-2][0] with the comparison evaluating to true or false. Finally that comparison is then compared to wl[i-3]. So if you had RED, RED, YELLOW, YELLOW (false, false, true, true) it would be true. (false==false is true, so (false==false)==true) is true, etc. Similarly RED, YELLOW, RED, YELLOW would evaluate to true (exercise for the reader...).

Finally, much of the rest of the logic isn't really clear to me. You look like you're trying to iterate from i=5 down to i=0; but then accessing elements i-1, i-2 etc of the array obviously won't work.

Upvotes: 1

Related Questions