Tic-Tac-Toe Game
Tic-Tac-Toe
const cells = document.querySelectorAll('.cell');
const result = document.getElementById('result');
const startBtn = document.getElementById('start-btn');
const humanVsHumanBtn = document.getElementById('human-vs-human');
const humanVsComputerBtn = document.getElementById('human-vs-computer');
const xBtn = document.getElementById('x');
const oBtn = document.getElementById('o');
let board;
let currentPlayer;
let humanPlayer;
let computerPlayer;
let isHumanVsHuman = true;
let gameActive = false;
// Winning combinations
const winCombos = [
[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 startGame() {
board = Array.from(Array(9).keys());
cells.forEach(cell => {
cell.textContent = '';
cell.style.backgroundColor = '';
cell.addEventListener('click', turnClick, false);
});
result.textContent = '';
gameActive = true;
}
function turnClick(event) {
const cellIndex = event.target.dataset.index;
if (typeof board[cellIndex] === 'number' && gameActive) {
turn(cellIndex, currentPlayer);
if (!checkWin(board, currentPlayer) && !checkTie()) {
if (!isHumanVsHuman) {
turn(bestSpot(), computerPlayer);
}
}
}
}
function turn(cellIndex, player) {
board[cellIndex] = player;
document.querySelector(`[data-index="${cellIndex}"]`).textContent = player;
const gameWon = checkWin(board, player);
if (gameWon) {
gameOver(gameWon);
}
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
}
function checkWin(board, player) {
let plays = board.reduce((a, e, i) =>
(e === player) ? a.concat(i) : a, []);
let gameWon = null;
for (let [index, win] of winCombos.entries()) {
if (win.every(elem => plays.indexOf(elem) > -1)) {
gameWon = {index: index, player: player};
break;
}
}
return gameWon;
}
function gameOver(gameWon) {
for (let index of winCombos[gameWon.index]) {
document.querySelector(`[data-index="${index}"]`).style.backgroundColor =
gameWon.player === humanPlayer ? "blue" : "red";
}
cells.forEach(cell => cell.removeEventListener('click', turnClick, false));
declareWinner(gameWon.player === humanPlayer ? "You win!" : "You lose.");
}
function declareWinner(who) {
result.textContent = who;
gameActive = false;
}
function emptySquares() {
return board.filter(s => typeof s === 'number');
}
function bestSpot() {
return minimax(board, computerPlayer).index;
}
function checkTie() {
if (emptySquares().length === 0) {
cells.forEach(cell => cell.style.backgroundColor = "green");
cells.forEach(cell => cell.removeEventListener('click', turnClick, false));
declareWinner("Tie Game!");
return true;
}
return false;
}
// Minimax algorithm to make the AI unbeatable
function minimax(newBoard, player) {
let availSpots = emptySquares();
if (checkWin(newBoard, humanPlayer)) {
return {score: -10};
} else if (checkWin(newBoard, computerPlayer)) {
return {score: 10};
} else if (availSpots.length === 0) {
return {score: 0};
}
let moves = [];
for (let i = 0; i < availSpots.length; i++) {
let move = {};
move.index = newBoard[availSpots[i]];
newBoard[availSpots[i]] = player;
let result;
if (player === computerPlayer) {
result = minimax(newBoard, humanPlayer);
move.score = result.score;
} else {
result = minimax(newBoard, computerPlayer);
move.score = result.score;
}
newBoard[availSpots[i]] = move.index;
moves.push(move);
}
let bestMove;
if (player === computerPlayer) {
let bestScore = -10000;
for (let i = 0; i < moves.length; i++) {
if (moves[i].score > bestScore) {
bestScore = moves[i].score;
bestMove = i;
}
}
} else {
let bestScore = 10000;
for (let i = 0; i < moves.length; i++) {
if (moves[i].score < bestScore) {
bestScore = moves[i].score;
bestMove = i;
}
}
}
return moves[bestMove];
}
// Event Listeners
humanVsHumanBtn.addEventListener('click', () => {
isHumanVsHuman = true;
});
humanVsComputerBtn.addEventListener('click', () => {
isHumanVsHuman = false;
});
xBtn.addEventListener('click', () => {
humanPlayer = 'X';
computerPlayer = 'O';
currentPlayer = 'X';
});
oBtn.addEventListener('click', () => {
humanPlayer = 'O';
computerPlayer = 'X';
currentPlayer = 'X';
});
startBtn.addEventListener('click', startGame);
Hi guys
ReplyDelete