The document provides code for a Java tic-tac-toe game that requires completing several "FIX-ME" items. It uses a 2D array to represent the game board and handles player moves by clicking buttons. It needs to add code to check for wins across, vertically, and diagonally. It also needs code for the computer to make random moves until finding an empty space. Resetting the board for new games and pausing the computer's turn are also incomplete.
1. Need help writing the code for a basic java tic tac toe game
// Tic-Tac-Toe: Complete the FIX-ME's to have a working version of Tic-Tac-Toe.
// Note: the basis of the game is a two-dimensional 'board' array, with 3 rows
// and 3 columns. A value of +1 indicates an 'X' on the board; and a value of
// -1 indicates an 'O'
// Group Member names:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.*;
public class TicTacToe implements ActionListener{
// FIX ME #5: set CPU_PAUSE to true when ready to play
final boolean CPU_PAUSE = true; // does the CPU pause to think?
JButton [][] buttons = new JButton[3][3];
int [][] board = new int[3][3];
JLabel status = new JLabel("Player's turn", JLabel.CENTER);
JFrame frame = new JFrame();
JPanel buttonPanel = new JPanel();
JPanel labelPanel = new JPanel();
Timer timer = null;
// draw X or O depending on 'x' values
void refresh(int [][] x) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
2. if (x[i][j] == 1) {
buttons[i][j].setForeground(Color.blue);
buttons[i][j].setText("X");
} else if (x[i][j] == -1) {
buttons[i][j].setForeground(Color.pink);
buttons[i][j].setText("O");
} else {
buttons[i][j].setText(" ");
}
}
}
}
boolean have_winner(int checkVal) {
boolean winner = false;
// FIX ME #1: if there are three 'checkVal' values in-a-row across,
// then set 'winner' to true
// FIX ME #2: if there are three 'checkVal' values in-a-row vertically,
// then set 'winner' to true
int checkSum = 0;
if (checkSum == 3 * checkVal){
winner = true;
}
// FIX ME #3: if there are three 'checkVal' values in-a-row diagonally,
// then set 'winner' to true
return winner;
}
3. boolean playerMove(ActionEvent e) {
JButton btn = (JButton) e.getSource();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (btn.equals(buttons[i][j])) {
if (board[i][j] != 0) {
return false;
}
board[i][j] = 1;
refresh(board);
return true;
}
}
}
return false;
}
boolean board_is_full() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 0) return false;
}
}
return true;
}
ActionListener refreshListener = new ActionListener(){
int delayCount = 0;
public void actionPerformed(ActionEvent event){
delayCount++;
if (delayCount > 5) {
delayCount = 0;
timer.stop();
enableButtons(false);
}
4. if (delayCount % 2 == 0) {
refresh(board);
} else {
int [][] x = new int[3][3];
refresh(x);
}
}
};
void enableButtons(boolean enable) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j].setEnabled(enable);
}
}
}
ActionListener computerMove = new ActionListener(){
public void actionPerformed(ActionEvent event){
/* FIX ME #4: The computer moves by placing an 'O' on the board
* (i.e.), assigning a -1 to a valid element of the board array
* The computer can play randomly, by randomly selecting a
* row and column to play in, and repeating until a valid (empty)
* spot on the board is found. Optionally, the computer can
* play strategically, though this is more challenging.
*/
System.out.println("The computer's move...");
// refresh board and set up for player's move
// DO NOT CHANGE THESE STATEMENTS!
refresh(board);
status.setText("Player's Move");
enableButtons(true);
5. if (have_winner(-1)) {
winning_board(-1);
} else {
status.setText("Player's Move");
}
enableButtons(true);
}
};
ActionListener newGame = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("newGame");
// FIX ME #6: set each value of the 'board' to 0
refresh(board);
enableButtons(true);
status.setText("Player's turn");
status.setForeground(Color.black);
}
};
void winning_board(int val) {
if (val == 1) {
status.setText("PLAYER WINS!");
status.setForeground(Color.blue);
} else if (val == -1) {
status.setText("COMPUTER WINS!");
status.setForeground(Color.pink);
}
timer = new Timer(500, refreshListener);
timer.setRepeats(true);
timer.start();
6. }
ActionListener onClick = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (timer != null && timer.isRunning()) {
timer.stop();
}
int delay = 0;
if (CPU_PAUSE) delay = 1000;
boolean player = playerMove(e);
if (player) {
if (have_winner(1)) {
winning_board(1);
return;
}
else if (board_is_full()) {
status.setText("IT'S A TIE!");
return;
}
status.setText("Computer is thinking...");
enableButtons(false);
Timer timer = new Timer(delay, computerMove);
timer.setRepeats(false);
timer.start();
} else {
System.out.println("No move ");
}
}
};
TicTacToe(){
7. labelPanel.setLayout(new GridLayout(2,3));
for (int i = 0; i < 6; i++) {
if (i!=1) {
labelPanel.add(new JLabel());
} else {
status.setText("Player's move...");
labelPanel.add(status);
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j] = new JButton(" ");
buttons[i][j].setFont(new Font("Arial", Font.BOLD, 50));
buttons[i][j].addActionListener(onClick);
buttonPanel.add(buttons[i][j]);
}
}
buttonPanel.setLayout(new GridLayout(3,3));
frame.setSize(700,300);
frame.add(labelPanel, BorderLayout.SOUTH);
frame.add(buttonPanel, BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Creates a menubar for a JFrame
JMenuBar menuBar = new JMenuBar();
// Define and add two drop down menu to the menubar
JMenu fileMenu = new JMenu("File");
JMenuItem newGameItem = new JMenuItem("New Game");
newGameItem.addActionListener(newGame);
8. fileMenu.add(newGameItem);
menuBar.add(fileMenu);
// Add the menubar to the frame
frame.setJMenuBar(menuBar);
frame.setVisible(true);
refresh(board);
}
public static void main(String[] args) {
new TicTacToe();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Solution
// Tic-Tac-Toe: Complete the FIX-ME's to have a working version of Tic-Tac-Toe.
// Note: the basis of the game is a two-dimensional 'board' array, with 3 rows
// and 3 columns. A value of +1 indicates an 'X' on the board; and a value of
// -1 indicates an 'O'
// Group Member names:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
9. import javax.swing.*;
public class TicTacToe implements ActionListener{
// FIX ME #5: set CPU_PAUSE to true when ready to play
final boolean CPU_PAUSE = true; // does the CPU pause to think?
JButton [][] buttons = new JButton[3][3];
int [][] board = new int[3][3];
JLabel status = new JLabel("Player's turn", JLabel.CENTER);
JFrame frame = new JFrame();
JPanel buttonPanel = new JPanel();
JPanel labelPanel = new JPanel();
Timer timer = null;
// draw X or O depending on 'x' values
void refresh(int [][] x) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (x[i][j] == 1) {
buttons[i][j].setForeground(Color.blue);
buttons[i][j].setText("X");
} else if (x[i][j] == -1) {
buttons[i][j].setForeground(Color.pink);
buttons[i][j].setText("O");
} else {
buttons[i][j].setText(" ");
}
}
}
}
boolean have_winner(int checkVal) {
boolean winner = false;
// FIX ME #1: if there are three 'checkVal' values in-a-row across,
// then set 'winner' to true
for (int i = 0; i < 3; i++) {
if (board[i][0]==checkVal && board[i][1]==checkVal && board[i][2]==checkVal){
winner=true;
10. }
}
// FIX ME #2: if there are three 'checkVal' values in-a-row vertically,
// then set 'winner' to true
for (int i = 0; i < 3; i++) {
if (board[0][i]==checkVal && board[1][i]==checkVal && board[2][i]==checkVal){
winner=true;
}
}
// FIX ME #3: if there are three 'checkVal' values in-a-row diagonally,
// then set 'winner' to true
if (board[0][0]==checkVal && board[1][1]==checkVal && board[2][2]==checkVal){
winner=true;
}
if (board[0][2]==checkVal && board[1][1]==checkVal && board[2][0]==checkVal){
winner=true;
}
return winner;
}
boolean playerMove(ActionEvent e) {
JButton btn = (JButton) e.getSource();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (btn.equals(buttons[i][j])) {
if (board[i][j] != 0) {
return false;
}
board[i][j] = 1;
refresh(board);
return true;
}
}
}
return false;
11. }
boolean board_is_full() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == 0) return false;
}
}
return true;
}
ActionListener refreshListener = new ActionListener(){
int delayCount = 0;
public void actionPerformed(ActionEvent event){
delayCount++;
if (delayCount > 5) {
delayCount = 0;
timer.stop();
enableButtons(false);
}
if (delayCount % 2 == 0) {
refresh(board);
} else {
int [][] x = new int[3][3];
refresh(x);
}
}
};
void enableButtons(boolean enable) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j].setEnabled(enable);
}
}
}
ActionListener computerMove = new ActionListener(){
public void actionPerformed(ActionEvent event){
12. /* FIX ME #4: The computer moves by placing an 'O' on the board
* (i.e.), assigning a -1 to a valid element of the board array
* The computer can play randomly, by randomly selecting a
* row and column to play in, and repeating until a valid (empty)
* spot on the board is found. Optionally, the computer can
* play strategically, though this is more challenging.
*/
mainloop:
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
if(!(board[i][j]==1 || board[i][j]==-1)){
board[i][j] = -1;
buttons[i][j].setForeground(Color.pink);
buttons[i][j].setText("O");
break mainloop;
}
}
}
System.out.println("The computer's move...");
// refresh board and set up for player's move
// DO NOT CHANGE THESE STATEMENTS!
refresh(board);
status.setText("Player's Move");
enableButtons(true);
if (have_winner(-1)) {
winning_board(-1);
} else {
status.setText("Player's Move");
}
enableButtons(true);
}
};
ActionListener newGame = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
13. System.out.println("newGame");
// FIX ME #6: set each value of the 'board' to 0
refresh(board);
enableButtons(true);
status.setText("Player's turn");
status.setForeground(Color.black);
}
};
void winning_board(int val) {
if (val == 1) {
status.setText("PLAYER WINS!");
status.setForeground(Color.blue);
} else if (val == -1) {
status.setText("COMPUTER WINS!");
status.setForeground(Color.pink);
}
timer = new Timer(500, refreshListener);
timer.setRepeats(true);
timer.start();
}
ActionListener onClick = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if (timer != null && timer.isRunning()) {
timer.stop();
}
int delay = 0;
if (CPU_PAUSE) delay = 1000;
boolean player = playerMove(e);
if (player) {
if (have_winner(1)) {
winning_board(1);
return;
}
else if (board_is_full()) {
status.setText("IT'S A TIE!");
14. return;
}
status.setText("Computer is thinking...");
enableButtons(false);
Timer timer = new Timer(delay, computerMove);
timer.setRepeats(false);
timer.start();
} else {
System.out.println("No move ");
}
}
};
TicTacToe(){
labelPanel.setLayout(new GridLayout(2,3));
for (int i = 0; i < 6; i++) {
if (i!=1) {
labelPanel.add(new JLabel());
} else {
status.setText("Player's move...");
labelPanel.add(status);
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j] = new JButton(" ");
buttons[i][j].setFont(new Font("Arial", Font.BOLD, 50));
buttons[i][j].addActionListener(onClick);
buttonPanel.add(buttons[i][j]);
}
}
buttonPanel.setLayout(new GridLayout(3,3));
frame.setSize(700,300);
frame.add(labelPanel, BorderLayout.SOUTH);
frame.add(buttonPanel, BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15. // Creates a menubar for a JFrame
JMenuBar menuBar = new JMenuBar();
// Define and add two drop down menu to the menubar
JMenu fileMenu = new JMenu("File");
JMenuItem newGameItem = new JMenuItem("New Game");
newGameItem.addActionListener(newGame);
fileMenu.add(newGameItem);
menuBar.add(fileMenu);
// Add the menubar to the frame
frame.setJMenuBar(menuBar);
frame.setVisible(true);
refresh(board);
}
public static void main(String[] args) {
new TicTacToe();
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}