import java.awt.*; import java.awt.event.*; public class TicTacMain extends Frame implements WindowListener, ActionListener { // Initialize the board; wait for buttons to be clicked public void init( ) { setLayout( new GridLayout( 3, 3 ) ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { squares[ i ][ j ] = new Button( ); add( squares[ i ][ j ] ); squares[ i ][ j ].addActionListener( this ); } addWindowListener( this ); resetBoard( ); } // Trivial constructor public TicTacMain( ) { init( ); } // Clear the internal board by constructing a new instance // of TicTacToe. Then clear the buttons' labels. public void resetBoard( ) { t = new TicTacToe( ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) { squares[ i ][ j ].setLabel( "" ); squares[ i ][ j ].setEnabled( true ); } } private int gameNum = 0; // Select a move for the computer. // If computer moves first, thinkAboutIt will be false, // and computer's move is picked by viewing gameNum. // This allows testing of the program. public void doCompMove( boolean thinkAboutIt ) { Best compMove; if( thinkAboutIt ) compMove = t.chooseMove( TicTacToe.COMPUTER ); else { compMove = new Best( 0, gameNum % 3, gameNum / 3 ); gameNum = ( gameNum + 1 ) % 9; } System.out.println( " ROW = " + compMove.row + " COL = " + compMove.column ); squares[ compMove.row ][ compMove.column ].setLabel( computerSide ); squares[ compMove.row ][ compMove.column ].setEnabled( false ); t.playMove( TicTacToe.COMPUTER, compMove.row, compMove.column ); } // If game is over, restart a new game, changing sides. public boolean resetIfDone( boolean condition, String message, boolean compMoves ) { if( condition ) { System.out.println( message ); System.out.println( "Restarting..." ); resetBoard( ); if( compMoves ) { System.out.println( "I go first..." ); computerSide = "X"; humanSide = "O"; doCompMove( false ); } else { humanSide = "X"; computerSide = "O"; System.out.println( "You go first..." ); } } return condition; } // Implement the WindowListener interface. public void windowClosing( WindowEvent event ) { System.exit( 0 ); } public void windowClosed( WindowEvent event ) { } public void windowDeiconified( WindowEvent event ) { } public void windowIconified( WindowEvent event ) { } public void windowActivated( WindowEvent event ) { } public void windowDeactivated( WindowEvent event ) { } public void windowOpened( WindowEvent event ) { } // Handle the button click. // Note that the move must be legal, since illegal // moves have had their button's clicking disabled. public void actionPerformed( ActionEvent evt ) { if( evt.getSource( ) instanceof Button ) { ( (Button)evt.getSource( ) ).setLabel( humanSide ); ( (Button)evt.getSource( ) ).setEnabled( false ); for( int i = 0; i < 3; i++ ) for( int j = 0; j < 3; j++ ) if( evt.getSource( ) == squares[ i ][ j ] ) t.playMove( TicTacToe.HUMAN, i, j ); if( resetIfDone( t.boardIsFull( ), "DRAW", true ) ) return; doCompMove( true ); resetIfDone( t.isAWin( TicTacToe.COMPUTER ), "I WIN!!", true ); resetIfDone( t.boardIsFull( ), "DRAW", false ); return; } } // Simple main; setup a board and go public static void main( String [ ] args ) { Frame f = new TicTacMain( ); f.pack( ); f.show( ); } private Button [ ][ ] squares = new Button[ 3 ][ 3 ]; private TicTacToe t; private String computerSide = "O"; private String humanSide = "X"; }