Unbeatable Tic Tac Toe. Single-page HTML, CSS & JavaScript.
![tic-tac-toe](https://private-user-images.githubusercontent.com/8287493/307416606-5dd43d69-1f90-4d90-aacd-be865b4009df.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU3Mjc1NjQsIm5iZiI6MTcyNTcyNzI2NCwicGF0aCI6Ii84Mjg3NDkzLzMwNzQxNjYwNi01ZGQ0M2Q2OS0xZjkwLTRkOTAtYWFjZC1iZTg2NWI0MDA5ZGYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDkwNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDA5MDdUMTY0MTA0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9YmI4YjczYjZmNGU3NmQyODAwNWUwNThhNDA0Y2U0MmZhOTUyYzM3ZmFjYjU5ODcwMDExNzA1ODllMWVmN2IwNCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.ckbwNKrBTLnAmLb0PoysmeBAdkffYr5W00zLehgdce4)
Implementation of Minimax algorithm wrapped up in a neat chalkboard UI. The chalk effect is achieved using SVG turbulence filters.
Minimax algorithm:
Lines 438 to 482 in 3e10e64
Unbeatable Tic Tac Toe. Single-page HTML, CSS & JavaScript
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Unbeatable Tic Tac Toe. Single-page HTML, CSS & JavaScript.
Implementation of Minimax algorithm wrapped up in a neat chalkboard UI. The chalk effect is achieved using SVG turbulence filters.
Minimax algorithm:
Lines 438 to 482 in 3e10e64
function getComputerMoveData(tempPlaygroundState, depth) { | |
const winCombinationIndex = getWinCombinationIndex(tempPlaygroundState); | |
if (winCombinationIndex !== -1) { | |
// we've got a winner in this hypothetical game! | |
const wonMover = tempPlaygroundState[winCombinations[winCombinationIndex][0]]; | |
return { | |
index: -1, | |
score: wonMover === 1 | |
? -1 // user hypothetically won (bad) | |
: 1 // computer hypothetically won (good) | |
}; | |
} else if (!tempPlaygroundState.some((mover) => mover === -1)) { | |
// a tie | |
return { index: -1, score: 0 }; | |
} | |
depth = (depth || 0) + 1; | |
// 1 - user's hypothetical turn; 0 - computer's hypothetical turn. | |
const mover = +!(depth % 2); | |
const availableMoves = tempPlaygroundState | |
.map((_, i) => i) | |
.filter((boardIndex) => tempPlaygroundState[boardIndex] === -1); | |
const scores = []; | |
const moves = []; | |
for (let i = 0; i < availableMoves.length; i++) { | |
const move = availableMoves[i]; | |
const iterationPlayground = [ ...tempPlaygroundState ]; | |
iterationPlayground[move] = mover; | |
const hypotheticalMoveData = getComputerMoveData(iterationPlayground, depth); | |
scores.push(hypotheticalMoveData.score); | |
moves.push(move); | |
// rollback the hypothetical move | |
tempPlaygroundState[move] = -1; | |
} | |
const func = mover === 1 | |
? Math.min // we're looking for the min score if it's user's turn | |
: Math.max; // and for the max score if it's computer's score | |
const moveScore = func.apply(null, scores); | |
const moveScoreIndex = scores.indexOf(moveScore); | |
return { index: moves[moveScoreIndex], score: moveScore }; | |
} |
Unbeatable Tic Tac Toe. Single-page HTML, CSS & JavaScript