/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* @author 000621812
*/
public class NoughtsAndCrossesGamev2 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
NoughtsAndCrossesGameFrame noughtsAndCrossesGame;
noughtsAndCrossesGame = new NoughtsAndCrossesGameFrame();
noughtsAndCrossesGame.setVisible(true);
}
}
class NoughtsAndCrossesGameFrame extends JFrame {
NoughtsAndCrossesGamePanel gamePanel;
NoughtsAndCrossesButtonPanel buttonPanel;
private ButtonPlayActionHandle playHandler;
private ButtonExitActionHandler exitHandler;
private JButton playButton;
private JButton exitButton;
public NoughtsAndCrossesGameFrame() {
gamePanel = new NoughtsAndCrossesGamePanel();
buttonPanel = new NoughtsAndCrossesButtonPanel();
this.setLayout(new GridLayout(3, 0));
this.setLayout(new FlowLayout());
this.setVisible(true);
this.setTitle("Noughts and Crosses");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(playButton );
this.add(exitButton );
this.add(gamePanel, FlowLayout.LEFT);
this.add(buttonPanel,FlowLayout.LEFT);
this.setSize(145, 145);
this.setVisible(true);
}
/**
* Asks the panel containing the game to reset the game.
*/
private void resetGame() {
//**
//* The button panel
//*/
}
class NoughtsAndCrossesButtonPanel extends JPanel {
/**
* The game panel
*
*/
public NoughtsAndCrossesButtonPanel() {
playButton = new JButton("Play");
playHandler = new ButtonPlayActionHandle();
playButton.addActionListener(playHandler);
exitButton = new JButton("Exit");
exitHandler = new ButtonExitActionHandler();
exitButton.addActionListener(exitHandler);
}
}
}
class NoughtsAndCrossesGamePanel extends JPanel {
private int clickCount = 0;
private JButton[] btnKeypad = new JButton[9];
public NoughtsAndCrossesGamePanel() {
/**
* Resets the buttons and clicjCount ready for a new game
*/
HandlePlayerShot shotHandler = new HandlePlayerShot();
// Set some JFrame details
// NOTE - In grid layout you provide the number of
// rows and columns but columns are ignored and always set equal to rows
// unless the rows are zero.
//TODO
this.setLayout(new BorderLayout());
this.setLayout(new GridLayout(3, 3));
this.setSize(110, 110);
this.setVisible(true);
// Create the buttons and add them to the JFrame
for (int i = 0; i < 9; i++) {
btnKeypad[i] = new JButton(" ");
this.add(btnKeypad[i]);
btnKeypad[i].addActionListener(shotHandler);
//TODO
}
// Register the same listener for each button as the action needed is always the same.
// Note - this could have been done in the above loop but is shown separately here to make
// it clearer.
//shotHandler = new HandlePlayerShot();
this.setSize(200, 200);
}
private void resetGame() {
/**
* Disables all the buttons when the game ends
*
*/
}
private void gameFinished() {
/**
* Inner class of NoughtsAndCrossesGamePanel to handle a players shot
* ie when a game button is pressed.
*
*/
for (int i = 0; i < 9; i++) {
btnKeypad[i].setEnabled(false);
}
}
class HandlePlayerShot implements ActionListener { //TODO implements ????
/**
* Inner class of NoughtsAndCrossesGameFrame to respond to the Exit Button being
* pressed. Dispose of the frame and exits the application
*/
@Override
/**
* Responds to the button press - ie player shot
*/
public void actionPerformed(ActionEvent e) {
JButton currentButton;
String winner;
clickCount++;
currentButton = (JButton) (e.getSource());
// If it is an odd click count (button press count) then it is "X"
// shot as "X" player always goes first
if (clickCount % 2 == 1) {
currentButton.setText("X");
} else {
currentButton.setText("0");
}
currentButton.setEnabled(false);
winner = checkForWinner();
if (winner != null) {
//Display a message showing who the winner is
//TODO
JOptionPane.showMessageDialog(null, "The winner is " + winner);
//NoughtsAndCrossesGamePanel.this.dispose();
} else {
// check that all possible shots have been had
if (clickCount == 9) {
//Display a message saying it is a drawn game
//TODO
//NoughtsAndCrossesGamePanel.this.dispose();
JOptionPane.showMessageDialog(null, "Draw!");
}
}
}
/**
* Checks if the button in btnKeypad array in positions i, j, k
* all have the same text.
* @param i - button number
* @param j - button number
* @param k - button number
* @return true if button i,j,k
*/
private boolean isAWinner(int i, int j, int k) {
return !btnKeypad[i].getText().equals(" ")
&& btnKeypad[i].getText().equals(btnKeypad[j].getText())
&& btnKeypad[i].getText().equals(btnKeypad[k].getText());
}
/**
* Checks for all possible winning scenarios
* @return null if there is no winner or the text on the button of the
* winner
*/
public String checkForWinner() {
/* Assumed mapping of button indexes to position in game is -
* 012
* 345
* 678
*/
int winner = -1; // -1 value means there was no winner
if (isAWinner(0, 1, 2)) {// Horizontal row 1
winner = 0;
} else if (isAWinner(3, 4, 5)) { // Horizontal row 2
winner = 3;
} else if (isAWinner(6, 7, 8)) { // Horizontal row 3
winner = 6;
} else if (isAWinner(0, 3, 6)) { // Vertical row 1
winner = 0;
} else if (isAWinner(1, 4, 7)) { // Vertical row 2
winner = 1;
} else if (isAWinner(2, 5, 8)) { // Vertical row 3
winner = 2;
} else if (isAWinner(0, 4, 8)) { // Diagonal 1
winner = 0;
} else if (isAWinner(2, 4, 6)) { // Diagonal 2
winner = 2;
}
if (winner != -1) {
return btnKeypad[winner].getText();
} else {
return null;
}
}
}
}
class ButtonExitActionHandler implements ActionListener {
/**
* Inner class of NoughtsAndCrossesGameFrame to respond to the Play Button being
* pressed. Asks the frame to reset the game by calling the frames resetGame
* method
*/
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
class ButtonPlayActionHandle implements ActionListener {
public void actionPerformed(ActionEvent e) {
//resetGame();
}
}