The emphasis is to show a typical control mechanism that handles the states change between the human player and the computer player. User interface is minimum and no image is used. This program runs as a java Application and SWING is used.
Programming Language: JavaSE 1.6;
IDE used: Eclipse SDK 3.7.0
IDE used: Eclipse SDK 3.7.0
Additional API or Packages: None.
There are only 2 classes in my tictactoe package: Class TicTacToe and Class Board.
(1) Class TicTacToe extends the JFrame class and acts as the main program. See Figure 1 below.
package tictactoe; import javax.swing.*; @SuppressWarnings("serial") public class TicTacToe extends JFrame { public TicTacToe() { add(new Board()); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setTitle("TicTacToe"); setSize(295,240); setLocationRelativeTo(null); setVisible(true); setResizable(false); } public static void main(String[] args) { new TicTacToe(); } }
Fig 1. Class TicTacToe
(2) Class Board extends a JPanel class. It handles the UI (user interface) and the control. Most of the 2D Board Games programming in Java use this structure. (See Figure 2 below)
By using simply JButtons, I handled the flow control in the mouseClicked method. I did not use any image in the UI portion and thus does not need to deal with the paint() method.
package tictactoe; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.*; @SuppressWarnings("serial") public class Board extends JPanel implements MouseListener { private JPanel upperPanel; private JPanel centerPanel; private JLabel label; private JButton startButton; private JButton button[] = new JButton[9]; private String[][] value = new String[][] { {"", "", ""}, {"", "", ""}, {"", "", ""} }; private int[][] winMatrixX = new int[][] { // 8 is correct, not 9 {0,0,0},{1,1,1},{2,2,2},{0,1,2}, {0,1,2},{0,1,2},{0,1,2},{0,1,2} }; private int[][] winMatrixY = new int[][] { {0,1,2},{0,1,2},{0,1,2},{0,0,0}, {1,1,1},{2,2,2},{0,1,2},{2,1,0} }; private boolean startGame = false; private boolean nextMoveIsComputer = false; private String msg; public Board() { setLayout(new BorderLayout()); upperPanel = new JPanel(); startButton = new JButton("Start Game"); startButton.setName("StartButton"); startButton.addMouseListener(this); upperPanel.add(startButton); add(upperPanel,BorderLayout.NORTH); // create an invisible area add(Box.createRigidArea(new Dimension(15, 0)), BorderLayout.WEST); add(Box.createRigidArea(new Dimension(15, 0)), BorderLayout.EAST); msg =" Click Start Button to start the game."; label = new JLabel(msg); add(label, BorderLayout.SOUTH); centerPanel = new JPanel(); centerPanel.setLayout(new GridLayout(3, 3, 0, 0)); add(centerPanel, BorderLayout.CENTER); for (int i = 0; i < 9; i++) { button[i]= new JButton(); centerPanel.add(button[i]); button[i].setName(String.valueOf(i)); button[i].addMouseListener(this); } } private void initGame() { startGame = true; // first click start the game nextMoveIsComputer = false; value = new String[][] { {"", "", ""}, {"", "", ""}, {"", "", ""} }; resetAllButtons(); msg=" Your turn "; label.setText(msg); } private void resetAllButtons() { for (int i = 0; i < 9; i++) { button[i].setText(""); } } private void computerMoveNow() { boolean stillInGame = true; if (nextMoveIsComputer && stillInGame) { decideMove(); } nextMoveIsComputer = false; } private void decideMove() { // Rule 0. Decide winner if ( gameOver() ) return; // Rule 1. Win: If computer player has two O in a row, // play the third to get three in a row. if (value[0][0].equals("") && value[0][1].equals("O") && value[0][2].equals("O")) { value[0][0]="O";button[0].setText("0"); msg=" I won !";label.setText(msg); nextMoveIsComputer=false;startGame=false;return;} if (value[0][0].equals("O") && value[0][1].equals("") && value[0][2].equals("O")) { value[0][1]="O";button[1].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("O") && value[0][1].equals("O") && value[0][2].equals("")) { value[0][2]="O";button[2].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[1][0].equals("") && value[1][1].equals("O") && value[1][2].equals("O")) {value[1][0]="O";button[3].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[1][0].equals("O") && value[1][1].equals("") && value[1][2].equals("O")) {value[1][1]="O";button[4].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[1][0].equals("O") && value[1][1].equals("O") && value[1][2].equals("")) {value[1][2]="O";button[5].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[2][0].equals("") && value[2][1].equals("O") && value[2][2].equals("O")) {value[2][0]="O";button[6].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[2][0].equals("O") && value[2][1].equals("") && value[2][2].equals("O")) {value[2][1]="O";button[7].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[2][0].equals("O") && value[2][1].equals("O") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("") && value[1][0].equals("O") && value[2][0].equals("O")) {value[0][0]="O";button[0].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("O") && value[1][0].equals("") && value[2][0].equals("O")) {value[1][0]="O";button[3].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("O") && value[1][0].equals("O") && value[2][0].equals("")) {value[2][0]="O";button[6].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][1].equals("") && value[1][1].equals("O") && value[2][1].equals("O")) {value[0][1]="O";button[1].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][1].equals("O") && value[1][1].equals("") && value[2][1].equals("O")) {value[1][1]="O";button[4].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][1].equals("O") && value[1][1].equals("O") && value[2][1].equals("")) {value[2][1]="O";button[7].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("") && value[1][2].equals("O") && value[2][2].equals("O")) {value[0][2]="O";button[2].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("O") && value[1][2].equals("") && value[2][2].equals("O")) {value[1][2]="O";button[5].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("O") && value[1][2].equals("O") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("") && value[1][1].equals("O") && value[2][2].equals("O")) {value[0][0]="O";button[0].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("O") && value[1][1].equals("") && value[2][2].equals("O")) {value[1][1]="O";button[4].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][0].equals("O") && value[1][1].equals("O") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("") && value[1][1].equals("O") && value[2][0].equals("O")) {value[0][2]="O";button[2].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("O") && value[1][1].equals("") && value[2][0].equals("O")) {value[1][1]="O";button[4].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } if (value[0][2].equals("O") && value[1][1].equals("O") && value[2][0].equals("")) {value[2][0]="O";button[6].setText("0"); msg=" I won !"; label.setText(msg); nextMoveIsComputer=false; startGame=false; return; } // Rule 2. Block: If the [opponent] has two in a row, // play the third to block them. if (value[0][0].equals("") && value[0][1].equals("X") && value[0][2].equals("X")) {value[0][0]="O";button[0].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[0][1].equals("") && value[0][2].equals("X")) {value[0][1]="O";button[1].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[0][1].equals("X") && value[0][2].equals("")) {value[0][2]="O";button[2].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("") && value[1][1].equals("X") && value[1][2].equals("X")) {value[1][0]="O";button[3].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("X") && value[1][1].equals("") && value[1][2].equals("X")) {value[1][1]="O";button[4].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("X") && value[1][1].equals("X") && value[1][2].equals("")) {value[1][2]="O";button[5].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][0].equals("") && value[2][1].equals("X") && value[2][2].equals("X")) {value[2][0]="O";button[6].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][0].equals("X") && value[2][1].equals("") && value[2][2].equals("X")) {value[2][1]="O";button[7].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][0].equals("X") && value[2][1].equals("X") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("") && value[1][0].equals("X") && value[2][0].equals("X")) {value[0][0]="O";button[0].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[1][0].equals("") && value[2][0].equals("X")) {value[1][0]="O";button[3].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[1][0].equals("X") && value[2][0].equals("")) {value[2][0]="O";button[6].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][1].equals("") && value[1][1].equals("X") && value[2][1].equals("X")) {value[0][1]="O";button[1].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][1].equals("X") && value[1][1].equals("") && value[2][1].equals("X")) {value[1][1]="O";button[4].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][1].equals("X") && value[1][1].equals("X") && value[2][1].equals("")) {value[2][1]="O";button[7].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("") && value[1][2].equals("X") && value[2][2].equals("X")) {value[0][2]="O";button[2].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("X") && value[1][2].equals("") && value[2][2].equals("X")) {value[1][2]="O";button[5].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("X") && value[1][2].equals("X") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("") && value[1][1].equals("X") && value[2][2].equals("X")) {value[0][0]="O";button[0].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[1][1].equals("") && value[2][2].equals("X")) {value[1][1]="O";button[4].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[1][1].equals("X") && value[2][2].equals("")) {value[2][2]="O";button[8].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("") && value[1][1].equals("X") && value[2][0].equals("X")) {value[0][2]="O";button[2].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("X") && value[1][1].equals("") && value[2][0].equals("X")) {value[1][1]="O";button[4].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("X") && value[1][1].equals("X") && value[2][0].equals("")) {value[2][0]="O";button[6].setText("0"); msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } // Rule 3. Fork: Create an opportunity where you can win in two ways. // Rule 4. Block opponent's Fork: // Option 1: Create two in a row to force the opponent into // defending, as long as it doesn't result in them creating // a fork or winning. For example, if "X" has a corner, "O" // has the center, and "X" has the opposite corner as well, // "O" must not play a corner in order to win. (Playing a // corner in this scenario creates a fork for "X" to win.) // Option 2: If there is a configuration where the opponent // can fork, block that fork. // Rule 5. Center: Play the center. if (value[1][1].equals("")) { value[1][1]="O";button[4].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } // Rule 6. Opposite corner: If the opponent is in the // corner, play the opposite corner. if (value[0][0].equals("") && value[2][2].equals("X")) { value[0][0]="O";button[0].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][1].equals("") && value[2][1].equals("X")) { value[0][1]="O";button[1].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("") && value[2][0].equals("X")) { value[0][2]="O";button[2].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("") && value[1][2].equals("X")) { value[1][0]="O";button[3].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("X") && value[1][2].equals("")) { value[1][2]="O";button[5].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("X") && value[2][0].equals("")) { value[2][0]="O";button[6].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][1].equals("X") && value[2][1].equals("")) { value[2][1]="O";button[7].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][0].equals("X") && value[2][2].equals("")) { value[2][2]="O";button[8].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } // Rule 7. Empty corner: Play in a corner square. if (value[0][0].equals("")) { value[0][0]="O";button[0].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[0][2].equals("")) { value[0][2]="O";button[2].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][0].equals("")) { value[2][0]="O";button[6].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][2].equals("")) { value[2][2]="O";button[8].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } // Rule 8. Empty side: Play in a middle square on any of // the 4 sides. if (value[0][1].equals("")) { value[0][1]="O";button[1].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][0].equals("")) { value[1][0]="O";button[3].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[1][2].equals("")) { value[1][2]="O";button[5].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } if (value[2][1].equals("")) { value[2][1]="O";button[7].setText("0");msg=" Your turn"; label.setText(msg); nextMoveIsComputer=false; return; } } private boolean gameOver() { int blank = 0; for (int i = 0; i < 8; i++) { int cross = 0; int nough = 0; for (int j = 0; j < 3; j++) { if (value[winMatrixX[i][j]][winMatrixY[i][j]]=="X" ) { cross++; } else if (value[winMatrixX[i][j]][winMatrixY[i][j]]=="O" ) { nough++; } else blank++; } if (cross == 3) { msg=" You won !"; label.setText(msg); startGame=false; return true; } if (nough == 3) { msg=" I won !"; label.setText(msg); startGame=false; return true; } } if (blank == 0) { msg=" Draw & Game Over!"; label.setText(msg); startGame=false; return true; } return false; } @Override public void mouseClicked(MouseEvent e) { JButton aButton = (JButton) e.getSource(); if (aButton.getName().equalsIgnoreCase(startButton.getName())) { initGame(); } else { if (startGame) { // game starts for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (aButton.getName().equalsIgnoreCase(button[i*3+j].getName())) { if (value[i][j].equals("") ) { value[i][j] = "X"; // computer:O, user: X aButton.setText("X"); nextMoveIsComputer = true; } } } } computerMoveNow(); } // end of inGame } // of else } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } }
Fig 2. Class BoardThe code has not been fully optimized or re-factored sufficiently. It is a working example though.
The is the TicTacToe java program.
No comments:
Post a Comment