0

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?

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your input James, I didn't quite see it through when i wrote the code, You're right that the array would go out of bounds obviously, but I need to compare the values from all positions in the row so it can be e.g.: Position 0 to 3 can be same, 2-5 can be same so I have to make a loop to check all positions.
0

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

6 Comments

Thanks. Since this is a button, I assume I have to write this function outside of the button? I apologise if this question seems dumb, I'm new to Java and learning by myself. And about the if statement, I could just take the boolean value of wl[i][0] and compare that value with every other array element? But since the array goes out of bounds at one time, it still won't work. Is there maybe a workaround which would work with the loop without making a function?
The function is just to make it reusable, you can put it wherever it's accessible to where you need to call it from.
@Ajay_C. I'm not really sure what you mean with the comment "about the if statement, I could just take the boolean value of wl[i][0] and compare that value with every other array element". You can't do a long combined if statement like you originally had - it just won't work, but yes you can reduce the function (see my edited version). You could do my approach (looping) without a function, but a function like this is the Right Thing to do - it is encapsulated and testable, and conveys your intent.
Thank you! I'm understanding it, except one thing. What value does index2 hold? And since I need to if compare 4 values are continuously true in the row, wouldn't this just compare maximum two and throw "WON" out?
@Ajay_C. Your question is changing a lot as we go - or rather, more relevant information is being given as we go - which isn't what SO is designed for. The original question was why your for loop didn't work. If that is now answered you should ask any further queries in a new question. I can answer your first point this time. index2 is the "row" or "col" index whichever you interpret it as. For the second point it does compare the entire row, but you can adapt the function I have given with a nested loop to test continuous ranges of 4 instead of the whole row.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.