# 10 minute Tic Tac Toe

After seeing Snake coded in 10 minutes, I decided to try a similar challenge, albeit easier. The following is Tic Tac Toe that I coded in 10 minutes. Given the short time frame, I'm sure there are style and convention errors abound, and would appreciate any suggestions :)

I will also specifically ask about one thing - checking if there is a winner(done in the only ActionPerformed method). It feels long and convoluted, but it was the best I could think of at the time. Looking back, I still can't really think of any ways to write it better, actually...

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TicTacToe {
private JFrame main;
private TicButton[][] buttons;
private JPanel[] rows;
private boolean p1turn = true;
private final Color bg1 = new Color(255,0,0);
private final Color bg2 = new Color(0,255,0);
public static void main(String[] args) {
new TicTacToe().go();
}
public void go() {
main = new JFrame("Tic Tac Toe!");
buttons = new TicButton[3][3];
rows = new JPanel[3];
int r = 0;
main.getContentPane().setLayout(new BoxLayout(main.getContentPane(),BoxLayout.Y_AXIS));
for (int i = 0; i < 3; i++) {
rows[r] = new JPanel();
for (int j = 0; j < 3; j++) {
buttons[i][j] = new TicButton();
rows[r].add(buttons[i][j]);
}
main.getContentPane().add(rows[r]);
r++;
}
main.pack();
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
}
private class TicButton extends JButton{
int value;
private boolean clicked;
public TicButton() {
super("-");
this.value = -1;
clicked = false;
setFocusable(false);
this.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if (!clicked) {
clicked = true;
setText(p1turn ? "X" : "O");
value = p1turn ? 1 : 2;
setBackground(p1turn ? bg1 : bg2);
p1turn = !p1turn;
setEnabled(false);
}

boolean winner = false;
String win = "";
for (TicButton[] tt : buttons) {
if (tt[0].value == tt[1].value && tt[0].value == tt[2].value && tt[0].value != -1) {
winner = true;
win = tt[0].value == 1 ? "X" : "O";
break;
}
}
for (int j = 0; j < 3; j++) {
if (buttons[0][j].value == buttons[1][j].value &&
buttons[0][j].value == buttons[2][j].value &&
buttons[0][j].value != -1) {
winner = true;
win = buttons[0][j].value == 1 ? "X" : "O";
break;
}
}
if (buttons[0][0].value == buttons[1][1].value && buttons[0][0].value == buttons[2][2].value &&
buttons[0][0].value != -1) {
winner = true;
win = buttons[0][0].value == 1 ? "X" : "O";
}
if (buttons[0][2].value == buttons[1][1].value && buttons[0][2].value == buttons[2][0].value &&
buttons[0][2].value != -1) {
winner = true;
win = buttons[0][2].value == 1 ? "X" : "O";
}
if (winner) {
JOptionPane.showMessageDialog(main, win + " wins!");
main.setVisible(false);
System.exit(0);
}
}
});
}
}

}


## 1 Answer

When it is X’s turn, and they make a move, only player X can win. Similarly, only Y can win on Y’s turn. So why all these tests?

win = tt[0].value == 1 ? "X" : "O";


If there is a winner, just test p1turn in the if (winner) { code!

String win = p1turn ? "X" : "O";


Okay, you may want to move p1turn = !p1turn; to the end of the function, first, to avoid X/O confusion.

This code is checking if the row has all the same symbols, and the symbol is not blank:

if (tt[0].value == tt[1].value && tt[0].value == tt[2].value && tt[0].value != -1) {


When the player moves, this.value is set to their code. And only they can win on this move. So we could instead write:

if (tt[0].value == value && tt[1].value == value && tt[2].value == value) {


Slightly shorter. But we can do better.

Change X’s & O’s values to +1 and -1. Use 0 for blank. Then, if a row sums to +3 or -3, you have a winner!

if (tt[0].value + tt[1].value + tt[2].value == 3*value) {


Similarly for other winning directions.

• Wow, that last trick is really neat, thanks :) Sep 27 '18 at 12:04