I have been making a color-based Tic Tac Toe game using Java Swing and Java AWT and have more or less finished the project, however there is still one problem that needs to be fixed in order to be a proper Tic Tac Toe game. The colors that are supposed to be used is Orange (X) and blue (O), however for some reason even when checking each turn iteration it refuses to switch colors after every click and at this point I am lost. Any help is appreciated
Board.java:
public class Board extends JPanel {
boolean gameRunning = true;
private final JButton[][] grid = new JButton[3][3];
JFrame board;
JPanel panel;
public Board() {
initBoard();
}
private void makePanel() {
panel = new JPanel();
panel.setBackground(Color.lightGray);
panel.setLayout(new GridLayout(3, 3));
setBoard();
board.add(panel);
}
private void initBoard() {
int BOARD_WIDTH = 800;
int BOARD_HEIGHT = 600;
board = new JFrame();
board.setTitle("JTicTacToe");
board.setSize(BOARD_WIDTH, BOARD_HEIGHT);
board.setResizable(false);
board.setLocationRelativeTo(null);
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
makePanel();
board.setVisible(true);
}
private void setBoard() {
//Loop through 2D array
for (int row = 0; row < grid.length; row ) {
for (int col = 0; col < grid[row].length; col ) {
grid[row][col] = new JButton();
grid[row][col].setOpaque(true);
grid[row][col].setBorderPainted(false);
grid[row][col].addActionListener(new ButtonListener());
panel.add(grid[row][col]);
}
}
validate();
}
protected class ButtonListener implements ActionListener {
Color defaultColor = new Color(238,238,238);
protected void check(int moves) {
//Rows
for (int c = 0; c < 3; c ) {
if (!defaultColor.equals(grid[c][0].getBackground()) && grid[c][0].getBackground() == grid[c][1].getBackground() && grid[c][0].getBackground() == grid[c][2].getBackground()) {
gameRunning = false;
JOptionPane.showMessageDialog(null, "Game Over!");
}
}
//Verticals
for (int c = 0; c < 3; c ) {
if (!defaultColor.equals(grid[0][c].getBackground()) && grid[0][c].getBackground() == grid[1][c].getBackground() && grid[0][c].getBackground() == grid[2][c].getBackground()) {
gameRunning = false;
JOptionPane.showMessageDialog(null, "Game Over!");
}
}
//Check diagonals
if (!defaultColor.equals(grid[0][0].getBackground()) && grid[0][0].getBackground() == grid[1][1].getBackground() && grid[0][0].getBackground() == grid[2][2].getBackground()) {
gameRunning = false;
JOptionPane.showMessageDialog(null, "Game Over!");}
if (!defaultColor.equals(grid[0][2].getBackground()) && grid[0][2].getBackground() == grid[1][1].getBackground() && grid[0][2].getBackground() == grid[2][0].getBackground()) {
gameRunning = false;
JOptionPane.showMessageDialog(null, "Game Over!");
}
//Check draw if game goes to 9 moves
if(moves == 9) {
gameRunning = false;
JOptionPane.showMessageDialog(null, "Draw!");
}
}
@Override
public void actionPerformed(ActionEvent e) {
int turns = 0;
if (e.getSource() == grid[0][0]) {
turns ;
if (turns % 2 == 0) {
grid[0][0].setBackground(Color.orange);
check(turns);
} else {
grid[0][0].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[0][1]) {
turns ;
if (turns % 2 == 0) {
grid[0][1].setBackground(Color.orange);
check(turns);
} else {
grid[0][1].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[0][2]) {
turns ;
if (turns % 2 == 0) {
grid[0][2].setBackground(Color.orange);
check(turns);
} else {
grid[0][2].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[1][0]) {
turns ;
if (turns % 2 == 0) {
grid[1][0].setBackground(Color.orange);
check(turns);
} else {
grid[1][0].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[1][1]) {
turns ;
if (turns % 2 == 0) {
grid[1][1].setBackground(Color.orange);
check(turns);
} else {
grid[1][1].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[1][2]) {
turns ;
if (turns % 2 == 0) {
grid[1][2].setBackground(Color.orange);
check(turns);
} else {
grid[1][2].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[2][0]) {
turns ;
if (turns % 2 == 0) {
grid[2][0].setBackground(Color.orange);
check(turns);
} else {
grid[2][0].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[2][1]) {
turns ;
if (turns % 2 == 0) {
grid[2][1].setBackground(Color.orange);
check(turns);
} else {
grid[2][1].setBackground(Color.blue);
check(turns);
}
} else if (e.getSource() == grid[2][2]) {
turns ;
if (turns % 2 == 0) {
grid[2][2].setBackground(Color.orange);
check(turns);
} else {
grid[2][2].setBackground(Color.blue);
check(turns);
}
} else {
JOptionPane.showMessageDialog(null, "Invalid");
}
System.out.println(turns);
}
}
}
CodePudding user response:
If you want to make the code prettier:
The variable
gameRunning
is set but it is never used. You can remove it and the program will still behave the same. Or you can start using it. But just giving it values without using those values is unnecessary work.The variables at the top should be
private
(grid
isprivate
, but egboard
is not)You can use a loop to shorten the
actionPerformed
method (note that I added areturn;
):@Override public void actionPerformed(ActionEvent e) { for (int col = 0; col < 3; col ) { for (int row = 0; row < 3; row ) { if (e.getSource() == grid[col][row]) { turns ; if (turns % 2 == 0) { grid[col][row].setBackground(Color.orange); check(turns); } else { grid[col][row].setBackground(Color.blue); check(turns); } System.out.println(turns); return; } } } JOptionPane.showMessageDialog(null, "Invalid"); }
CodePudding user response:
You set the variable turns
to 0
every time a button is clicked (ie every time actionPerformed
is called). You need to make turns
global (same as eg grid
).