Files

433 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tic Tac Toe vs Computer</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.game-container {
background: white;
border-radius: 25px;
padding: 40px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
text-align: center;
max-width: 450px;
}
h1 {
font-size: 2rem;
margin-bottom: 20px;
background: linear-gradient(90deg, #ff6b6b, #ff9500);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: 700;
}
.coin-container {
display: none;
margin: 20px auto;
}
.coin-container.active {
display: block;
}
.coin-message {
font-size: 1.2rem;
color: #555;
margin-bottom: 10px;
font-weight: 500;
}
.coin {
width: 120px;
height: 120px;
border-radius: 50%;
margin: 0 auto;
position: relative;
transition: transform 1.5s ease-in-out;
}
.coin.heads {
background: linear-gradient(135deg, #ffd700, #ffa500);
}
.coin.tails {
background: linear-gradient(135deg, #3498db, #2980b9);
}
.coin-header {
position: absolute;
top: 40px;
left: 50%;
transform: translateX(-50%);
font-size: 2rem;
font-weight: bold;
color: white;
text-shadow: 1px 1px 3px rgba(0,0,0,0.3);
}
.coin-tails .coin-header {
top: 40px;
}
.result-message {
font-size: 1.5rem;
font-weight: bold;
min-height: 40px;
margin: 15px 0;
color: #333;
}
.heads-result {
background: linear-gradient(90deg, #ffd700, #ffa500);
padding: 15px 25px;
border-radius: 15px;
color: white;
font-size: 1.3rem;
box-shadow: 0 4px 15px rgba(255,165,0,0.4);
}
.tails-result {
background: linear-gradient(90deg, #3498db, #2980b9);
padding: 15px 25px;
border-radius: 15px;
color: white;
font-size: 1.3rem;
box-shadow: 0 4px 15px rgba(52,152,219,0.4);
}
.board {
display: grid;
grid-template-columns: repeat(3, 85px);
grid-template-rows: repeat(3, 85px);
gap: 8px;
margin: 30px auto 0;
justify-content: center;
}
.cell {
width: 85px;
height: 85px;
background: linear-gradient(135deg, #87CEEB, #B0E0E6);
border: none;
border-radius: 12px;
cursor: pointer;
font-size: 2.5rem;
font-weight: bold;
transition: transform 0.15s ease, background 0.3s ease;
box-shadow: 0 3px 0 rgba(0,0,0,0.15);
display: flex;
justify-content: center;
align-items: center;
}
.cell:hover:not(:disabled) {
transform: scale(1.05);
background: linear-gradient(135deg, #98DCE8, #C4E2F0);
}
.cell:active:not(:disabled) {
transform: scale(0.98);
box-shadow: none;
}
.cell.x {
color: #3498db;
text-shadow: 0 2px 10px rgba(52,152,219,0.4);
}
.cell.o {
color: #ff9500;
text-shadow: 0 2px 10px rgba(255,149,0,0.4);
}
.cell.winning {
background: linear-gradient(135deg, #2ecc71, #27ae60);
transform: scale(1.03);
box-shadow: 0 5px 20px rgba(46,204,113,0.5);
}
.cell.disabled {
cursor: not-allowed;
opacity: 0.7;
}
.game-message {
min-height: 70px;
margin: 20px auto;
font-size: 1.3rem;
font-weight: 600;
padding: 15px 25px;
border-radius: 15px;
max-width: 95%;
word-wrap: break-word;
}
.message-player-wins {
background: linear-gradient(90deg, #2ecc71, #27ae60);
color: white;
animation: bounceIn 0.6s ease;
}
.message-computer-wins {
background: linear-gradient(90deg, #ff6b6b, #ff9500);
color: white;
animation: bounceIn 0.6s ease;
}
.message-draw {
background: linear-gradient(90deg, #a29bfe, #6c5ce7);
color: white;
animation: fadeIn 0.6s ease;
}
.message-start {
background: linear-gradient(90deg, #fdcb6e, #ffd700);
color: #333;
animation: scaleIn 0.6s ease;
}
@keyframes bounceIn {
0% { opacity: 0; transform: scale(0.3); }
50% { opacity: 1; transform: scale(1.1); }
70% { transform: scale(0.9); }
100% { transform: scale(1); }
}
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
@keyframes scaleIn {
0% { opacity: 0; transform: scale(0.8); }
100% { opacity: 1; transform: scale(1); }
}
@keyframes wave {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.cell-animating {
animation: wave 0.3s ease;
}
.status-indicator {
font-size: 1rem;
color: #666;
margin: 0 0 10px 0;
font-style: italic;
}
.thinking {
color: #ff9500;
font-weight: 600;
}
</style>
</head>
<body>
<div class="game-container">
<h1>✏️ Tic Tac Toe vs Computer 🤖</h1>
<div class="coin-container" id="coinContainer">
<div class="coin-message" id="coinMessage">Flipping the coin...</div>
<div class="coin" id="coin">
<div class="coin-header H">H</div>
</div>
</div>
<div class="result-message" id="resultMessage"></div>
<div class="status-indicator" id="statusIndicator"></div>
<div class="board" id="board">
<button class="cell" data-index="0"></button>
<button class="cell" data-index="1"></button>
<button class="cell" data-index="2"></button>
<button class="cell" data-index="3"></button>
<button class="cell" data-index="4"></button>
<button class="cell" data-index="5"></button>
<button class="cell" data-index="6"></button>
<button class="cell" data-index="7"></button>
<button class="cell" data-index="8"></button>
</div>
<div class="game-message" id="gameMessage"></div>
</div>
<script>
const board = [null, null, null, null, null, null, null, null, null];
let player = 'X';
let computer = 'O';
let playerNext = true;
let gameActive = false;
const coinContainer = document.getElementById('coinContainer');
const coin = document.getElementById('coin');
const coinMessage = document.getElementById('coinMessage');
const resultMessage = document.getElementById('resultMessage');
const gameMessage = document.getElementById('gameMessage');
const statusIndicator = document.getElementById('statusIndicator');
const cells = document.querySelectorAll('.cell');
function randomMove() {
let available = [];
board.forEach((cell, index) => {
if (cell === null) available.push(index);
});
return available[Math.floor(Math.random() * available.length)];
}
function startCoinFlip() {
setTimeout(() => {
if (!gameActive) {
gameActive = true;
coinContainer.classList.add('active');
coinMessage.textContent = 'Flipping...';
coin.classList.add('active');
setTimeout(() => {
const isHeads = Math.random() < 0.5;
coin.className = 'coin ' + (isHeads ? 'heads' : 'tails');
coinMessage.textContent = isHeads ? 'Heads!' : 'Tails!';
resultMessage.innerHTML = isHeads
? '<div class="heads-result"><span>Heads, <strong>you\'re X!</strong></span></div>'
: '<div class="tails-result"><span>Tails, <strong>computer is <span class="player">\'X\'</span></strong>!</span></div>';
setTimeout(startGame, 500);
}, 1500);
}
}, 1000);
}
function startGame() {
coinMessage.textContent = 'Ready!';
cells.forEach(cell => {
cell.textContent = '';
cell.className = 'cell';
cell.disabled = false;
});
statusIndicator.textContent = '';
gameMessage.innerHTML = '<div class="message-start">Your Turn!</div>';
gameActive = true;
setTimeout(() => {
gameActive = false;
computerMove();
}, 500);
}
function computerMove() {
if (!gameActive) return;
statusIndicator.textContent = '🤖 Computer is thinking...';
setTimeout(() => {
const move = randomMove();
if (move !== undefined) {
makeMove(move, computer, true);
playerNext = true;
gameActive = false;
}
}, 500);
}
function makeMove(index, mark, isComputer = false) {
const cell = cells[index];
board[index] = mark;
cell.textContent = mark;
cell.classList.add(mark.toLowerCase());
cell.classList.add('cell-animating');
setTimeout(() => cell.classList.remove('cell-animating'), 300);
if (isComputer) {
statusIndicator.textContent = '';
checkResult();
} else {
gameActive = false;
if (board.includes(null)) {
statusIndicator.textContent = 'Your Turn!';
playerNext = true;
} else {
gameMessage.textContent = '🤝';
}
checkResult();
}
}
function checkResult() {
const wins = [
[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]
];
let winner = null;
for (let i = 0; i < 8; i++) {
if (board[wins[i][0]] === board[wins[i][1]] &&
board[wins[i][1]] === board[wins[i][2]] &&
board[wins[i][0]] !== null) {
winner = board[wins[i][0]];
}
}
if (winner) {
cells.forEach(cell => {
if (board[parseInt(cell.dataset.index)] === winner) {
cell.classList.add('winning');
}
});
setTimeout(() => {
gameMessage.innerHTML = winner === computer
? '<div class="message-computer-wins">😄 Computer wins! Better luck next time! 🎮</div>'
: '<div class="message-player-wins">🎉 You win! Great job! 🎮</div>';
}, 500);
} else if (board.every(cell => cell !== null)) {
setTimeout(() => {
gameMessage.textContent = '🤝 It is a draw! 🎮';
}, 500);
}
}
function restart() {
cells.forEach(cell => {
cell.textContent = '';
cell.className = 'cell';
});
setTimeout(() => {
gameMessage.innerHTML = '<div class="message-start">Play Again!</div>';
startCoinFlip();
}, 300);
}
cells.forEach(cell => {
cell.addEventListener('click', () => {
if (playerNext) {
makeMove(parseInt(cell.dataset.index), player);
}
});
});
startCoinFlip();
</script>
</body>
</html>