56 for (
int i = 0; i < 3; i++) {
57 for (
int j = 0; j < 3; j++) {
63 frame =
new JFrame(
"Tic Tac Toe");
64 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
67 JPanel topPanel =
new JPanel();
68 frame.add(topPanel, BorderLayout.NORTH);
69 welcomeLabel =
new JLabel(
"Enter your player name...");
70 topPanel.add(welcomeLabel);
73 JPanel bottomPanel =
new JPanel();
74 bottomPanel.setLayout(
new GridBagLayout());
75 frame.add(bottomPanel, BorderLayout.SOUTH);
78 JPanel playerNameInputElements =
new JPanel();
79 bottomPanel.add(playerNameInputElements);
80 playerNameInputElements.setLayout(
new GridBagLayout());
83 JLabel playerNameLabel =
new JLabel(
"Enter your name: ");
84 playerNameInputElements.add(playerNameLabel);
87 playerNameField =
new JTextField(20);
88 playerNameInputElements.add(playerNameField);
91 submitButton =
new JButton(
"Submit");
92 playerNameInputElements.add(submitButton);
93 submitButton.addActionListener(
new ActionListener() {
94 public void actionPerformed(ActionEvent event) {
95 playerName = playerNameField.getText().trim();
96 if (playerName.isEmpty()) {
97 JOptionPane.showMessageDialog(frame,
"Name cannot be empty.");
106 GridBagConstraints c =
new GridBagConstraints();
108 bottomPanel.add(timeLabel, c);
111 Timer timer =
new Timer(1000,
new ActionListener() {
112 public void actionPerformed(ActionEvent e) {
119 JMenuBar menuBar =
new JMenuBar();
120 frame.setJMenuBar(menuBar);
123 JMenu controlMenu =
new JMenu(
"Control");
124 menuBar.add(controlMenu);
125 JMenuItem exit =
new JMenuItem(
"Exit");
126 exit.addActionListener(
new ActionListener() {
127 public void actionPerformed(ActionEvent event) {
132 controlMenu.add(exit);
135 JMenu helpMenu =
new JMenu(
"Help");
136 menuBar.add(helpMenu);
137 JMenuItem instruction =
new JMenuItem(
"Instruction");
138 helpMenu.add(instruction);
139 instruction.addActionListener(
new ActionListener() {
140 public void actionPerformed(ActionEvent event) {
141 Object[] options = {
"Okay"};
142 JOptionPane.showOptionDialog(frame,
"Some information about the game:\n\n"
143 +
"Criteria for a valid move:\n"
144 +
"- The move is not occupied by any mark.\n"
145 +
"- The move is made in the player's turn.\n"
146 +
"- The move is made within the 3 x 3 board.\n"
148 +
"The game would continue and switch among the opposite player until it reaches either one of the following conditions:\n"
149 +
"- Player 1 wins.\n"
150 +
"- Player 2 wins.\n"
152 +
"- One of the players leaves the game.",
"Game Information", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, options, options[0]);
157 gameBoard =
new JPanel();
158 frame.add(gameBoard, BorderLayout.CENTER);
159 gameBoard.setLayout(
new GridLayout(3,3));
160 for (
int i = 0; i < 9; i++) {
161 JButton button =
new JButton();
164 button.setBackground(Color.WHITE);
166 button.setEnabled(
false);
167 gameBoard.add(button);
169 final int const_i = i;
170 button.addActionListener(
new ActionListener() {
171 public void actionPerformed(ActionEvent event) {
173 JOptionPane.showMessageDialog(frame,
"Not your turn!");
176 if (!button.getText().equals(
" ")) {
177 JOptionPane.showMessageDialog(frame,
"Cell already occupied!");
181 int row = const_i / 3;
182 int col = const_i % 3;
183 out.println(
"MOVE " + row +
" " + col);
189 scorePanel =
new JPanel();
190 scorePanel.setBorder(BorderFactory.createTitledBorder(
"Score"));
191 frame.add(scorePanel, BorderLayout.EAST);
193 scorePanel.setLayout(
new GridBagLayout());
194 GridBagConstraints c2 =
new GridBagConstraints();
195 c2.anchor = GridBagConstraints.WEST;
196 c2.insets =
new Insets(5,5,5,5);
199 JLabel player1ScoreText =
new JLabel(
"Player 1 Wins:");
202 scorePanel.add(player1ScoreText, c2);
203 player1Score =
new JLabel(
"0");
205 scorePanel.add(player1Score, c2);
208 JLabel player2ScoreText =
new JLabel(
"Player 2 Wins:");
211 scorePanel.add(player2ScoreText, c2);
212 player2Score =
new JLabel(
"0");
214 scorePanel.add(player2Score, c2);
217 JLabel drawScoreText =
new JLabel(
"Draws:");
220 scorePanel.add(drawScoreText, c2);
221 drawScore =
new JLabel(
"0");
223 scorePanel.add(drawScore, c2);
226 frame.setSize(600,600);
227 frame.setVisible(
true);
239 socket =
new Socket(
"127.0.0.1", 8901);
240 in =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
241 out =
new PrintWriter(socket.getOutputStream(),
true);
248 while ((response = in.readLine()) !=
null) {
249 if (response.startsWith(
"SUBMITNAME")) {
251 }
else if (response.startsWith(
"INVALIDNAME")) {
253 SwingUtilities.invokeLater(
new Runnable() {
255 JOptionPane.showMessageDialog(frame,
"Invalid name submitted. Connection closing.");
260 }
else if (response.startsWith(
"NAMEACCEPTED")) {
262 SwingUtilities.invokeLater(
new Runnable() {
264 welcomeLabel.setText(
"WELCOME " + playerName);
265 frame.setTitle(
"Tic Tac Toe - Player: " + playerName.toUpperCase());
268 }
else if (response.startsWith(
"GAMESTART")) {
269 String[] parts = response.split(
" ");
270 if (parts.length >= 3) {
271 String playerXName = parts[1];
272 String playerOName = parts[2];
273 if (mySymbol ==
'\0') {
274 if (playerXName.equals(playerName)) {
276 opponentName = playerOName;
279 opponentName = playerXName;
281 if (mySymbol ==
'X') {
282 welcomeLabel.setText(
"Game started. Now is your turn.");
286 welcomeLabel.setText(
"WELCOME " + playerName);
292 }
else if (response.startsWith(
"MOVE")) {
293 String[] parts = response.split(
" ");
294 if (parts.length != 4)
continue;
295 char symbol = parts[1].charAt(0);
296 int row = Integer.parseInt(parts[2]);
297 int col = Integer.parseInt(parts[3]);
298 SwingUtilities.invokeLater(
new Runnable() {
301 if (symbol != mySymbol) {
302 welcomeLabel.setText(
"Your opponent has moved. Now is your turn.");
306 welcomeLabel.setText(
"Valid move, wait for your opponent.");
312 }
else if (response.startsWith(
"VICTORY")) {
313 SwingUtilities.invokeLater(new Runnable() {
315 int option = JOptionPane.showConfirmDialog(frame,
"Congratulations. You wins! Do you want to play again?",
"Game Over", JOptionPane.YES_NO_OPTION);
316 if (option == JOptionPane.YES_OPTION) {
317 out.println(
"RESET");
322 if (mySymbol ==
'X') {
323 player1Score.setText(Integer.parseInt(player1Score.getText()) + 1 +
"");
325 player2Score.setText(Integer.parseInt(player2Score.getText()) + 1 +
"");
329 }
else if (response.startsWith(
"DEFEAT")) {
330 SwingUtilities.invokeLater(
new Runnable() {
332 int option = JOptionPane.showConfirmDialog(frame,
"You Lose! Do you want to play again?",
"Game Over", JOptionPane.YES_NO_OPTION);
333 if (option == JOptionPane.YES_OPTION) {
334 out.println(
"RESET");
339 if (mySymbol ==
'X') {
340 player2Score.setText(Integer.parseInt(player2Score.getText()) + 1 +
"");
342 player1Score.setText(Integer.parseInt(player1Score.getText()) + 1 +
"");
346 }
else if (response.startsWith(
"TIE")) {
347 SwingUtilities.invokeLater(
new Runnable() {
349 int option = JOptionPane.showConfirmDialog(frame,
"It's a Draw! Do you want to play again?",
"Game Over", JOptionPane.YES_NO_OPTION);
350 if (option == JOptionPane.YES_OPTION) {
351 out.println(
"RESET");
356 drawScore.setText(Integer.parseInt(drawScore.getText()) + 1 +
"");
359 }
else if (response.startsWith(
"YOURMOVE")) {
360 SwingUtilities.invokeLater(
new Runnable() {
362 welcomeLabel.setText(
"Your opponent has moved. Now is your turn.");
367 }
else if (response.startsWith(
"WAIT")) {
368 SwingUtilities.invokeLater(
new Runnable() {
370 welcomeLabel.setText(
"Valid move, wait for your opponent.");
375 }
else if (response.startsWith(
"MESSAGE")) {
376 String msg = response.substring(8);
377 SwingUtilities.invokeLater(
new Runnable() {
379 welcomeLabel.setText(msg);
382 }
else if (response.startsWith(
"INVALID")) {
383 SwingUtilities.invokeLater(
new Runnable() {
385 JOptionPane.showMessageDialog(frame,
"Invalid Move!");
388 }
else if (response.startsWith(
"OTHERLEFT")) {
389 SwingUtilities.invokeLater(
new Runnable() {
391 JOptionPane.showMessageDialog(frame,
"Game Ends. One of the players left.");
392 welcomeLabel.setText(
"Game started. Wait for your opponent.");
397 }
else if (response.startsWith(
"RESET")) {
398 SwingUtilities.invokeLater(
new Runnable() {
403 }
else if (response.startsWith(
"SERVERFULL")) {
404 SwingUtilities.invokeLater(
new Runnable() {
406 JOptionPane.showMessageDialog(frame,
"Server is full. Try again later.");
413 }
catch (IOException e) {
414 System.out.println(
"Connection lost.");
415 SwingUtilities.invokeLater(
new Runnable() {
417 JOptionPane.showMessageDialog(frame,
"Connection to server lost.");
426 }
catch (IOException e) {
427 JOptionPane.showMessageDialog(frame,
"Cannot connect to the server.");