COMP2396
Loading...
Searching...
No Matches
game.java
Go to the documentation of this file.
1import javax.swing.*;
2import javax.swing.plaf.metal.MetalButtonUI;
3import java.awt.*;
4import java.awt.event.*;
5
6/**
7 * A simple Tic Tac Toe game with GUI.
8 * COMP2396 Assignment 4
9 * @author @eric15342335 Cheng Ho Ming, Eric (3036216734)
10 */
11public class game {
12 JFrame frame;
13 JLabel welcomeLabel;
14 JTextField playerNameField;
15 JButton submitButton;
16 JPanel gameBoard;
17 JPanel scorePanel;
18 JLabel playerScore, computerScore, drawScore;
19 enum State {
20 EMPTY, PLAYER, COMPUTER
21 }
22 static State[][] board = new State[3][3];
23 int board_filled = 0;
24 /**
25 * Main method to start the game.
26 * Initialize the game board and GUI.
27 * @param args Does nothing
28 */
29 public static void main(String[] args) {
30 game gui = new game();
31 for (int i = 0; i < 3; i++) {
32 for (int j = 0; j < 3; j++) {
33 board[i][j] = State.EMPTY;
34 }
35 }
36 gui.go();
37 }
38 /**
39 * Initialize the GUI.
40 * Set up the game board, player name input, and score display.
41 * @param void
42 */
43 public void go() {
44 frame = new JFrame("Tic Tac Toe");
45 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
46 // top display
47 // "Enter your player name..." and "WELCOME {NAME}"
48 JPanel topPanel = new JPanel();
49 frame.add(topPanel, BorderLayout.NORTH);
50 welcomeLabel = new JLabel("Enter your player name...");
51 topPanel.add(welcomeLabel);
52 // bottom display with name input and time
53 JPanel bottomPanel = new JPanel();
54 bottomPanel.setLayout(new GridBagLayout());
55 frame.add(bottomPanel, BorderLayout.SOUTH);
56 // player name input: holds text, textfield, and submit button
57 JPanel playerNameInputElements = new JPanel();
58 bottomPanel.add(playerNameInputElements);
59 playerNameInputElements.setLayout(new GridBagLayout());
60 // text
61 JLabel playerNameLabel = new JLabel("Enter your name: ");
62 playerNameInputElements.add(playerNameLabel);
63 // text field for input
64 playerNameField = new JTextField(20);
65 playerNameInputElements.add(playerNameField);
66 // submit button
67 submitButton = new JButton("Submit");
68 playerNameInputElements.add(submitButton);
69 submitButton.addActionListener(new ActionListener() {
70 public void actionPerformed(ActionEvent event) {
71 String input = playerNameField.getText();
72 welcomeLabel.setText("WELCOME " + input.toUpperCase());
73 frame.setTitle("Tic Tac Toe - Player: " + input);
74 // disable
75 playerNameField.setEnabled(false);
76 submitButton.setEnabled(false);
77 // enable all gameboard buttons
78 Component[] components = gameBoard.getComponents();
79 for (Component component : components) {
80 component.setEnabled(true);
81 }
82 }
83 });
84 // time display
85 // get current system time 24 hr format
86 JLabel timeLabel = new JLabel(getLocalTime());
87 GridBagConstraints c = new GridBagConstraints();
88 c.gridy = 1;
89 bottomPanel.add(timeLabel, c);
90 // update time every second
91 Timer timer = new Timer(1000, new ActionListener() {
92 public void actionPerformed(ActionEvent e) {
93 timeLabel.setText(getLocalTime());
94 }
95 });
96 timer.start();
97 // menu bar
98 JMenuBar menuBar = new JMenuBar();
99 frame.setJMenuBar(menuBar);
100 // menu: control
101 JMenu controlMenu = new JMenu("Control");
102 menuBar.add(controlMenu);
103 JMenuItem exit = new JMenuItem("Exit");
104 exit.addActionListener(new ActionListener() {
105 public void actionPerformed(ActionEvent event) {
106 System.exit(0);
107 }
108 });
109 controlMenu.add(exit);
110 // menu: help
111 JMenu helpMenu = new JMenu("Help");
112 menuBar.add(helpMenu);
113 JMenuItem instruction = new JMenuItem("Instruction");
114 helpMenu.add(instruction);
115 instruction.addActionListener(new ActionListener() {
116 public void actionPerformed(ActionEvent event) {
117 Object[] options = {"Yes"};
118 JOptionPane.showOptionDialog(frame, "Some information about the game:\n"
119 + "- The move is not occupied by any mark.\n"
120 + "- The move is made in the player's turn.\n"
121 + "- The move is made within the 3 x 3 board.\n"
122 + "The game would continue and switch among the player and the computer until it reaches either one of the following conditions:\n"
123 + "- Player wins.\n"
124 + "- Computer wins.\n"
125 + "- Draw.", "Instructions", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
126 }
127 });
128 // the 3x3 game board
129 // is actually buttons?
130 gameBoard = new JPanel();
131 frame.add(gameBoard, BorderLayout.CENTER);
132 gameBoard.setLayout(new GridLayout(3,3));
133 for (int i = 0; i < 9; i++) {
134 JButton button = new JButton();
135 button.setText(" ");
136 // white background
137 button.setBackground(Color.WHITE);
138 // no effect when clicked
139 button.setFocusPainted(false);
140 // disable at beginning
141 button.setEnabled(false);
142 gameBoard.add(button);
143 // actual game logic handling
144 final int const_i = i;
145 button.addActionListener(new ActionListener() {
146 public void actionPerformed(ActionEvent event) {
147 // if button is not empty, do nothing
148 if (button.getText().equals("X") || button.getText().equals("O")) {
149 return;
150 }
151 // player's turn
152 button.setText("X");
153 // set bigger text and green
154 button.setFont(new Font("Arial", Font.BOLD, 40));
155 button.setForeground(Color.GREEN);
156 board[const_i / 3][const_i % 3] = State.PLAYER;
157 board_filled++;
158 // computer's turn
159 welcomeLabel.setText("Valid move, waiting for your opponent.");
160 // check if game is over
162 return;
163 }
164 Component[] components = gameBoard.getComponents();
165 // disable all buttons
166 for (Component component : components) {
167 JButton button = (JButton)component;
168 button.setEnabled(false);
169 // set disabled text color to original color
170 button.setUI(new MetalButtonUI() {
171 protected Color getDisabledTextColor() {
172 return button.getForeground();
173 }
174 });
175 }
176 // wait 2 seconds using timer
177 Timer timer = new Timer(2000, new ActionListener() {
178 public void actionPerformed(ActionEvent e) {
179 // find an empty spot by random
180 int x = (int)(Math.random() * 3);
181 int y = (int)(Math.random() * 3);
182 while (board[x][y] != State.EMPTY && board_filled < 9) {
183 x = (int)(Math.random() * 3);
184 y = (int)(Math.random() * 3);
185 }
186 board[x][y] = State.COMPUTER;
187 board_filled++;
188 // update the button
189 int index = x * 3 + y;
190 JButton computerButton = (JButton)components[index];
191 computerButton.setText("O");
192 computerButton.setFont(new Font("Arial", Font.BOLD, 40));
193 computerButton.setForeground(Color.RED);
194 // enable all buttons
195 for (Component component : components) {
196 component.setEnabled(true);
197 }
198 // update top message
199 welcomeLabel.setText("Your opponent has moved, now is your turn.");
200 // check if game is over
201 endGameCheck();
202 }
203 });
204 timer.setRepeats(false);
205 timer.start();
206 }
207 });
208 }
209 // score display on the right
210 scorePanel = new JPanel();
211 scorePanel.setBorder(BorderFactory.createTitledBorder("Score"));
212 frame.add(scorePanel, BorderLayout.EAST);
213 // labels inside the score panel
214 scorePanel.setLayout(new GridBagLayout());
215 GridBagConstraints c2 = new GridBagConstraints();
216 c2.anchor = GridBagConstraints.WEST;
217 c2.ipadx = 30;
218 c2.ipady = 80;
219 // player score
220 JLabel playerScoreText = new JLabel("Player Wins:");
221 c2.gridy = 0;
222 scorePanel.add(playerScoreText, c2);
223 playerScore = new JLabel("0");
224 c2.gridx = 1;
225 scorePanel.add(playerScore, c2);
226 // computer score
227 JLabel computerScoreText = new JLabel("Computer Wins:");
228 c2.gridx = 0;
229 c2.gridy = 1;
230 scorePanel.add(computerScoreText, c2);
231 computerScore = new JLabel("0");
232 c2.gridx = 1;
233 scorePanel.add(computerScore, c2);
234 // draw score
235 JLabel drawScoreText = new JLabel("Draws:");
236 c2.gridx = 0;
237 c2.gridy = 2;
238 scorePanel.add(drawScoreText, c2);
239 drawScore = new JLabel("0");
240 c2.gridx = 1;
241 scorePanel.add(drawScore, c2);
242 // launch the gui
243 frame.setSize(500,500);
244 frame.setVisible(true);
245 }
246 /**
247 * Get the current system time in 24 hour format.
248 * Truncate the miliseconds precision.
249 * @return String of the current time in HH:mm:ss format, e.g. "Current Time: 12:34:56"
250 */
251 private String getLocalTime() {
252 return "Current Time: " + java.time.LocalTime.now().format(java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss"));
253 }
255 PLAYER_WIN, COMPUTER_WIN, DRAW, CONTINUE
257 /**
258 * Responsible for popping a dialog box when the game ends.
259 * Also updates the score display.
260 * Otherwise, return END_GAME_STATUS.CONTINUE.
261 * @return END_GAME_STATUS.PLAYER_WIN if player wins, END_GAME_STATUS.COMPUTER_WIN if computer wins, END_GAME_STATUS.DRAW if draw, END_GAME_STATUS.CONTINUE if game continues
262 */
264 END_GAME_STATUS status = checkWin();
265 String message_delivered = "";
266 if (status == END_GAME_STATUS.PLAYER_WIN) {
267 message_delivered = "Player wins!";
268 playerScore.setText(Integer.parseInt(playerScore.getText()) + 1 + "");
269 } else if (status == END_GAME_STATUS.COMPUTER_WIN) {
270 message_delivered = "Computer wins!";
271 computerScore.setText(Integer.parseInt(computerScore.getText()) + 1 + "");
272 } else if (status == END_GAME_STATUS.DRAW) {
273 message_delivered = "It's a draw!";
274 drawScore.setText(Integer.parseInt(drawScore.getText()) + 1 + "");
275 } else {
277 }
278 Object[] options = {"Yes"};
279 JOptionPane.showOptionDialog(frame, message_delivered, "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
280 // reset the game
281 for (int i = 0; i < 3; i++) {
282 for (int j = 0; j < 3; j++) {
283 board[i][j] = State.EMPTY;
284 }
285 }
286 board_filled = 0;
287 Component[] components = gameBoard.getComponents();
288 for (Component component : components) {
289 JButton button = (JButton)component;
290 button.setText(" ");
291 }
292 return status;
293 }
294 /**
295 * Check if the game is over by looking at the board[][] array.
296 * @return END_GAME_STATUS.PLAYER_WIN if player wins, END_GAME_STATUS.COMPUTER_WIN if computer wins, END_GAME_STATUS.DRAW if draw, END_GAME_STATUS.CONTINUE if game continues
297 */
299 // check rows
300 for (int i = 0; i < 3; i++) {
301 if (board[i][0] == State.PLAYER && board[i][1] == State.PLAYER && board[i][2] == State.PLAYER) {
303 }
304 if (board[i][0] == State.COMPUTER && board[i][1] == State.COMPUTER && board[i][2] == State.COMPUTER) {
306 }
307 }
308 // check columns
309 for (int i = 0; i < 3; i++) {
310 if (board[0][i] == State.PLAYER && board[1][i] == State.PLAYER && board[2][i] == State.PLAYER) {
312 }
313 if (board[0][i] == State.COMPUTER && board[1][i] == State.COMPUTER && board[2][i] == State.COMPUTER) {
315 }
316 }
317 // check diagonals
318 if (board[0][0] == State.PLAYER && board[1][1] == State.PLAYER && board[2][2] == State.PLAYER) {
320 }
321 if (board[0][0] == State.COMPUTER && board[1][1] == State.COMPUTER && board[2][2] == State.COMPUTER) {
323 }
324 if (board[0][2] == State.PLAYER && board[1][1] == State.PLAYER && board[2][0] == State.PLAYER) {
326 }
327 if (board[0][2] == State.COMPUTER && board[1][1] == State.COMPUTER && board[2][0] == State.COMPUTER) {
329 }
330 // check draw
331 if (board_filled == 9) {
332 return END_GAME_STATUS.DRAW;
333 }
335 }
336}
A simple Tic Tac Toe game with GUI.
Definition game.java:11
END_GAME_STATUS checkWin()
Check if the game is over by looking at the board[][] array.
Definition game.java:298
String getLocalTime()
Get the current system time in 24 hour format.
Definition game.java:251
void go()
Initialize the GUI.
Definition game.java:43
END_GAME_STATUS endGameCheck()
Responsible for popping a dialog box when the game ends.
Definition game.java:263
static void main(String[] args)
Main method to start the game.
Definition game.java:29