Tic Tac Toe Game Using Typescript
Last Updated :
23 Jul, 2025
In this tutorial, We are going to create an interactive tic-tac-toe game in which two users can play against each other and the winner will be displayed to the winning user.
What We’re Going to Create
We’ll build a Tic Tac Toe game focusing on event handling, DOM manipulation, and core game logic containing components.
- A game board.
- Various buttons to show the X or 0 which is the chance of the user.
- A reset button to reset the game board.
- A result component to show the winner.
Project Preview
Tic Tac Toe using TypescriptTic Tac Toe Game - HTML and CSS code
This HTML code sets up the structure for a Tic Tac Toe game, including a 3x3 grid of buttons for gameplay, a reset button, and the CSS add's up the styling to the buttons and the reset button on the game board.
HTML
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: lightcyan;
text-align: center;
}
.c {
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
}
.g {
height: 60vmin;
width: 60vmin;
display: flex;
flex-wrap: wrap;
gap: 1.5vmin;
justify-content: center;
}
.b {
height: 18vmin;
width: 18vmin;
border-radius: 1rem;
border: none;
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.3);
font-size: 8vmin;
color: red;
background-color: yellow;
}
#r {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
.b:hover {
background-color: chocolate;
}
#n {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
#m {
font-size: 8vmin;
}
.m-c {
height: 30vmin;
}
.h {
display: none;
}
</style>
</head>
<body>
<div class="m-c h">
<p id="m">Winner</p>
<button id="n">New Game</button>
</div>
<main>
<h1>Tic Tac Toe</h1>
<div class="c">
<div class="g">
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
</div>
</div>
<button id="r">Reset Game</button>
</main>
<script defer src="mains.js"></script>
</body>
</html>
In this example
- The layout is responsive, utilizing flexbox for centering and vmin units for scalable elements.
- Hover effects and shadow styling enhance user interaction and visual appeal.
- Game behavior is managed dynamically, with elements being shown or hidden based on game events.
Tic Tac Toe Game – TypeScript Logic
This TypeScript code implements the game logic for a Tic Tac Toe game, handling player turns, detecting wins or draws, and enabling game reset functionality.
mains.ts
const cells: NodeListOf<HTMLElement> = document.querySelectorAll('.b');
const resetButton: HTMLElement = document.querySelector('#r')!;
const newGameButton: HTMLElement = document.querySelector('#n')!;
const messageContainer: HTMLElement = document.querySelector('.m-c')!;
const message: HTMLElement = document.querySelector('#m')!;
let isPlayerO: boolean = true;
const winPatterns: number[][] = [
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 5, 8],
[2, 4, 6],
[3, 4, 5],
[6, 7, 8]
];
cells.forEach((cell) => {
cell.addEventListener('click', function () {
if (isPlayerO) {
cell.innerText = 'O';
cell.style.color = 'green';
isPlayerO = false;
(cell as HTMLButtonElement).disabled = true;
checkForWinner();
} else {
cell.innerText = 'X';
cell.style.color = 'black';
isPlayerO = true;
(cell as HTMLButtonElement).disabled = true;
checkForWinner();
}
});
});
const enableCells = (): void => {
cells.forEach((cell) => {
(cell as HTMLButtonElement).disabled = false;
cell.innerText = "";
});
};
const disableCells = (): void => {
cells.forEach((cell) => {
(cell as HTMLButtonElement).disabled = true;
});
};
const displayWinner = (winner: string): void => {
message.innerText = `Congratulations, Winner is ${winner}`;
messageContainer.classList.remove('h');
disableCells();
};
const checkForWinner = (): void => {
let winnerFound: boolean = false;
winPatterns.forEach((pattern) => {
let pos1Value: string = cells[pattern[0]].innerText;
let pos2Value: string = cells[pattern[1]].innerText;
let pos3Value: string = cells[pattern[2]].innerText;
if (pos1Value !== "" && pos2Value !== "" && pos3Value !== ""
&& pos1Value === pos2Value && pos2Value === pos3Value) {
displayWinner(pos1Value);
winnerFound = true;
return;
}
});
if (!winnerFound) {
const allCellsFilled: boolean = Array.prototype.slice.call(cells)
.every((cell) => cell.innerText !== "");
if (allCellsFilled) {
messageContainer.classList.remove('h');
message.innerText = 'Match Drawn';
}
}
};
const resetGame = (): void => {
isPlayerO = true;
enableCells();
messageContainer.classList.add('h');
};
newGameButton.addEventListener('click', resetGame);
resetButton.addEventListener('click', resetGame);
In this example
- HTML elements like game cells (.box) and buttons (#reset, #new-btn) are selected using querySelector, with explicit type definitions for type safety.
- The turnO flag alternates between true (Player O's turn) and false (Player X's turn), with the respective player's symbol displayed and the cell disabled after each move.
- The winPatterns array defines all possible winning combinations. The checkWinner function compares the current board state to these patterns and triggers showWinner if a match is found.
- The resetGame function clears the board, re-enables cells, and hides the message container. Both the #reset and #new-btn buttons trigger this reset.
Convert to JavaScript File
Now You need to convert the TypeScript file into JavaScript to render by browser. Use one of the following command.
npx tsc mains.ts
tsc mains.ts
- The command tsc mains.ts compiles the mains.js TypeScript file into a mains.js JavaScript file.
- It places the output in the same directory as the input file by default.
Complete Code
HTML
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: lightcyan;
text-align: center;
}
.c {
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
}
.g {
height: 60vmin;
width: 60vmin;
display: flex;
flex-wrap: wrap;
gap: 1.5vmin;
justify-content: center;
}
.b {
height: 18vmin;
width: 18vmin;
border-radius: 1rem;
border: none;
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.3);
font-size: 8vmin;
color: red;
background-color: yellow;
}
#r {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
.b:hover {
background-color: chocolate;
}
#n {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
#m {
font-size: 8vmin;
}
.m-c {
height: 30vmin;
}
.h {
display: none;
}
</style>
</head>
<body>
<div class="m-c h">
<p id="m">Winner</p>
<button id="n">New Game</button>
</div>
<main>
<h1>Tic Tac Toe</h1>
<div class="c">
<div class="g">
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
<button class="b"></button>
</div>
</div>
<button id="r">Reset Game</button>
</main>
<script defer>
const cells = document.querySelectorAll('.b');
const resetButton = document.querySelector('#r');
const newGameButton = document.querySelector('#n');
const messageContainer = document.querySelector('.m-c');
const message = document.querySelector('#m');
let isPlayerO = true;
const winPatterns = [
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 5, 8],
[2, 4, 6],
[3, 4, 5],
[6, 7, 8]
];
cells.forEach((cell) => {
cell.addEventListener('click', function () {
if (isPlayerO) {
cell.innerText = 'O';
cell.style.color = 'green';
isPlayerO = false;
cell.disabled = true;
checkForWinner();
} else {
cell.innerText = 'X';
cell.style.color = 'black';
isPlayerO = true;
cell.disabled = true;
checkForWinner();
}
});
});
const enableCells = () => {
cells.forEach((cell) => {
cell.disabled = false;
cell.innerText = "";
});
};
const disableCells = () => {
cells.forEach((cell) => {
cell.disabled = true;
});
};
const displayWinner = (winner) => {
message.innerText = `Congratulations, Winner is ${winner}`;
messageContainer.classList.remove('h');
disableCells();
};
const checkForWinner = () => {
let winnerFound = false;
winPatterns.forEach((pattern) => {
let pos1Value = cells[pattern[0]].innerText;
let pos2Value = cells[pattern[1]].innerText;
let pos3Value = cells[pattern[2]].innerText;
if (pos1Value !== "" && pos2Value !== "" && pos3Value !== ""
&& pos1Value === pos2Value && pos2Value === pos3Value) {
displayWinner(pos1Value);
winnerFound = true;
return;
}
});
if (!winnerFound) {
const allCellsFilled = Array.prototype.slice.call(cells).
every((cell) => cell.innerText !== "");
if (allCellsFilled) {
messageContainer.classList.remove('h');
message.innerText = 'Match Drawn';
}
}
};
const resetGame = () => {
isPlayerO = true;
enableCells();
messageContainer.classList.add('h');
};
newGameButton.addEventListener('click', resetGame);
resetButton.addEventListener('click', resetGame);
</script>
</body>
</html>
Similar Reads
Calculator App Using TypeScript A calculator app is a perfect project for practising TypeScript along with HTML and CSS. This app will have basic functionalities like addition, subtraction, multiplication, and division. It provides a clean and interactive interface for the user while using TypeScript to handle logic safely and eff
6 min read
Pixel Art Maker Using Typescript A Pixel Art Maker lets users create art by colouring squares on a grid, like retro pixel graphics. This project uses TypeScript and DOM manipulation for a fun and creative experience.What Weâre Going to CreateWe are going to create a pixel Art maker with the following components.A grid with size * s
5 min read
Quiz App Using Typescript A quiz app built with TypeScript provides an interactive way to test knowledge while using TypeScriptâs strong typing for better code quality. By implementing features like multiple-choice questions, score tracking, and timers, we can create a robust and engaging quiz experience for users.What Weâre
7 min read
Chandelier Animation Using Typescript In this project, we'll create an interactive chandelier animation that moves in response to mouse movements. Using Euclidean formulas, we'll calculate distances between nodes to ensure smooth and realistic motion.What Weâre Going to CreateIn this project, we will create an interactive chandelier ani
5 min read
How to use TypeScript with React? TypeScript enhances JavaScript by adding strict type definitions, making your code more robust and maintainable. ReactJS, a popular library for building user interfaces, pairs excellently with TypeScript to create clean, efficient, and scalable codebases. Combining TypeScript with React offers a pow
3 min read
Getting Started with TypeScript TypeScript is an open-source programming language developed by Microsoft that extends JavaScript by adding optional static typing to the language. It aims to make JavaScript development more scalable and maintainable, especially for large-scale projects. TypeScript code is transpiled into JavaScript
4 min read