Building an Interactive Tic Tac Toe Game with HTML, CSS, and JavaScript

In the world of web development, creating interactive games is an excellent way to hone your skills and understand the interplay between HTML, CSS, and JavaScript. Today, we're going to walk through the process of building a classic: Tic Tac Toe. This project is perfect for beginners looking to practice their skills or for experienced developers wanting a quick, fun challenge.
Project Overview
Our Tic Tac Toe game will feature:
- A responsive 3x3 game board
- Interactive cells that display X or O when clicked
- Turn-based gameplay
- Win and draw detection
- A reset button to start a new game
Let's break down the development process into three main parts: structure (HTML), style (CSS), and functionality (JavaScript).
HTML: Setting Up the Structure
We'll start with a simple HTML structure:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Awesome Tic Tac Toe</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<h1>Tic Tac Toe</h1>
<div class="board" id="board">
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
</div>
<div id="status"></div>
<button id="reset">Reset Game</button>
</div>
<script src="script.js">
</script>
</body>
</html>
This structure provides a container for our game, a 3x3 grid of cells, a status display, and a reset button.
CSS: Styling the Game
Next, let's style our game to make it visually appealing:
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.game-container {
text-align: center;
}
.board {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-gap: 5px;
margin-top: 20px;
}
.cell {
width: 100px;
height: 100px;
background-color: #fff;
border: 2px solid #333;
font-size: 4em;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: background-color 0.3s;
}
.cell:hover {
background-color: #f0f0f0;
}
.cell.x::before {
content: '×';
color: #ff4136;
}
.cell.o::before {
content: '○';
color: #0074d9;
}
#status {
margin-top: 20px;
font-size: 1.2em;
font-weight: bold;
}
#reset {
margin-top: 20px;
padding: 10px 20px;
font-size: 1em;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
#reset:hover {
background-color: #45a049;
}
This CSS centers the game on the page, creates a grid for the board, and styles the cells and symbols.
JavaScript: Adding Interactivity
Now for the fun part - let's make our game interactive with JavaScript:
const X_CLASS = 'x';
const O_CLASS = 'o';
const 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]
];
const cellElements = document.querySelectorAll('[data-cell]');
const board = document.getElementById('board');
const statusElement = document.getElementById('status');
const resetButton = document.getElementById('reset');
let isOTurn = false;
startGame();
resetButton.addEventListener('click', startGame);
function startGame() {
isOTurn = false;
cellElements.forEach(cell => {
cell.classList.remove(X_CLASS);
cell.classList.remove(O_CLASS);
cell.removeEventListener('click', handleClick);
cell.addEventListener('click', handleClick, { once: true });
});
setBoardHoverClass();
statusElement.textContent = '';
}
function handleClick(e) {
const cell = e.target;
const currentClass = isOTurn ? O_CLASS : X_CLASS;
placeMark(cell, currentClass);
if (checkWin(currentClass)) {
endGame(false);
} else if (isDraw()) {
endGame(true);
} else {
swapTurns();
setBoardHoverClass();
}
}
function placeMark(cell, currentClass) {
cell.classList.add(currentClass);
}
function swapTurns() {
isOTurn = !isOTurn;
}
function setBoardHoverClass() {
board.classList.remove(X_CLASS);
board.classList.remove(O_CLASS);
if (isOTurn) {
board.classList.add(O_CLASS);
} else {
board.classList.add(X_CLASS);
}
}
function checkWin(currentClass) {
return WINNING_COMBINATIONS.some(combination => {
return combination.every(index => {
return cellElements[index].classList.contains(currentClass);
});
});
}
function isDraw() {
return [...cellElements].every(cell => {
return cell.classList.contains(X_CLASS) || cell.classList.contains(O_CLASS);
});
}
function endGame(draw) {
if (draw) {
statusElement.textContent = 'Draw!';
} else {
statusElement.textContent = `${isOTurn ? "O's" : "X's"} Win!`;
}
}
This JavaScript code handles the game logic, including:
- Tracking turns
- Placing X and O marks
- Checking for wins or draws
- Updating the game status
- Resetting the game
Bringing It All Together
With these three components, we've created a fully functional Tic Tac Toe game. Players can take turns, the game detects wins and draws, and it can be reset for multiple rounds of play.
Conclusion
Building this Tic Tac Toe game demonstrates several key concepts in web development:
- Using CSS Grid for layout
- Manipulating the DOM with JavaScript
- Implementing game logic and win conditions
- Creating interactive elements with event listeners
This project serves as an excellent foundation for more complex games or interactive web applications. Feel free to expand on this base, perhaps by adding animations, a score tracker, or even an AI opponent!
Remember, the best way to improve your coding skills is through practice. Why not try modifying this game or creating your own unique twist on Tic Tac Toe?
Happy coding!
Comments
No approved comments available yet