Search code examples
javaif-statementnested-loops

Java Nested for loop ( with if statement in inner for loop )


I am trying to create a checkerboard with JavaFX. The rows and columns being determined by the input. The last box must be white. My code works if I start with an odd number but not if I start with an even number. I am not sure what is wrong with the if-else if statement. I have been staring at it for hours. Please help!

package application;    
import javax.swing.JOptionPane;
import javax.swing.JTextField;    
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;    
/** 
    Java FX Hello World using a Label.
 */    
public class VG_CheckerBoard0 extends Application
{  
    int columnIndex, rowIndex;
    boolean nOdd;
    @Override
    public void start(Stage stage)
    {               
        //get n from user
        int n= Integer.parseInt(JOptionPane.showInputDialog("Please input a number to make checkerboard: "));
         //create gridpane
        GridPane gridpane = new GridPane();
        gridpane.setGridLinesVisible(true);

        // Create array of boxes 
        TextField[][] box = new TextField[n][n];             
        //set initial value of nOdd
        if ( n%2 == 0 ){
            nOdd = false;
        System.out.println(nOdd);
        }
        else {
            nOdd = true ;
        System.out.println(nOdd);
        }
        //populate array of boxes, set color and position for each
        for(int c= 0; c<box.length;c++){
             for(int r= 0; r<box.length;r++){
                 box[c][r] = new TextField("x");
                 //System.out.println(box[c][r]);

                     if (nOdd == true){

                         box[c][r].setStyle("-fx-background-color: white;" + "-fx-border-color: black;");

                         //switch for next iteration
                         System.out.println(nOdd + " - inside if true before ");
                         nOdd = false;
                         System.out.println(nOdd + " - inside if true after");
                     }else if (nOdd == false){
                         box[c][r].setStyle("-fx-background-color: black;" + "-fx-border-color: black;");

                        //switch for next iteration
                         System.out.println(nOdd + " + inside if false before");
                         nOdd = true;
                         System.out.println(nOdd + " + inside if false after");
                        }

                 gridpane.add(box[c][r], c, r);

             }//inner
         }//outer   

        // Set label as the root of scene graph.
        Scene scene = new Scene(gridpane);   
        stage.setScene(scene);

        // Set stage title and show the stage.
        stage.setTitle("Checkerboard");
        stage.show();
    }   
    public static void main(String[] args){
        launch(args);
    }        
}

SAMPLE OUTPUT BELOW ( ODD NUMBER WORKS, CHECKERBOARD PATTERN). ODD NUMBER WORKS AS EXPECTED

EVEN NUMBER DOES NOT WORK


Solution

  • What's happening is that since the outer loop is for the columns, and the number is identified as even it will alternate black and white for all the rows in that column but will reset for subsequent columns. So for example

    initial value for nOdd = false
                                c = 0     c = 1 .. the process repeats again
                                |column 0|column 1|column 2|column3
    it's alternating ------>    |black   |black                     nOdd = true
    row-wise            |-->    |white   |white                     nOdd = false
                                |black   |black                     nOdd = true
                                |white   |white                     nOdd = false
    
    nOdd came full circle so it starts back in black again
    

    It works for odd because everything aligns correctly

    initial value for nOdd = true
                                c = 0     c = 1 .. the process repeats again
                                |column 0|column 1|column 2
    it's alternating ------>    |white   |black             nOdd = false
    row-wise            |-->    |black   |white             nOdd = true
                                |white   |black             nOdd = false
    
    nOdd started as true and ended as false so for the next column we get alternating colors
    

    One quick fix is to check if n is indeed even once you've gone through all iterations of the inner loop and then xor the variable nOdd with true (a fancy way to say, "toggle" the value)

        for(int c= 0; c<box.length;c++){
             for(int r= 0; r<box.length;r++){
                 box[c][r] = new TextField("x");
                 //System.out.println(box[c][r]);
    
                     if (nOdd == true){
    
                         box[c][r].setStyle("-fx-background-color: white;" + "-fx-border-color: black;");
    
                         //switch for next iteration
                         System.out.println(nOdd + " - inside if true before ");
                         nOdd = false;
                         System.out.println(nOdd + " - inside if true after");
                     }else if (nOdd == false){
                         box[c][r].setStyle("-fx-background-color: black;" + "-fx-border-color: black;");
    
                        //switch for next iteration
                         System.out.println(nOdd + " + inside if false before");
                         nOdd = true;
                         System.out.println(nOdd + " + inside if false after");
                        }
    
                 gridpane.add(box[c][r], c, r);
    
             }//inner
             if(n % 2 == 0) {
                 nOdd = nOdd ^ true;
             }
         }//outer 
    

    You can also use the indexes r and c to decide the color of the cells. Minor detail, since Java is row-major, it might be better to have r as the outer variable for large n but I'm assuming you don't expect to have huge values for n so don't worry about this too much.