Ask me anything
Ithy Logo
Sign in to save

Full Tic Tac Toe Game

A complete guide and program using PHP, HTML, CSS, and JavaScript

tic tac toe game board on wooden table

Highlights

  • Comprehensive Game Structure: Detailed explanation of front-end and back-end integration.
  • Interactive Gameplay: Dynamic interaction through JavaScript and PHP session management.
  • Enhanced Styling and Responsiveness: User-friendly design with responsive CSS styling.

Project Overview

In this guide, we detail how to build a full Tic Tac Toe game combining PHP, HTML, CSS, and JavaScript. The project involves a front-end interface that provides the grid board and interactive gameplay, whereas PHP is used for managing the game state and session, allowing continuity between moves using server-side logic.

The game logic is implemented in JavaScript to detect the cell that a user clicks, update the board, and check winning conditions or draws. The PHP backend uses sessions to store the current game board and track whose turn it is. This integration facilitates further expansion, such as recording game results or implementing high score tracking.


Project Structure

The project has a clear structure composed of the following files:

File Name Description
index.php Main page rendering the game board and handling PHP session for game state.
style.css CSS styles for designing the Tic Tac Toe grid and overall layout.
script.js JavaScript code for dynamic interactivity and game logic.

Step-by-Step Implementation

1. Creating the Main PHP File (index.php)

PHP Session and Game Logic

The PHP file initializes the session and sets up the game state if it's not already present. It creates an array representing the board with nine positions and a current player variable. When a move is made and received via a POST request, the backend updates the board and checks for a win or a draw.

Below is the code for index.php:

<?php
// Start the session to store game state
session_start();

// Initialize game state if not already set
if (!isset($_SESSION['board'])) {
    $_SESSION['board'] = array_fill(0, 9, '');
    $_SESSION['current_player'] = 'X';
}

// Function to check the winner of the game
function checkWinner($board) {
    $winning_combinations = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6]
    ];
    foreach ($winning_combinations as $combo) {
        if ($board[$combo[0]] && $board[$combo[0]] === $board[$combo[1]] && $board[$combo[1]] === $board[$combo[2]]) {
            return $board[$combo[0]];
        }
    }
    return null;
}

// Process the POST request when a move is made
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_POST['reset']) && $_POST['reset'] === 'true') {
        // Reset the game state and start a new game
        $_SESSION['board'] = array_fill(0, 9, '');
        $_SESSION['current_player'] = 'X';
    } else {
        $position = intval($_POST['position']);
        // Only update if the cell is empty
        if ($_SESSION['board'][$position] === '') {
            $_SESSION['board'][$position] = $_SESSION['current_player'];
            $winner = checkWinner($_SESSION['board']);
            if ($winner) {
                echo json_encode(["winner" => $_SESSION['current_player']]);
                session_destroy();
                exit;
            } elseif (!in_array('', $_SESSION['board'])) {
                echo json_encode(["winner" => "Tie"]);
                session_destroy();
                exit;
            }
            // Toggle turn between X and O
            $_SESSION['current_player'] = ($_SESSION['current_player'] === 'X') ? 'O' : 'X';
        }
    }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Tic Tac Toe</title>
</head>
<body>
  <h1 style="color: #cc9900;">Tic Tac Toe</h1>
  <div id="game-board">
  <?php
    // Generate the 3x3 grid dynamically
    foreach ($_SESSION['board'] as $index => $value) {
        echo "<div class='cell' id='cell-$index' onclick='makeMove($index)'>$value</div>";
    }
  ?>
  </div>
  <h2 id="message" style="color: #388278;"></h2>
  <button id="resetBtn" onclick="resetGame()">Reset Game</button>
  <script src="script.js"></script>
</body>
</html>

2. Styling the Game with CSS (style.css)

Responsive and Attractive Design

The CSS file is responsible for the visual presentation of the Tic Tac Toe grid. The design includes borders, sizing, hover effects, and overall layout to ensure a responsive and appealing interface.

Below is the code for style.css:

/* Style for the overall page */
body {
    font-family: Arial, sans-serif;
    text-align: center;
    background-color: #f2f2f2;
    margin: 0;
    padding: 20px;
}

/* Styling the game board container */
#game-board {
    display: grid;
    grid-template-columns: repeat(3, 100px);
    grid-gap: 10px;
    justify-content: center;
    margin: 20px auto;
}

/* Styling each cell of the grid */
.cell {
    width: 100px;
    height: 100px;
    background-color: #ffffff;
    border: 2px solid #333;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 36px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

/* Hover effect for each cell */
.cell:hover {
    background-color: #e6e6e6;
}

/* Message display styling */
#message {
    margin: 20px;
    font-size: 24px;
}

/* Reset button styling */
button {
    padding: 10px 20px;
    font-size: 18px;
    background-color: #388278;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #2c6f63;
}

3. Implementing Game Logic with JavaScript (script.js)

AJAX, Event Handling, and Interactivity

The JavaScript file handles the dynamic interactions on the board. It leverages AJAX to communicate with the PHP backend to update the game state upon every move. This asynchronous communication allows board updates without requiring a full page reload.

The script listens for click events on each cell, sends a POST request with the cell index, updates the board accordingly, and handles game reset logic. Additionally, it interprets responses from the server to alert players when someone wins or when there is a tie.

Below is the code for script.js:

// Function to execute a move by sending an AJAX request to the PHP backend
function makeMove(index) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "index.php", true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.onreadystatechange = function() {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
            try {
                var response = JSON.parse(this.responseText);
                if(response.winner) {
                    if(response.winner === "Tie") {
                        document.getElementById("message").textContent = "It's a tie!";
                    } else {
                        document.getElementById("message").textContent = "Player " + response.winner + " wins!";
                    }
                    // Disable further moves since the game has ended
                    disableBoard();
                } else {
                    // Reload page to update the board
                    location.reload();
                }
            } catch(e) {
                // In case of standard move, simply reload the page
                location.reload();
            }
        }
    };
    xhr.send("position=" + index);
}

// Function to reset the game by sending a reset request to the PHP backend
function resetGame() {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "index.php", true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.onreadystatechange = function() {
        if(this.readyState === XMLHttpRequest.DONE && this.status === 200) {
            location.reload();
        }
    };
    xhr.send("reset=true");
}

// Disable board clicks after game over
function disableBoard() {
    var cells = document.getElementsByClassName("cell");
    for (var i = 0; i < cells.length; i++) {
        cells[i].style.pointerEvents = "none";
    }
}

Additional Enhancements and Explanations

To further enhance the functionality of the game, you can expand the PHP backend to store game statistics in a database, add an AI opponent, or maintain a history of moves. For instance, by adding database connectivity (using MySQLi or PDO in PHP), you can record players’ scores or overall game performance.

Furthermore, the use of session management in PHP ensures that every player’s move is maintained between page reloads. This basic example establishes the fundamental dynamic pattern that can be scaled up for more complicated applications such as multiplayer interaction or high score tracking.

The use of an AJAX call in the JavaScript file improves user experience by eliminating an unnecessary full page refresh on every move. For advanced implementations, you may also consider handling errors, such as network interruptions and invalid state transitions, with more robust error management strategies.

Finally, the design patterns and coding techniques demonstrated in this project provide a solid foundation for building many types of interactive web applications, merging client-side scripting with PHP’s server-side power.


Table of Winning Combinations

The table below summarizes the possible winning combinations in a Tic Tac Toe game:

Combination Cells (Indices)
Top Row 0, 1, 2
Middle Row 3, 4, 5
Bottom Row 6, 7, 8
Left Column 0, 3, 6
Middle Column 1, 4, 7
Right Column 2, 5, 8
Main Diagonal 0, 4, 8
Anti-Diagonal 2, 4, 6

References


Recommended


Last updated March 13, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI