Creating A Tic-Tac-Toe Game With HTML, CSS, And JavaScript
- With Code Example
- July 17, 2024
Tic-Tac-Toe Game Tutorial: From Basics to Advanced
Series - Game
Tic-Tac-Toe is a timeless and universally recognized game that offers a straightforward yet engaging challenge. Its simplicity makes it an ideal project for anyone looking to dip their toes into the world of programming and web development. The game itself is played on a 3x3 grid where two players, X and O, take turns marking the cells in an attempt to align three of their marks either horizontally, vertically, or diagonally. The first player to achieve this goal wins, and if all cells are filled without a winner, the game results in a draw.
In the realm of web development, creating a Tic-Tac-Toe game is an excellent exercise for learning the fundamentals of HTML, CSS, and JavaScript. HTML provides the structure of the game board, CSS is used to style and enhance the visual appeal of the game, and JavaScript is the key to implementing the game logic and interactive elements.
In this guide, we’ll take you through a comprehensive process to build your own Tic-Tac-Toe game from scratch. We’ll start by creating the HTML structure that outlines the layout of the game board and controls. Next, we’ll style the game with CSS to ensure it looks polished and visually appealing. Finally, we’ll dive into JavaScript to handle the game’s functionality, such as tracking player moves, determining the winner, and allowing the game to be restarted.
This project will not only help you understand how these three technologies work together but also provide hands-on experience in creating a functional and interactive web application. By following along, you’ll gain valuable skills in front-end development that you can apply to more complex projects in the future.
1. Setup Your HTML
We’ll start by creating a basic HTML structure. This file will include the game’s layout and a reference to our CSS and JavaScript files.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Tic-Tac-Toe</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<section>
<h1 class="game--title">Tic-Tac-Toe</h1>
<div class="game--container">
<div data-cell-index="0" class="cell"></div>
<div data-cell-index="1" class="cell"></div>
<div data-cell-index="2" class="cell"></div>
<div data-cell-index="3" class="cell"></div>
<div data-cell-index="4" class="cell"></div>
<div data-cell-index="5" class="cell"></div>
<div data-cell-index="6" class="cell"></div>
<div data-cell-index="7" class="cell"></div>
<div data-cell-index="8" class="cell"></div>
</div>
<h2 class="game--status"></h2>
<button class="game--restart">Restart Game</button>
</section>
<script src="game.js"></script>
</body>
</html>
2. Style the Game with CSS
Next, we’ll add some styles to make the game visually appealing. This file will style the game board, cells, and status message.
styles.css
body {
font-family: 'Arial', sans-serif;
}
section {
text-align: center;
}
.cell {
font-family: 'Permanent Marker', cursive;
width: 100px;
height: 100px;
box-shadow: 2px 2px 2px 2px #ecd7ba;
border: 2px solid #ecd7ba;
cursor: pointer;
line-height: 100px;
font-size: 60px;
}
.game--title {
font-size: 100px;
color: #d7a62f;
margin: 10px auto;
}
.game--container {
display: grid;
grid-template-columns: repeat(3, auto);
width: 306px;
margin: 10px auto;
background-color: #11213a;
color: #04c0b2;
}
.game--status {
font-size: 50px;
color: #d7a62f;
margin: 20px auto;
}
.game--restart {
background-color: #f7e4ac;
width: 200px;
height: 50px;
font-size: 25px;
color: #5586e2;
box-shadow: 2px 2px 2px 2px #d86c23;
border: 2px solid #d86c23;
}
3. Add Game Logic with JavaScript
Now, we’ll add the JavaScript that powers the game. This script will handle player moves, check for wins or draws, and manage the game state.
game.js
const statusDisplay = document.querySelector('.game--status');
let gameActive = true;
let currentPlayer = 'X';
let gameState = ['', '', '', '', '', '', '', '', ''];
const winningMessage = () => `Player ${currentPlayer} has won!`;
const drawMessage = () => `Game ended in a draw!`;
const currentPlayerTurn = () => `It's ${currentPlayer}'s turn`;
statusDisplay.innerHTML = currentPlayerTurn();
const winningConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
function handleCellPlayed(clickedCell, clickedCellIndex) {
gameState[clickedCellIndex] = currentPlayer;
clickedCell.innerHTML = currentPlayer;
}
function handlePlayerChange() {
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
statusDisplay.innerHTML = currentPlayerTurn();
}
function handleResultValidation() {
let roundWon = false;
for (let i = 0; i <= 7; i++) {
const winCondition = winningConditions[i];
const a = gameState[winCondition[0]];
const b = gameState[winCondition[1]];
const c = gameState[winCondition[2]];
if (a === '' || b === '' || c === '') continue;
if (a === b && b === c) {
roundWon = true;
break;
}
}
if (roundWon) {
statusDisplay.innerHTML = winningMessage();
gameActive = false;
return;
}
const roundDraw = !gameState.includes('');
if (roundDraw) {
statusDisplay.innerHTML = drawMessage();
gameActive = false;
return;
}
handlePlayerChange();
}
function handleCellClick(clickedCellEvent) {
const clickedCell = clickedCellEvent.target;
const clickedCellIndex = parseInt(
clickedCell.getAttribute('data-cell-index')
);
if (gameState[clickedCellIndex] !== '' || !gameActive) return;
handleCellPlayed(clickedCell, clickedCellIndex);
handleResultValidation();
}
function handleRestartGame() {
gameActive = true;
currentPlayer = 'X';
gameState = ['', '', '', '', '', '', '', '', ''];
statusDisplay.innerHTML = currentPlayerTurn();
document.querySelectorAll('.cell').forEach((cell) => (cell.innerHTML = ''));
}
document
.querySelectorAll('.cell')
.forEach((cell) => cell.addEventListener('click', handleCellClick));
document
.querySelector('.game--restart')
.addEventListener('click', handleRestartGame);
How It Works
- HTML: Defines the layout of the game, including the game board and status message.
- CSS: Styles the game to make it visually appealing.
- JavaScript: Implements the game logic, including handling player moves, checking for winners or draws, and updating the game status.
By combining these elements, you’ve created a functional and interactive Tic-Tac-Toe game. Enjoy coding and playing your game!