* { padding: 0; margin: 0; box-sizing: inherit; }
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-image: linear-gradient(to top, #a8edea, #ffc7d9);
font-family: "Bungee Inline", cursive;
color: #f5f5f5;
overflow: hidden;
}
.wrapper {
background-color: #55acee53;
padding: 50px;
}
.board {
display: grid;
grid-template-columns: repeat(3, minmax(90px, 1fr));
grid-template-rows: repeat(3, minmax(90px, 1fr));
grid-gap: 12px;
width: 100%;
max-width: 495px;
margin: 0 auto 15px;
}
.cell {
cursor: pointer;
position: relative;
background-color: #f5f5f5;
width: 90px;
height: 90px;
opacity: 0.5;
transition: opacity 0.2s ease-in-out;
}
.cell:hover { opacity: 1; }
.game-end-overlay {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background-color: #0d1021;
}
.game-end-overlay.show { display: flex; flex-direction: column; justify-content: center; align-items: center; }
.reset-button {
color: #f5f5f5;
font-size: 30px;
border: none;
padding: 10px 20px;
background-color: #a186be;
box-shadow: 5px 5px 0 #55acee;
cursor: pointer;
}
.reset-button:hover { transform: scale(1.2); }
.reset-button:active { top: 6px; left: 6px; box-shadow: none; }
const board = document.getElementById('board');
const cells = document.querySelectorAll('[data-cell]');
const currentStatus = document.getElementById('currentStatus');
const resetButton = document.getElementById('resetButton');
const gameEndOverlay = document.getElementById('gameEndOverlay');
const currentBeastStatusImg = document.getElementById('currentBeastImg');
const winningMessage = document.querySelector('[data-winning-message]');
const winningMessageText = document.querySelector('[data-winning-message] p');
const winningMessageImg = document.createElement('img');
let gameIsLive = true;
let unicornTurn = true;
const winningCombinations = [
[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 setBoardHoverClass = () => {
board.classList.remove('unicorn', 'dragon');
if (unicornTurn) board.classList.add('unicorn');
else board.classList.add('dragon');
}
const placeBeastImg = (cell, currentBeast) => {
cell.classList.add(currentBeast);
}
const swapTurns = () => {
unicornTurn = !unicornTurn;
}
const updateCurrentStatus = () => {
if (unicornTurn) {
currentBeastStatusImg.src = './1.gif';
currentBeastStatusImg.alt = 'unicorn';
} else {
currentBeastStatusImg.src = './2.gif';
currentBeastStatusImg.alt = 'dragon';
}
}
const checkWin = (currentBeast) => {
return winningCombinations.some(combination => {
return combination.every(i => {
return cells[i].classList.contains(currentBeast);
});
});
}
const isDraw = () => {
return [...cells].every(cell => {
return cell.classList.contains('unicorn') || cell.classList.contains('dragon');
});
}
const startGame = () => {
cells.forEach(cell => {
winningMessageImg.remove();
cell.classList.remove('unicorn', 'dragon');
cell.removeEventListener('click', handleCellClick);
cell.addEventListener('click', handleCellClick, { once: true });
});
setBoardHoverClass();
gameEndOverlay.classList.remove('show');
}
const endGame = (draw) => {
if (draw) {
winningMessageText.innerText = `draw!`;
} else {
winningMessageImg.src = unicornTurn ? './1.gif' : './2.gif';
winningMessageImg.alt = unicornTurn ? 'unicorn' : 'dragon';
winningMessage.insertBefore(winningMessageImg, winningMessageText);
winningMessageText.innerText = `wins!!!`;
}
gameEndOverlay.classList.add('show');
}
const handleCellClick = (e) => {
const cell = e.target;
const currentBeast = unicornTurn ? 'unicorn' : 'dragon';
placeBeastImg(cell, currentBeast);
if (checkWin(currentBeast)) {
endGame(false);
} else if (isDraw()) {
endGame(true);
} else {
swapTurns();
updateCurrentStatus();
setBoardHoverClass();
}
}
resetButton.addEventListener('click', startGame);
startGame();