Skip to content

Commit 42c85a1

Browse files
authored
Create tic-tac-toe
1 parent 1145fbb commit 42c85a1

1 file changed

Lines changed: 177 additions & 0 deletions

File tree

tic-tac-toe

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Tic Tac Toe</title>
6+
<style>
7+
body {
8+
font-family: Arial, sans-serif;
9+
background: #1d1d1d;
10+
color: #fff;
11+
text-align: center;
12+
margin: 0;
13+
}
14+
h1 {
15+
margin: 20px;
16+
}
17+
#mode-select {
18+
margin: 20px;
19+
font-size: 18px;
20+
padding: 10px;
21+
}
22+
#game-board {
23+
display: grid;
24+
grid-template-columns: repeat(3, 100px);
25+
grid-gap: 5px;
26+
justify-content: center;
27+
margin: 20px auto;
28+
}
29+
.cell {
30+
width: 100px;
31+
height: 100px;
32+
background: #333;
33+
font-size: 48px;
34+
display: flex;
35+
justify-content: center;
36+
align-items: center;
37+
cursor: pointer;
38+
user-select: none;
39+
}
40+
.cell:hover {
41+
background: #444;
42+
}
43+
#message {
44+
font-size: 24px;
45+
margin-top: 20px;
46+
}
47+
#restart {
48+
margin-top: 20px;
49+
font-size: 18px;
50+
padding: 10px 20px;
51+
cursor: pointer;
52+
}
53+
</style>
54+
</head>
55+
<body>
56+
57+
<h1>Tic Tac Toe</h1>
58+
59+
<select id="mode-select">
60+
<option value="pvp">Player vs Player</option>
61+
<option value="pvc">Player vs Computer</option>
62+
</select>
63+
64+
<div id="game-board"></div>
65+
66+
<p id="message"></p>
67+
<button id="restart">Restart Game</button>
68+
69+
<script>
70+
const board = document.getElementById('game-board');
71+
const message = document.getElementById('message');
72+
const restart = document.getElementById('restart');
73+
const modeSelect = document.getElementById('mode-select');
74+
75+
let cells = [];
76+
let currentPlayer = 'X';
77+
let gameMode = 'pvp';
78+
let gameOver = false;
79+
80+
function createBoard() {
81+
board.innerHTML = '';
82+
cells = [];
83+
for (let i = 0; i < 9; i++) {
84+
const cell = document.createElement('div');
85+
cell.classList.add('cell');
86+
cell.addEventListener('click', () => makeMove(i));
87+
board.appendChild(cell);
88+
cells.push(cell);
89+
}
90+
message.textContent = "Player X's Turn";
91+
currentPlayer = 'X';
92+
gameOver = false;
93+
}
94+
95+
function checkWinner() {
96+
const combos = [
97+
[0,1,2], [3,4,5], [6,7,8],
98+
[0,3,6], [1,4,7], [2,5,8],
99+
[0,4,8], [2,4,6]
100+
];
101+
for (let combo of combos) {
102+
const [a,b,c] = combo;
103+
if (cells[a].textContent && cells[a].textContent === cells[b].textContent && cells[a].textContent === cells[c].textContent) {
104+
gameOver = true;
105+
message.textContent = `${cells[a].textContent} Wins! 🎉`;
106+
return true;
107+
}
108+
}
109+
if ([...cells].every(cell => cell.textContent)) {
110+
gameOver = true;
111+
message.textContent = "It's a Draw!";
112+
return true;
113+
}
114+
return false;
115+
}
116+
117+
function makeMove(index) {
118+
if (cells[index].textContent || gameOver) return;
119+
cells[index].textContent = currentPlayer;
120+
if (checkWinner()) return;
121+
if (gameMode === 'pvc' && currentPlayer === 'X') {
122+
currentPlayer = 'O';
123+
message.textContent = "Computer's Turn";
124+
setTimeout(computerMove, 300);
125+
} else {
126+
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
127+
message.textContent = `Player ${currentPlayer}'s Turn`;
128+
}
129+
}
130+
131+
// Smarter AI: Win > Block > Random
132+
function computerMove() {
133+
let bestMove = getBestMove('O') || getBestMove('X') || getRandomMove();
134+
if (bestMove !== null) {
135+
cells[bestMove].textContent = 'O';
136+
}
137+
if (!checkWinner()) {
138+
currentPlayer = 'X';
139+
message.textContent = "Player X's Turn";
140+
}
141+
}
142+
143+
// Tries to find winning/blocking move
144+
function getBestMove(player) {
145+
const combos = [
146+
[0,1,2], [3,4,5], [6,7,8],
147+
[0,3,6], [1,4,7], [2,5,8],
148+
[0,4,8], [2,4,6]
149+
];
150+
for (let combo of combos) {
151+
const [a,b,c] = combo;
152+
const values = [cells[a].textContent, cells[b].textContent, cells[c].textContent];
153+
if (values.filter(val => val === player).length === 2 && values.includes('')) {
154+
const emptyIndex = [a,b,c].find(idx => !cells[idx].textContent);
155+
return emptyIndex;
156+
}
157+
}
158+
return null;
159+
}
160+
161+
function getRandomMove() {
162+
const empty = cells.map((cell, idx) => cell.textContent ? null : idx).filter(idx => idx !== null);
163+
if (empty.length === 0) return null;
164+
return empty[Math.floor(Math.random() * empty.length)];
165+
}
166+
167+
restart.addEventListener('click', createBoard);
168+
modeSelect.addEventListener('change', function() {
169+
gameMode = this.value;
170+
createBoard();
171+
});
172+
173+
createBoard();
174+
</script>
175+
176+
</body>
177+
</html>

0 commit comments

Comments
 (0)