Tic Tac Toe with HTML CSS and JS

Play & Fun Tic Tac Toe

First Selet Your Sign

Here's an example of a Tic Tac Toe game implemented using HTML, CSS, and JavaScript:

HTML (index.html)

				
					<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Tic Tac Toe with HTML CSS and JS</title>
  <link rel="stylesheet" href="./style.css">

</head>
<body>
<div class="selection">
        <h3>Play & Fun Tic Tac Toe</h3>
        <p>First Selet Your Sign</p>
        <div class="players">
            <button class="player" onclick="playerSelect('X')">X</button>
            <button class="player" onclick="playerSelect('O')">O</button>
        </div>
    </div>

    <div class="play-board">
        <table>
            <tr>
                <td class="cell" id="0"></td>
                <td class="cell" id="1"></td>
                <td class="cell" id="2"></td>
            </tr>
            <tr>
                <td class="cell" id="3"></td>
                <td class="cell" id="4"></td>
                <td class="cell" id="5"></td>
            </tr>
            <tr>
                <td class="cell" id="6"></td>
                <td class="cell" id="7"></td>
                <td class="cell" id="8"></td>
            </tr>
        </table>

        <button class="reset" onclick="startGame()">Reset Your Game</button>

    </div>

        <div class="winner">

            <h3></h3>
            <button class="reset" onclick="startGame()"> Start New Game</button>
            
            </div>
            <!-- partial -->
  <script  src="./script.js"></script>

</body>
</html>
				
			

CSS (style.css)

				
					.selection{
    padding: 50px 100px;
    text-align: center;
    border-radius: 12px;
}

.selection h3{
    font-size: 3rem;
    color: #ff0000;
    font-weight: 700;
}

.selection p{
    margin-top: 10px;
    font-size: 2rem;
    color: #333;
}

.selection .players{
    width: 100%;
    margin-top: 10px;
}

.selection .players .player{

    border: 2px solid #ff0000;
    border-radius: 8px;
    font-size: 2.5rem;
    cursor: pointer;
    margin: 0 4px;
    height: 4rem;
    transition: .4s ease;

}
.selection .players .player:hover{
    color: whitesmoke;
    background-color: #ff0000;
}

.fadeOut{
    animation: hide .3s linear alternate;
}

@keyframes hide {
    from{
        opacity: 1;
        transform: scale(1);
    }
    to{
        opacity: 0;
        transform: scale(0);
    }
}

.fadeIn{
    animation: show .3s linear alternate;
}

@keyframes show{
    from{
        opacity: 0;
        transform: scale(0);
    }
    to{
        opacity: 1;
        transform: scale(1);
    }
}


.play-board{
    display: none;
    padding: 50px;
    border-radius: 8px;
    background: whitesmoke;
    text-align: center;

}

table td{
    width: 5rem;
    height: 5rem;
    font-size: 2rem;
    border-radius: 8px;
    border: 2px solid whitesmoke;
    background: #000;
    cursor: pointer;
    transition: .4s linear;
    text-align: center;
}

.reset{
    cursor: pointer;
    padding: 8px 18px;
    margin-top: 30px;
    color: #fff;
    font-size: 1.5rem;
    border-radius: 4px;
    border: 3px solid #ff0000;
    transition: .4s;
}

.reset:hover{
    color: whitesmoke;
    background: #820000;
}

.winner{
    display: none;
    padding: 40px 50px;
    border-radius: 8px;
    background: whitesmoke;
    text-align: center;

}

.winner h3{
    font-size: 30px;
    font-weight: 500;
}
/* Mobile media query */
@media (max-width: 768px) {
  .selection h3 {
    font-size: 1.7rem;
    color: #ff0000;
    font-weight: 500;
  }
	.selection{
     padding: 0px 0px;
    text-align: center;
    border-radius: 12px;
}
	.selection p{
    margin-top: 10px;
    font-size: 1.2rem;
    color: #333;
}
}

				
			

JS (script.js)

				
					const selection = document.querySelector('.selection');
const playBoard = document.querySelector('.play-board');
const winner = document.querySelector('.winner');

let gameBoard, user='X', computer='O';
const cells = document.querySelectorAll('.cell')
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]];

const playerSelect = player => {

    user=player;
    computer = (player === 'X') ? 'O' : 'X';

    gameBoard = Array.from(Array(9).keys());

    for (let cell of cells){
        cell.addEventListener('click',handleClick, false);
    }

    if (computer === 'X') {
        turn(bestSpot(), computer);
        
    }

    selection.classList.add('fadeOut')
    setTimeout(() => {selection.style.display='none'}, 250);

    playBoard.classList.add('fadeIn')
    setTimeout(() => {playBoard.style.display='block'}, 250);
}

const startGame = () => {

    winner.classList.remove('fadeIn')
    winner.classList.add('fadeOut')
    setTimeout(() => {winner.style.display= 'none' }, 250);

    playBoard.classList.remove('fadeIn')
    playBoard.classList.add('fadeOut')
    setTimeout(() => {playBoard.style.display= 'none' }, 250);

    selection.classList.add('fadeIn')
    setTimeout(() => {selection.style.display= 'block' }, 250);

    for(let cell of cells){
        cell.innerHTML='';
        cell.style.color='#fff';
        cell.style.background='#000';
    }

}

startGame();

const handleClick = gameSpace => {
    if (typeof gameBoard[gameSpace.target.id] === 'number') {

        turn(gameSpace.target.id, user);
        if (!checkWin(gameBoard, user) && !checkTie()) {
            setTimeout(() => {turn(bestSpot(), computer)}, 400);            
        }
        
    }
}

const turn = (spaceId, player) => {
    gameBoard[spaceId]=player;
    document.getElementById(spaceId).innerHTML= player;

    let gameWon = checkWin(gameBoard, player);
    if (gameWon) {gameOver(gameWon);}

    checkTie();
}

const checkWin=(board, player) => {
    let spaces = board.reduce((acc,ele,idx) => (ele === player) ? acc.concat(idx) : acc, []);
    let gameWon = null;
    for(let [index, winComboSpace] of winCombos.entries()){
        if(winComboSpace.every(elem => spaces.indexOf(elem) > -1)){
            gameWon = {index : index, player : player}
            break;
        }
    }
    return gameWon;
}

const gameOver=gameWon =>{

    for(let index of winCombos [gameWon.index]){
        document.getElementById(index).style.color='#4E6C50';
        document.getElementById(index).style.backgroundColor = '#820000';
    }

    for (let cell of cells){
        cell.removeEventListener('click',handleClick, false);

    }
    declareWinner(gameWon.player === user ? "You Won The Game" : "Computer Won The Game");

}

const declareWinner = message => {
    winner.querySelector('h3').innerHTML=message;

    setTimeout(() => {
        
    playBoard.classList.remove('fadeIn')
    playBoard.classList.add('fadeOut')
    setTimeout(() => {playBoard.style.display='none'}, 250);

    winner.classList.add('fadeIn')
    setTimeout(() => {winner.style.display='block'}, 250);


    }, 1500);

}

const bestSpot = () => {
    return minMax (gameBoard, computer).index;

}

const emptySquares = () =>{
    return gameBoard.filter((elm, i) => i === elm);
}

const checkTie = () =>{
    if (emptySquares().length === 0) {
        selection.classList.remove('fadeOut');
        
    for (let cell of cells){
        cell.style.backgroundColor='#820000';
        cell.removeEventListener('click',handleClick,false);
    }
    declareWinner("The Game Is Tie!");
    return true;
}
    return false;
}

const minMax = (testBoard, player) => {
    let openSpaces = emptySquares(testBoard);

    if (checkWin(testBoard, user))
    return{score: -10};

    else if (checkWin(testBoard, computer))
    return{score: 10};

    if (openSpaces.length === 0)
    return{score: 0};

    let moves = [];

    for (let i = 0; i < openSpaces.length; i++){

        let move = {};
        move.index = testBoard[openSpaces[i]];
        testBoard[openSpaces[i]] = player;

        if(player === computer)
        move.score = minMax(testBoard, user).score;
        else
        move.score = minMax(testBoard, computer).score;

        testBoard[openSpaces[i]]=move.index;

        if ((player === computer && move.score === 10) || (player === user && move.score === -10))
        return move;
        else
        moves.push(move);
    }

    let bestMove, bestScore;
    if (player === computer) {
        bestScore = -1000;
        for (let i = 0; i < moves.length; i++){
            if (moves [i].score > bestScore) {
                bestScore = moves [i].score;
                bestMove = i;

                
            }
        }
        
    }

    else{
        bestScore = 1000;
        for (let i = 0; i < moves.length; i++){
            if (moves [i].score < bestScore) {
                bestScore = moves [i].score;
                bestMove = i;
    }
}
    }
        return moves[bestMove];
}