'How to check if it's a tie in "Tic-Tac-Toe"?

I was following a tutorial and changed the winner check code and it works fine (it was all if statements in the tutorial) but couldn't figure out how to check if it's a tie. I tried a for loop which would increase a count variable according to how many places in the grid is filled but it didnt work well. Also in some games the person gets 2 rounds. e.g. X plays but it doesnt switch to O. Im new to java, we learned python last semester so im sorry if this is a dumb question. (https://codeshare.io/eV4Bwx this is the tutors code to check the winner)


import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;


public class TicTacToe implements ActionListener{

    Random random = new Random();
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JLabel textfield = new JLabel();
    JButton[] buttons = new JButton[9];
    boolean player1_turn;



    TicTacToe(){

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800,800);
        frame.getContentPane().setBackground(new Color(50,50,50));
        frame.setLayout(new BorderLayout());
        frame.setVisible(true);

        textfield.setBackground(new Color(25, 25, 25));
        textfield.setForeground(new Color(40,23,50));
        textfield.setFont(new Font("Ink Free", Font.BOLD,75));
        textfield.setHorizontalAlignment(JLabel.CENTER);
        textfield.setText("Tic-Tac-Toe");
        textfield.setOpaque(true);

        title_panel.setLayout(new BorderLayout());
        title_panel.setBounds(0, 0, 800, 100);

        button_panel.setLayout(new GridLayout(3,3));
        textfield.setBackground(new Color(50, 100, 150));

        for (int i = 0; i < 9; i++){
            buttons[i] = new JButton();
            button_panel.add(buttons[i]);
            buttons[i].setFont(new Font("MV Boli", Font.BOLD,120));
            buttons[i].setFocusable(false);
            buttons[i].addActionListener(this);
        }

        title_panel.add(textfield);
        frame.add(title_panel, BorderLayout.NORTH);
        frame.add(button_panel);


        firstTurn();

        check_x();

    }

    @Override
    public void actionPerformed(ActionEvent e){

        for (int i = 0; i < 9; i++){
            if (e.getSource() == buttons[i]){
                if (player1_turn){
                    if (buttons[i].getText() == ""){
                        buttons[i].setForeground(new Color(25,50,55));
                        buttons[i].setText("X");
                        player1_turn = false;
                        textfield.setText("O turn");
                    }
                }else {
                    if (buttons[i].getText() == ""){
                        buttons[i].setForeground(new Color(55,0,25));
                        buttons[i].setText("O");
                        player1_turn = true;
                        textfield.setText("X turn");
                }
                }
            }
        }

    }

    public void firstTurn(){

        try{
            Thread.sleep(2000);
        } catch (InterruptedException e){
            e.printStackTrace();
        }

        if (random.nextInt(2) == 0){
            player1_turn = true;
            textfield.setText("X turn");
        }else{
            player1_turn = false;
            textfield.setText("O turn");
        }

    }

    public void check_x(){

        int[][] win = {{0,1,2}, {3,4,5}, {6,7,8}, {0,4,8}, {2,4,6}, {0,3,6}, {1,4,7}, {2,5,8}};

        while (true) {

            //Check Y
            boolean t = false;
            for (int i = 0; i < win.length; i++) {

                int q = win[i][0];
                int w = win[i][1];
                int e = win[i][2];

                if ((buttons[q].getText() == "O") && (buttons[w].getText() == "O") && (buttons[e].getText() == "O")) {
                    textfield.setText("O wins");

                    t = true;

                    buttons[q].setBackground(Color.GREEN);
                    buttons[w].setBackground(Color.GREEN);
                    buttons[e].setBackground(Color.GREEN);

                    for(int s=0;s<9;s++) {
                        buttons[s].setEnabled(false);
                    }
                }

            }if(t){break;}

            //Check X
            boolean n = false;
            for (int i = 0; i < win.length; i++) {

                int w = win[i][1];
                int q = win[i][0];
                int e = win[i][2];

                if ((buttons[q].getText() == "X") && (buttons[w].getText() == "X") && (buttons[e].getText() == "X")) {
                    textfield.setText("X wins");

                    n = true;

                    buttons[q].setBackground(Color.GREEN);
                    buttons[w].setBackground(Color.GREEN);
                    buttons[e].setBackground(Color.GREEN);

                    for(int s=0;s<9;s++) {
                        buttons[s].setEnabled(false);
                    }
                }
            }if (n){break;}





}
    }
}



Solution 1:[1]

For good practice, the only thing between your loops different is the X and the O. You could put it in a separate function and call it twice: didWin("X"); didWin("O");

I tried a for loop which would increase a count variable according to how many places in the grid is filled but it didnt work well.

That would exactly be what i do. What did not work?

        private int[][] win = {{0,1,2}, {3,4,5}, {6,7,8}, {0,4,8}, {2,4,6}, {0,3,6}, {1,4,7}, {2,5,8}}; // either can be init like that or filled in constructor

 public void check_x(){


        while (true) {
if(didWin("X") || didWin("O") || isDraw()) break;
}
}

private boolean didWin(string playerToken){
            for (int i = 0; i < win.length; i++) {

                int q = win[i][0];
                int w = win[i][1];
                int e = win[i][2];

                if ((buttons[q].getText().equals(playerToken)) && (buttons[w].getText().equals(playerToken)) && (buttons[e].getText().equals(playerToken))) {

                    endGame(playerToken+" wins"); // more useful to end the game with a separate function, so we can use it for the draw again.
return true;
                }

            }
return false;
}
private void endGame(string message){
                    textfield.setText(message);

                    buttons[q].setBackground(Color.GREEN);
                    buttons[w].setBackground(Color.GREEN);
                    buttons[e].setBackground(Color.GREEN);

                    for(int s=0;s<9;s++) {
                        buttons[s].setEnabled(false);
                    }
}
private boolean isDraw(){
 int usedFields = 0;
 for(int i=0;i<9;i++){
   if(buttons[i].getText().equals("")) usedFields++;
 }
  if( usedFields==9){
   endGame("its a draw");
return true;
  }
return false;
}

If you want, put the whole while(true) away, rename it to checkGameEnd() and call it each time in actionPerformed.

Add another variable player1_symbol and you can change between X and O for player 1 and play more rounds.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cookie