Search code examples
javaswingtic-tac-toe

Evaluate the winning states of Tic-Tac-Toe


I want to try to evaluate the winning state in the tic-tac-toe below game.

So what I end up doing normally is trying to use the getText() method on the buttons in a for loop and evaluate for example if cells[0][i].getText() is equal to cells[0][1] and cells[0][2].
Then I see if cells[0][2] aren't blank (so not equal to " ") then that would finish the first row.
The problem is that this doesn't work and I would appreciate if someone provides me with a better alternative to this approach, if there is any.

package tictactoe;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

import javax.swing.JFrame;

public class TicTacToe implements ActionListener
{
   JFrame window;
   static JButton[][]cells=new JButton[3][3];
   boolean playing;
   char turn='X';
        public TicTacToe()
        {
           //SETS UP THE WINDOW
            window=new JFrame("TicTacToe");
            window.setSize(new Dimension(400,400));
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            window.setResizable(false);
            //**********************//
            createCells();

            window.setVisible(true);
        }
public static void main(String[] args) 
{
  new TicTacToe();
}
private void createCells()
{
  window.setLayout(new GridLayout(3,3));
   for(int i=0;i<cells.length;i++)
   {
       for(int j=0;j<cells.length;j++)
       {
           cells[i][j]=new JButton();
           cells[i][j].addActionListener(this);
           window.add(cells[i][j]);
       }
   }
}

@Override
public void actionPerformed(ActionEvent e) 
{
    playing=true;
    JButton _buttonPressed=(JButton)e.getSource();
      while(playing)
      {
          if(turn=='X')
          {
             _buttonPressed.setText("X");
             _buttonPressed.setEnabled(false);
             turn='O';
          }
          else
          {
              _buttonPressed.setText("O");
              _buttonPressed.setEnabled(false);
          }
     }

}
}

Solution

  • I'm not seeing where you are evaluating the winning state, but try removing the infinite loop from the click listener.

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton _buttonPressed = (JButton) e.getSource();
    
        _buttonPressed.setText("" + turn);
        _buttonPressed.setEnabled(false);
        if (turn == 'X') {
            turn = 'O';
        } else {
            turn = 'X';
        }
    }
    

    And these are mostly suggestions, so feel free to ignore this, if you wish.

    Make the TicTacToe class be a JFrame itself - no need to instantiate one.

    public class TicTacToe extends JFrame implements ActionListener {
        private JButton[][] cells = new JButton[3][3];
        private char turn = 'X';
        private boolean playing;
    
        public TicTacToe() {
            setTitle("TicTacToe");
            setSize(new Dimension(400, 400));
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setResizable(false);
            createCells();
            pack();
        }
    

    Secondly, the recommended way to start a Swing app, is on its own thread like so

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TicTacToe ttt = new TicTacToe();
                ttt.setVisible(true);
            }
        });
    }