Search code examples
javaswingfor-loopjbuttontic-tac-toe

Keeping track of JButtons generated in a for loop


I am working on a Java tic-tac-toe game but I'm having trouble keeping track of my JButtons because I'm using a for loop to create 9 buttons:

for(int i=0;i<button.length;i++){           
    button[i] = new JButton();
    button[i].setText(Integer.toString(i+1));
    frame.add(button[i]);
    button[i].addActionListener(this);
}

I want to check if my button text matches (in rows/columns/diagonal) and if so, display that you win.

Here is all my code:

public class TicTacToe extends Board implements ActionListener{
    JButton button[] = new JButton[9];
    boolean win = false;
    int count = 0;
    String letter = "";

    public TicTacToe(){
        //create + add JButtons to JFrame
        for(int i=0;i<button.length;i++){
            button[i] = new JButton();
            button[i].setText(Integer.toString(i+1));
            frame.add(button[i]);
            button[i].addActionListener(this);
        }
    }   

    public void actionPerformed(ActionEvent e) {
        for(int i=0;i<button.length;i++){
            if(i%2 == 0){
                letter = "X";
            }else{
                letter = "O";
            }

            if(e.getSource() == button[i]){
                button[i].setText(letter);
                button[i].setEnabled(false);
                count = i+1;
            }

            //check win
            if(){             //<---------------NEED HELP HERE. THANK YOU
                win = true;
                JOptionPane.showMessageDialog(null, "YOU WIN");
            }
        }
    }
}

How can I keep track of dynamically created JButtons?


Solution

  • The win conditions for tic tac toe are:

    X - -    - X -    - - X
    X - - or - X - or - - X
    X - -    - X -    - - X
    
    private boolean colWinner() {
      for (int i = 0; i < 3; i++) {
        String mark = button[i].getText();
        if (mark.equals(button[i+3].getText()) &&
            mark.equals(button[i+6].getText()) {
          return true;
        }
      }
      return false;
    }
    

    or

    X X X    - - -    - - -
    - - - or X X X or - - -
    - - -    - - -    X X X
    
    private boolean rowWinner() {
      for (int i = 0; i < 3; i++) {
        String mark = button[3*i].getText();
        if (mark.equals(button[3*i+1].getText()) &&
            mark.equals(button[3*i+2].getText()) {
          return true;
        }
      }
      return false;
    }
    

    or

    X - -    - - X
    - X - or - X -
    - - X    X - -
    
    private boolean diagWinner() {
      String mark = button[4].getText();
      return 
        (mark.equals(button[0].getText()) && mark.equals(button[8].getText()) ||
        (mark.equals(button[2].getText()) && mark.equals(button[6].getText());
    }
    

    This naive approach checks all possible win conditions, which isn't really necessary if you are checking for wins after each turn. You only need to check the conditions for:

    1. the row the new mark was made
    2. the col the new mark was made
    3. one diagonal if the mark is in a corner or both diagonals if the mark is in the center.

    I'll leave it to you to figure that out.