//Tictactoe applet //3rd assignment. added computer player import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.StringTokenizer; public class Tictactoe5 extends JApplet { final static int maxboard=6; final static int N=3; //kludge FIX private CustomPanel drawPanel; private JTextField owinsField, xwinsField, tiesField; private JTextField playField; private Timer gameOverTimer; char[][] B = new char [maxboard][maxboard]; int moves; int numPlayers; char who; boolean gameOver; public void init() { JLabel oLabel, xLabel, tieLabel; JLabel playLabel; JPanel statusPanel; JPanel playPanel; JMenuBar bar; JMenu gameMenu; JMenuItem gameItem; JMenuItem matchItem; JMenuItem exitItem; Container container = getContentPane(); container.setLayout( new BorderLayout(3,3) ); playPanel = new JPanel(); playPanel.setLayout( new FlowLayout() ); playLabel = new JLabel( "Enter row column" ); playPanel.add( playLabel ); playField = new JTextField( "", 6 ); playField.addActionListener( new PlayHandler() ); playPanel.add( playField ); container.add( playPanel, BorderLayout.NORTH ); statusPanel = new JPanel(); statusPanel.setLayout( new GridLayout( 1, 9 ) ); oLabel = new JLabel( "O wins" ); statusPanel.add( oLabel ); owinsField = new JTextField( "0" ); owinsField.setEditable( false ); statusPanel.add( owinsField ); xLabel = new JLabel( "X wins" ); statusPanel.add( xLabel ); xwinsField = new JTextField( "0" ); xwinsField.setEditable( false ); statusPanel.add( xwinsField ); tieLabel = new JLabel( "Ties" ); statusPanel.add( tieLabel ); tiesField = new JTextField( "0" ); tiesField.setEditable( false ); statusPanel.add( tiesField ); container.add( statusPanel, BorderLayout.SOUTH ); drawPanel = new CustomPanel(); container.add( drawPanel, BorderLayout.CENTER ); bar = new JMenuBar(); setJMenuBar( bar ); gameMenu = new JMenu( "Game" ); gameMenu.setMnemonic( 'G' ); bar.add( gameMenu ); gameItem = new JMenuItem( "New game" ); gameItem.setMnemonic( 'n' ); gameMenu.add( gameItem ); gameItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent event ) { newGame(); } } ); matchItem = new JMenuItem( "New match" ); matchItem.setMnemonic( 'm' ); gameMenu.add( matchItem ); matchItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent event ) { xwinsField.setText( "0" ); owinsField.setText( "0" ); tiesField.setText( "0" ); newMatch(); } } ); exitItem = new JMenuItem( "Exit" ); exitItem.setMnemonic( 'x' ); gameMenu.add( exitItem ); exitItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent event ) { stop(); } } ); gameOverTimer = new Timer( 1000, new ActionListener() { public void actionPerformed( ActionEvent event ) { if ( gameOver ) { gameOver = false; newGame(); } } } ); } public void start() { newMatch(); } void newMatch() { xwinsField.setText( "0" ); owinsField.setText( "0" ); tiesField.setText( "0" ); String s = JOptionPane.showInputDialog( "2 people or 1? 2 or [1])" ); if ( s.equals( "2" ) ) { numPlayers = 2; who = 'o'; } else { numPlayers = 1; String first = JOptionPane.showInputDialog( "You are Oh.\n You play first? ([y]es or no)" ); if ( first.equals("") || first.charAt(0)=='y' ) who = 'o'; else who = 'x'; } newGame(); } private void newGame() { for (int i=0; iN || j<1 || j>N ) { err = true; JOptionPane.showMessageDialog(Tictactoe5.this,"Invalid row column. Re-enter.", "Invalid input", JOptionPane.PLAIN_MESSAGE); playField.setText( "" ); } else if ( B[i-1][j-1] != ' ' ) { err = true; JOptionPane.showMessageDialog(Tictactoe5.this,"Already played! Re-enter.", "Invalid input", JOptionPane.PLAIN_MESSAGE); playField.setText( "" ); } else { moves++; playField.setText( "" ); B[i-1][j-1] = who; drawPanel.draw(); gameOver = end_check(); //this if needs to be atomic with the end_check... if (who == 'x') who = 'o'; else who = 'x'; if ( !gameOver && numPlayers==1 ) computerMakesMove(); } } } void computerMakesMove() { int row, col; char otherWho; playField.setEditable( false ); //for really slow computer ;) otherWho = who=='x' ? 'o' : 'x'; //"strategy": //1. win if can int[] winning = new int[2]; //row and col of winning move if ( canWin( winning, who ) ) { row = winning[0]; col = winning[1]; } //2. don't lose else if ( canWin( winning, otherWho ) ) { //if human can win, take his position row = winning[0]; col = winning[1]; } //3. random unplayed one else do { row = (int)(Math.random() * 3); col = (int)(Math.random() * 3); } while ( B[row][col] != ' '); moves++; B[row][col] = who; drawPanel.draw(); gameOver = end_check(); //this if needs to be atomic with the end_check... if (who == 'x') who = 'o'; else who = 'x'; playField.setEditable( true ); playField.requestFocusInWindow(); } public boolean end_check() { String result; if (check_winner()) { if (who == 'x') { result = "Winner is X"; int xwins = Integer.parseInt(xwinsField.getText()); xwins++; xwinsField.setText("" + xwins); } else { result = "Winner is O"; int owins = Integer.parseInt(owinsField.getText()); owins++; owinsField.setText("" + owins); } JOptionPane.showMessageDialog(this,result,"Game decision", JOptionPane.PLAIN_MESSAGE); return true; } else if (moves == N*N) { result = "Draw"; JOptionPane.showMessageDialog(this,result,"Game decision", JOptionPane.PLAIN_MESSAGE); int ties = Integer.parseInt(tiesField.getText()); ties++; tiesField.setText("" + ties); return true; } return false; } public boolean check_winner () { int inseq; //each row for (int i=0; i