![Tic Tac Toe in Java 5 successful codes](https://darekdari.com/wp-content/uploads/2023/11/YOfan-2-1024x512.png)
Table of Contents
Introduction to Tic Tac Toe in Java
Tic Tac Toe in Java, a timeless game loved by many, takes a new twist in the programming world. As a developer, you’re in for a treat with three exciting Java implementations. In this article, we’ll dive into the codes for a Simple Console-based Tic-Tac-Toe, a JavaFX version, and an advanced version with the Minimax algorithm.
Code 1: Simple Console-based Tic-Tac-Toe in java
Setting the Stage
Before we delve into the code, let’s understand the basics. This example provides a classic console-based Tic-Tac-Toe experience where players take turns entering their moves.
The Java Code
import java.util.Scanner;
public class SimpleTicTacToe {
public static void main(String[] args) {
char[][] board = {
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
};
char currentPlayer = 'X';
Scanner scanner = new Scanner(System.in);
while (true) {
printBoard(board);
System.out.print("Player " + currentPlayer + ", enter your move (row and column): ");
int row = scanner.nextInt();
int col = scanner.nextInt();
if (isValidMove(board, row, col)) {
board[row][col] = currentPlayer;
if (isWinner(board, currentPlayer)) {
printBoard(board);
System.out.println("Player " + currentPlayer + " wins!");
break;
}
if (isBoardFull(board)) {
printBoard(board);
System.out.println("It's a draw!");
break;
}
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
} else {
System.out.println("Invalid move. Try again.");
}
}
scanner.close();
}
private static void printBoard(char[][] board) {
for (char[] row : board) {
for (char cell : row) {
System.out.print(cell + " | ");
}
System.out.println();
System.out.println("---------");
}
}
private static boolean isValidMove(char[][] board, int row, int col) {
return (row >= 0 && row < 3 && col >= 0 && col < 3 && board[row][col] == ' ');
}
private static boolean isWinner(char[][] board, char player) {
// Check rows, columns, and diagonals
for (int i = 0; i < 3; i++) {
if ((board[i][0] == player && board[i][1] == player && board[i][2] == player) ||
(board[0][i] == player && board[1][i] == player && board[2][i] == player) ||
(board[0][0] == player && board[1][1] == player && board[2][2] == player) ||
(board[0][2] == player && board[1][1] == player && board[2][0] == player)) {
return true;
}
}
return false;
}
private static boolean isBoardFull(char[][] board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
return false;
}
}
}
return true;
}
}
Code 2: JavaFX Tic-Tac-Toe
Elevating the Experience with Graphics
JavaFX brings a visual twist to the classic game. The grid is presented in a graphical user interface, making it more engaging for players.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class JavaFX_TicTacToe extends Application {
private char currentPlayer = 'X';
private Button[][] buttons = new Button[3][3];
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
GridPane grid = new GridPane();
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
Button button = new Button();
button.setMinSize(100, 100);
button.setOnAction(e -> handleButtonClick(button));
buttons[row][col] = button;
grid.add(button, col, row);
}
}
Scene scene = new Scene(grid, 300, 300);
primaryStage.setTitle("JavaFX Tic-Tac-Toe");
primaryStage.setScene(scene);
primaryStage.show();
}
private void handleButtonClick(Button button) {
if (button.getText().equals("")) {
button.setText(Character.toString(currentPlayer));
if (isWinner()) {
System.out.println("Player " + currentPlayer + " wins!");
resetGame();
} else if (isBoardFull()) {
System.out.println("It's a draw!");
resetGame();
} else {
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
}
}
private boolean isWinner() {
for (int i = 0; i < 3; i++) {
if (buttons[i][0].getText().equals(Character.toString(currentPlayer)) &&
buttons[i][1].getText().equals(Character.toString(currentPlayer)) &&
buttons[i][2].getText().equals(Character.toString(currentPlayer))) {
return true; // Check rows
}
if (buttons[0][i].getText().equals(Character.toString(currentPlayer)) &&
buttons[1][i].getText().equals(Character.toString(currentPlayer)) &&
buttons[2][i].getText().equals(Character.toString(currentPlayer))) {
return true; // Check columns
}
}
if (buttons[0][0].getText().equals(Character.toString(currentPlayer)) &&
buttons[1][1].getText().equals(Character.toString(currentPlayer)) &&
buttons[2][2].getText().equals(Character.toString(currentPlayer))) {
return true; // Check diagonal (top-left to bottom-right)
}
if (buttons[0][2].getText().equals(Character.toString(currentPlayer)) &&
buttons[1][1].getText().equals(Character.toString(currentPlayer)) &&
buttons[2][0].getText().equals(Character.toString(currentPlayer))) {
return true; // Check diagonal (top-right to bottom-left)
}
return false;
}
private boolean isBoardFull() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (buttons[i][j].getText().equals("")) {
return false;
}
}
}
return true;
}
private void resetGame() {
currentPlayer = 'X';
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j].setText("");
}
}
}
}
Code 3: Tic-Tac-Toe with Minimax Algorithm
Unleashing the Power of AI
Take Tic-Tac-Toe to the next level with the Minimax algorithm. Now, the computer player (‘O’) makes optimal moves, ensuring a challenging game.
import java.util.Scanner;
public class TicTacToeMinimax {
private static char[][] board = {
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
};
private static char currentPlayer = 'X';
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
printBoard();
if (currentPlayer == 'X') {
playerMove(scanner);
} else {
minimaxMove();
}
if (isWinner()) {
printBoard();
System.out.println("Player " + currentPlayer + " wins!");
break;
} else if (isBoardFull()) {
printBoard();
System.out.println("It's a draw!");
break;
}
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
scanner.close();
}
private static void printBoard() {
for (char[] row : board) {
for (char cell : row) {
System.out.print(cell + " | ");
}
System.out.println();
System.out.println("---------");
}
}
private static void playerMove(Scanner scanner) {
System.out.print("Player X, enter your move (row and column): ");
int row = scanner.nextInt();
int col = scanner.nextInt();
if (isValidMove(row, col)) {
board[row][col] = 'X';
} else {
System.out.println("Invalid move. Try again.");
playerMove(scanner);
}
}
private static void minimaxMove() {
int[] bestMove = minimax(0, currentPlayer);
board[bestMove[0]][bestMove[1]] = 'O';
}
private static int[] minimax(int depth, char player) {
int[] bestMove = new int[]{-1, -1};
int bestScore = (player == 'X') ? Integer.MIN_VALUE : Integer.MAX_VALUE;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
board[i][j] = player;
int score = minimaxHelper(depth + 1, (player == 'X') ? 'O' : 'X');
board[i][j] = ' ';
if ((player == 'X' && score > bestScore) || (player == 'O' && score < bestScore)) {
bestScore = score;
bestMove[0] = i;
bestMove[1] = j;
}
}
}
}
return bestMove;
}
private static int minimaxHelper(int depth, char player) {
if (isWinner()) {
return (player == 'X') ? -1 : 1;
} else if (isBoardFull()) {
return 0;
}
int bestScore = (player == 'X') ? Integer.MIN_VALUE : Integer.MAX_VALUE;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
board[i][j] = player;
int score = minimaxHelper(depth + 1, (player == 'X') ? 'O' : 'X');
board[i][j] = ' ';
if ((player == 'X' && score > bestScore) || (player == 'O' && score < bestScore)) {
bestScore = score;
}
}
}
}
return bestScore;
}
private static boolean isValidMove(int row, int col) {
return (row >= 0 && row < 3 && col >= 0 && col < 3 && board[row][col] == ' ');
}
private static boolean isWinner() {
// Check rows, columns, and diagonals
for (int i = 0; i < 3; i++) {
if ((board[i][0] == currentPlayer && board[i][1] == currentPlayer && board[i][2] == currentPlayer) ||
(board[0][i] == currentPlayer && board[1][i] == currentPlayer && board[2][i] == currentPlayer) ||
(board[0][0] == currentPlayer && board[1][1] == currentPlayer && board[2][2] == currentPlayer) ||
(board[0][2] == currentPlayer && board[1][1] == currentPlayer && board[2][0] == currentPlayer)) {
return true;
}
}
return false;
}
private static boolean isBoardFull() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
return false;
}
}
}
return true;
}
}
Code 4: Tic-Tac-Toe with a GUI using Java Swing
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TicTacToeSwing extends JFrame implements ActionListener {
private JButton[][] buttons;
private char currentPlayer = 'X';
public TicTacToeSwing() {
super("Tic-Tac-Toe");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
setLayout(new GridLayout(3, 3));
initializeButtons();
setVisible(true);
}
private void initializeButtons() {
buttons = new JButton[3][3];
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(Font.SANS_SERIF, Font.BOLD, 50));
buttons[i][j].setFocusPainted(false);
buttons[i][j].addActionListener(this);
add(buttons[i][j]);
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
JButton clickedButton = (JButton) e.getSource();
if (clickedButton.getText().equals("")) {
clickedButton.setText(Character.toString(currentPlayer));
if (checkWin() || checkDraw()) {
endGame();
} else {
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
}
}
private boolean checkWin() {
// Check rows, columns, and diagonals
for (int i = 0; i < 3; i++) {
if (checkLine(buttons[i][0], buttons[i][1], buttons[i][2]) ||
checkLine(buttons[0][i], buttons[1][i], buttons[2][i])) {
return true;
}
}
return checkLine(buttons[0][0], buttons[1][1], buttons[2][2]) ||
checkLine(buttons[0][2], buttons[1][1], buttons[2][0]);
}
private boolean checkLine(JButton b1, JButton b2, JButton b3) {
return b1.getText().equals(b2.getText()) && b2.getText().equals(b3.getText()) && !b1.getText().equals("");
}
private boolean checkDraw() {
// Check if all buttons are filled
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (buttons[i][j].getText().equals("")) {
return false;
}
}
}
return true;
}
private void endGame() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
buttons[i][j].setEnabled(false);
}
}
if (checkWin()) {
JOptionPane.showMessageDialog(this, "Player " + currentPlayer + " wins!");
} else {
JOptionPane.showMessageDialog(this, "It's a draw!");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new TicTacToeSwing());
}
}
Code 5: Tic-Tac-Toe with a 3D Array
import java.util.Scanner;
public class TicTacToe3DArray {
private static char[][][] board = {
{
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
},
{
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
},
{
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
}
};
private static char currentPlayer = 'X';
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
printBoard();
System.out.print("Player " + currentPlayer + ", enter your move (layer, row, and column): ");
int layer = scanner.nextInt();
int row = scanner.nextInt();
int col = scanner.nextInt();
if (isValidMove(layer, row, col)) {
board[layer][row][col] = currentPlayer;
if (isWinner()) {
printBoard();
System.out.println("Player " + currentPlayer + " wins!");
break;
} else if (isBoardFull()) {
printBoard();
System.out.println("It's a draw!");
break;
}
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
} else {
System.out.println("Invalid move. Try again.");
}
}
scanner.close();
}
private static void printBoard() {
for (int layer = 0; layer < 3; layer++) {
System.out.println("Layer " + layer);
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
System.out.print(board[layer][row][col] + " | ");
}
System.out.println();
System.out.println("---------");
}
System.out.println();
}
}
private static boolean isValidMove(int layer, int row, int col) {
return (layer >= 0 && layer < 3 && row >= 0 && row < 3 && col >= 0 && col < 3 && board[layer][row][col] == ' ');
}
private static boolean isWinner() {
// Check layers, rows, columns, and diagonals
for (int layer = 0; layer < 3; layer++) {
for (int i = 0; i < 3; i++) {
if ((board[layer][i][0] == currentPlayer && board[layer][i][1] == currentPlayer && board[layer][i][2] == currentPlayer) ||
(board[layer][0][i] == currentPlayer && board[layer][1][i] == currentPlayer && board[layer][2][i] == currentPlayer) ||
(board[layer][0][0] == currentPlayer && board[layer][1][1] == currentPlayer && board[layer][2][2] == currentPlayer) ||
(board[layer][0][2] == currentPlayer && board[layer][1][1] == currentPlayer && board[layer][2][0] == currentPlayer)) {
return true;
}
}
}
return false;
}
private static boolean isBoardFull() {
for (int layer = 0; layer < 3; layer++) {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
if (board[layer][row][col] == ' ') {
return false;
}
}
}
}
return true;
}
}
How to create game in Java?
Whether you prefer the simplicity of the console-based version, the visual appeal of JavaFX, or the strategic challenge of the Minimax algorithm, these Java implementations have something for every developer. So, roll up your sleeves, dive into the code, and unleash the fun of Tic-Tac-Toe!
FAQs
- Can I modify the JavaFX version for a custom look? Absolutely! JavaFX provides extensive customization options for buttons, layouts, and more. Feel free to tailor it to your preferences.
- Is the Minimax algorithm the best for Tic-Tac-Toe AI? The Minimax algorithm is a strong choice, but there are other approaches. It depends on your goals and the complexity you want to add to the game.
- Can I implement these games in other programming languages? While these examples are in Java, the logic can be adapted to other languages with some adjustments.
- How can I make the console-based version more user-friendly? Consider adding clear instructions, highlighting the current player, and providing feedback on invalid moves for a better user experience.
- Are there additional enhancements I can make to these games? Absolutely! Add features like a scoring system, a restart option, or even integrate network play for an extra layer of excitement.
0 Comments