I recently built a simple 2-player Tic-Tac-Toe game in Java! The game runs in the console and lets two players choose between X and O to play a 3x3 grid. It’s a classic, and it was a fun project to practice basic Java concepts like arrays, loops, conditionals, and user input handling.

import java.util.Scanner;

class TicTacToe {
    static Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("Welcome to TicTacToe");
        System.out.println("Two Player Mode 3 X 3");
        System.out.println("Player One may choose: X or O");

        char playerOneInput = scan.next().toUpperCase().charAt(0);
        if (playerOneInput != 'X' && playerOneInput != 'O') {
            System.out.println("Wrong Input sorry");
            scan.close();
            return;
        }

        System.out.println("Player1 has chosen " + playerOneInput);
        char playerTwoInput = playerOneInput == 'X' ? 'O' : 'X';
        System.out.println("Player2 has chosen " + playerTwoInput);
        System.out.println("Who wants to go first X or O");
        char firstChance = scan.next().toUpperCase().charAt(0);
        char currentPlayer = ((firstChance == 'X') || (firstChance == 'O') ? firstChance : playerOneInput);

        playGame(playerOneInput, playerTwoInput, currentPlayer);
        scan.close();
    }

    public static void playGame(char playerOneInput, char playerTwoInput, char currentPlayer) {
        char[][] board = { { '1', '2', '3' }, { '4', '5', '6' }, { '7', '8', '9' } };
        int numberOfChances = 9;
        int currentTurn = 0;
        boolean playerTurn = (currentPlayer == playerOneInput);

        while (currentTurn < numberOfChances) {
            displayBoardToUser(board);
            System.out.println("Fill a Square for player " + (playerTurn ? "1" : "2") + " = " +
                    getCurrentPlayer(playerTurn, playerOneInput, playerTwoInput) + " ==> From 1-9 Digits");

            int square = scan.nextInt();
            if (square < 1 || square > 9) {
                System.out.println("Invalid Input Out of Range. Please Retry Again");
                continue;
            }

            if (!makeMovesInBoard(board, square, getCurrentPlayer(playerTurn, playerOneInput, playerTwoInput))) {
                System.out.println("Square already taken. Try Again");
                continue;
            }

            if (finaliseWinnerFromMoves(board, getCurrentPlayer(playerTurn, playerOneInput, playerTwoInput))) {
                displayBoardToUser(board);
                System.out.println("Player " + (playerTurn ? "1" : "2") + " Wins!");
                return;
            }
            playerTurn = !playerTurn;
            currentTurn++;
        }
        }

        displayBoardToUser(board);
        System.out.println("It's a tie!");
    }

    static void displayBoardToUser(char[][] board) {
        for (int i = 0; i < 3; i++) {
            System.out.println("===========");
            for (int j = 0; j < 3; j++) {
                System.out.print("[" + board[i][j] + "]");
            }
            System.out.println();
        }
        System.out.println("===========");
    }

    public static boolean makeMovesInBoard(char[][] board, int square, char player) {
        int row = (square - 1) / 3;
        int col = (square - 1) % 3;
        if (board[row][col] == 'X' || board[row][col] == 'O') {
            return false;
        }
        board[row][col] = player;
        return true;
    }

    public static boolean finaliseWinnerFromMoves(char[][] checkBoard, char player) {
        for (int i = 0; i < checkBoard.length; i++) {
            if (checkBoard[i][0] == player && checkBoard[i][1] == player && checkBoard[i][2] == player ||
                    checkBoard[0][i] == player && checkBoard[1][i] == player && checkBoard[2][i] == player) {
                return true;
            }
        }
        return (checkBoard[0][0] == player && checkBoard[1][1] == player && checkBoard[2][2] == player) ||
               (checkBoard[0][2] == player && checkBoard[1][1] == player && checkBoard[2][0] == player);
    }

    public static char getCurrentPlayer(boolean playerTurn, char playerOneInput, char playerTwoInput) {
        return playerTurn ? playerOneInput : playerTwoInput;
    }
}