Question

In: Computer Science

For this assignment, you will write a tic-tac-toe application in HTML and JavaScript, using an HTML...

For this assignment, you will write a tic-tac-toe application in HTML and JavaScript, using an HTML <canvas> tag. The game will be played "hot seat" where players take turns using the same device.

Requirements:

  1. The canvas should be 600px tall and wide, with the gameplay area occupying most of the canvas.
    1. The X's and O's may be drawn using polygons or large-font text
    2. The grid should be drawn using polygons, specifically long, thin rectangles
  2. Before & between games, the canvas will show an "attract mode" screen showing a blank 3x3 grid in the canvas
  3. Additional HTML components:
    1. Two <input> tags, appropriately labeled, where the players can enter their names
    2. An appropriately-label HTML <button> that starts the game
  4. Gameplay:
    1. Players will be randomly assigned to X and O, with X moving first
    2. Players will take turns placing X's and O's by clicking on open grid squares
    3. Text written on the canvas will indicate which player's turn by name and X or O, e.g., if it's Joe's turn and Joe is X, the text would read "Joe (X) to move"
    4. Invalid moves should not be permitted but no game action is required when a player clicks on an unavailable square
  5. After each player's move, the game will check whether the game has ended
    1. After a victory, a line will be drawn through every winning sequence of X's or O's – note that a winning move might make more than one winning sequence – and congratulatory text will appear on the canvas, e.g, if Joe wins, it might read "Joe wins!"
    2. If the grid is filled without a winner, the text "tie game" will appear on the canvas
    3. In either case, a timer will start - after five seconds, the canvas will return to attract mode with the players' names retained in the input tags

Solutions

Expert Solution

I am pasting the codes with its filenames.

Make sure you make the same filenames :

Put all the files in same folder and the 3 png images in a img folder

file : index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Tic Tac Toe</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <canvas id="cvs" width="450" height="450"></canvas>
        <div class="options">
            <h1>Tic Tac Toe</h1>
            <input type="text" id="player-name" placeholder="Enter Name">
            <h2>Play Versus</h2>
            <div class="computer">COMPUTER</div>
            <div class="friend">FRIEND</div>

            <h2>Symbol</h2>
            <div class="x">X</div>
            <div class="o">O</div>

            <div class="play">PLAY</div>
        </div>
        <div class="gameover hide"></div>
    </div>

    <script src="options.js"></script>
    <script src="game.js"></script>
</body>
</html>

file : style.css


@font-face {
    font-family: 'Fascinate Inline';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: local('Fascinate Inline'), local('FascinateInline-Regular'), url(font/jVyR7mzzB3zc-jp6QCAu60poNqIy5grIfA.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
  }

.container{
    width: 450px;
    height: 450px;
    display: block;
    margin: 25px auto;
    position: relative;
}

#cvs{
    position: absolute;
    border: 1px solid #000;
}

.options{
    position: absolute;
    width: 450px;
    height: 450px;
}

.options h1{
    text-align: center;
    font-size: 65px;
    font-family: 'Fascinate Inline', cursive;
    color: #f00;
    margin: 30px 0 20px 0;
}

.options h2{
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    text-align: center;
    font-weight: bold;
}

.options div{
    display: inline-block;
}

.options .computer, .x{
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    padding: 5px;
    background-color: #FFF;
    color: #000;
    font-size: 1.5em;
    border-radius: 5px;
    margin-left: 70px;
    width: 150px;
    text-align: center;
    cursor: pointer;
    border: 1px solid #000;
}

.options .friend, .o{
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    padding: 5px;
    background-color: #FFF;
    color: #000;
    font-size: 1.5em;
    border-radius: 5px;
    margin-left: 10px;
    width: 150px;
    text-align: center;
    cursor: pointer;
    border: 1px solid #000;
}

.options .friend:hover, .computer:hover, .x:hover, .o:hover{
    background-color: #011627;
    color: #FFF;
}

.options .play{
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    font-size: 1.5em;
    width: 70px;
    display: block;
    margin: 25px auto;
    border-radius: 5px;
    border: 1px solid #011627;
    text-align: center;
    padding: 10px;
    background-color: #011627;
    color: #FFF;
    cursor: pointer;
    transition: 100ms width ease-in;
}
.options .play:hover{
    width: 110px;
}

.active{
    background-color: #011627 !important;
    color: #FFF !important;
}

.hide{
    display: none;
}

.gameover{
    position: absolute;
    width: 450px;
    height: 450px;
    background-color: rgba(0, 0, 0, 0.95);
}
.gameover h1{
    text-align: center;
    font-size: 50px;
    font-family: 'Fascinate Inline', cursive;
    color: #fff;
    margin: 40px 0 20px 0;
}

.gameover .winner-img{
    display: block;
    margin: 20px auto;
}

.gameover .play{
    font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
    font-size: 1.5em;
    width: 150px;
    display: block;
    margin: 25px auto;
    border-radius: 5px;
    border: 1px solid #fff;
    text-align: center;
    padding: 10px;
    background-color: #fff;
    color: #000;
    cursor: pointer;
    transition: 100ms width ease-in;
}
.gameover .play:hover{
    width: 200px;
}
#player-name{
    border: 3px solid black;
    border-radius: 6px;
    padding: 10px;
    width: 80%;
    margin-left: 35px;
    font-size: 20px;
    text-transform: uppercase;
    font-weight: bold;
}

file : options.js

const options = document.querySelector(".options");

const computerBtn = document.querySelector(".computer");
const friendBtn = document.querySelector(".friend");
const xBtn = document.querySelector(".x");
const oBtn = document.querySelector(".o");
const playBtn = document.querySelector(".play");

const gameOverElement = document.querySelector(".gameover");

const player = new Object;
let OPPONENT;

oBtn.addEventListener("click", function(){
    player.man = "O";
    player.computer = "X";
    player.friend = "X";

    switchActive(xBtn, oBtn);
});

xBtn.addEventListener("click", function(){
    player.man = "X";
    player.computer = "O";
    player.friend = "O";

    switchActive(oBtn, xBtn);
});
 
computerBtn.addEventListener("click", function(){
    OPPONENT = "computer";
    switchActive(friendBtn, computerBtn);
});

friendBtn.addEventListener("click", function(){
    OPPONENT = "friend";
    switchActive(computerBtn, friendBtn);
});

playBtn.addEventListener("click", function(){
    let name=document.querySelector("#player-name").value;
    if( !OPPONENT){
        computerBtn.style.backgroundColor = "red";
        friendBtn.style.backgroundColor = "red";
        return;
    }

    if( !player.man ){
        oBtn.style.backgroundColor = "red";
        xBtn.style.backgroundColor = "red";
        return;
    }
    
    init(player, OPPONENT,name);
    console.log(player)
    options.classList.add("hide");
});

function switchActive(off, on){
    off.classList.remove("active");
    on.classList.add("active");
}

file : game.js

function init(player, OPPONENT,name){
    console.log(name);
    const canvas = document.getElementById("cvs");
    const ctx = canvas.getContext("2d");

    let board = [];
    const COLUMN = 3;
    const ROW = 3;
    const SPACE_SIZE = 150;

    let gameData = new Array(9);
    
    let currentPlayer = player.man;

    const xImage = new Image();
    xImage.src = "img/X.png";

    const oImage = new Image();
    oImage.src = "img/O.png";

    const COMBOS = [
        [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 GAME_OVER = false;
    
    function drawBoard(){
        let id = 0
        for(let i = 0; i < ROW; i++){
            board[i] = [];
            for(let j = 0; j < COLUMN; j++){
                board[i][j] = id;
                id++;

                ctx.strokeStyle = "#000";
                ctx.strokeRect(j * SPACE_SIZE, i * SPACE_SIZE, SPACE_SIZE, SPACE_SIZE);
            }
        }
    }
    drawBoard();

    canvas.addEventListener("click", function(event){
        
        if(GAME_OVER) return;

        let X = event.clientX - canvas.getBoundingClientRect().x;
        let Y = event.clientY - canvas.getBoundingClientRect().y;

        let i = Math.floor(Y/SPACE_SIZE);
        let j = Math.floor(X/SPACE_SIZE);

        let id = board[i][j];

        if(gameData[id]) return;

        gameData[id] = currentPlayer;
        
        drawOnBoard(currentPlayer, i, j);

        if(isWinner(gameData, currentPlayer)){
            showGameOver(currentPlayer);
            GAME_OVER = true;
            return;
        }

        if(isTie(gameData)){
            showGameOver("tie");
            GAME_OVER = true;
            return;
        }

        if( OPPONENT == "computer"){
            let id = minimax( gameData, player.computer ).id;

            gameData[id] = player.computer;
            
            let space = getIJ(id);

            drawOnBoard(player.computer, space.i, space.j);

            if(isWinner(gameData, player.computer)){
                showGameOver(player.computer);
                GAME_OVER = true;
                return;
            }

            if(isTie(gameData)){
                showGameOver("tie");
                GAME_OVER = true;
                return;
            }
        }else{
            currentPlayer = currentPlayer == player.man ? player.friend : player.man;
        }

    });

    function minimax(gameData, PLAYER){
        if( isWinner(gameData, player.computer) ) return { evaluation : +10 };
        if( isWinner(gameData, player.man)      ) return { evaluation : -10 };
        if( isTie(gameData)                     ) return { evaluation : 0 };

        let EMPTY_SPACES = getEmptySpaces(gameData);
        let moves = [];

        for( let i = 0; i < EMPTY_SPACES.length; i++){
            let id = EMPTY_SPACES[i];
            let backup = gameData[id];
            gameData[id] = PLAYER;
            let move = {};
            move.id = id;
            if( PLAYER == player.computer){
                move.evaluation = minimax(gameData, player.man).evaluation;
            }else{
                move.evaluation = minimax(gameData, player.computer).evaluation;
            }
            gameData[id] = backup;
            moves.push(move);
        }

        let bestMove;

        if(PLAYER == player.computer){
            let bestEvaluation = -Infinity;
            for(let i = 0; i < moves.length; i++){
                if( moves[i].evaluation > bestEvaluation ){
                    bestEvaluation = moves[i].evaluation;
                    bestMove = moves[i];
                }
            }
        }else{
            let bestEvaluation = +Infinity;
            for(let i = 0; i < moves.length; i++){
                if( moves[i].evaluation < bestEvaluation ){
                    bestEvaluation = moves[i].evaluation;
                    bestMove = moves[i];
                }
            }
        }

        return bestMove;
    }

    function getEmptySpaces(gameData){
        let EMPTY = [];

        for( let id = 0; id < gameData.length; id++){
            if(!gameData[id]) EMPTY.push(id);
        }

        return EMPTY;
    }

    function getIJ(id){
        for(let i = 0; i < board.length; i++){
            for(let j = 0; j < board[i].length; j++){
                if(board[i][j] == id) return { i : i, j : j}
            }
        }
    }

    function isWinner(gameData, player){
        for(let i = 0; i < COMBOS.length; i++){
            let won = true;

            for(let j = 0; j < COMBOS[i].length; j++){
                let id = COMBOS[i][j];
                won = gameData[id] == player && won;
            }

            if(won){
                return true;
            }
        }
        return false;
    }

    function isTie(gameData){
        let isBoardFill = true;
        for(let i = 0; i < gameData.length; i++){
            isBoardFill = gameData[i] && isBoardFill;
        }
        if(isBoardFill){
            return true;
        }
        return false;
    }
    function showGameOver(player){
        console.log(currentPlayer,name,player)
        let str=name;
        if(currentPlayer!==player){
            str="Player 2";
        }
        let message = player == "tie" ? "Oops No Winner" : `The Winner is ${str}`;
        let imgSrc = `img/${player}.png`;

        gameOverElement.innerHTML = `
            <h1>${message}</1>
            <img class="winner-img" src=${imgSrc} </img>
            <div class="play" onclick="location.reload()">Play Again!</div>
        `;

        gameOverElement.classList.remove("hide");
    }
    function drawOnBoard(player, i, j){
        let img = player == "X" ? xImage : oImage;
        ctx.drawImage(img, j * SPACE_SIZE, i * SPACE_SIZE);
    }
}

'X.png', 'O.png' and "tie.png" (place in "img" folder)


Related Solutions

How to make tic tac toe game in javascript with vue.js
How to make tic tac toe game in javascript with vue.js
Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3...
Write a program that plays tic-tac-toe. The tic-tac-toe game is played on a 3 × 3 grid as shown below: The game is played by two players, who take turns. The first player marks moves with a circle, the second with a cross. The player who has formed a horizontal, vertical, or diagonal sequence of three marks wins. Your program should draw the game board, ask the user for the coordinates of the next mark (their move), change the players...
Use JavaScript/HTML to create a Tic Tac Toe game displaying X's O's. Score the result. Each...
Use JavaScript/HTML to create a Tic Tac Toe game displaying X's O's. Score the result. Each player takes a turn putting their mark until done or tied.
make a 4x4 tic tac toe in javascript (X is the user) (O is the computer)
make a 4x4 tic tac toe in javascript (X is the user) (O is the computer)
PYTHON (Game: Tic-tac-toe): Write a program that plays the tic-tac-toe game. Two players take turns clicking...
PYTHON (Game: Tic-tac-toe): Write a program that plays the tic-tac-toe game. Two players take turns clicking an available cell in a 3 x 3 grid with their respective tokens (either X or O). When one player has placed three tokens in a horizontal, vertical, or diagonal row on the grid, the game is over and that player has won. A draw (no winner) occurs when all the cells in the grid have been filled with tokens and neither player has...
The objective of this assignment is to implement the tic-tac-toe game with a C program. The...
The objective of this assignment is to implement the tic-tac-toe game with a C program. The game is played by two players on a board defined as a 5x5 grid (array). Each board position can contain one of two possible markers, either ‘X’ or ‘O’. The first player plays with ‘X’ while the second player plays with ‘O’. Players place their markers in an empty position of the board in turns. The objective is to place 5 consecutive markers of...
If you were to write a game of tic-tac-toe, you may store the representation of the...
If you were to write a game of tic-tac-toe, you may store the representation of the game board as a two dimensional list such as   [['X', '', 'X'], ['O', 'X', ''], ['', 'O', 'X']] where each sublist is a row in the board.   Empty strings ('') denote a space that does not yet have a value. Assuming this representation, write functions (contained in the same file) that do the following: a) Create a new empty tic-tac-toe board. This function should...
Using C language Problem!! <3 x 3 tic tac toe> 2 players are doing tic tac...
Using C language Problem!! <3 x 3 tic tac toe> 2 players are doing tic tac toe alternatively. Anyone could win when they first make a bingo for any line(horizontal, vertical, diagonal) [Constraints] 1. Use 2dimensional Array(3 X 3) 2. Each elements are 1 or 2 so that can show their player1, player2's mark. 3. Inputs are 1 through 9 as you can see 1 2 3 4 5 6 7 8 9 4. No inputs are duplicated 5. if...
Programming assignment (100 pts): In the C++ programming language write a program capable of playing Tic-Tac-Toe...
Programming assignment (100 pts): In the C++ programming language write a program capable of playing Tic-Tac-Toe against the user. Your program should use OOP concepts in its design. You can use ASCII art to generate and display the 3x3 playing board. The program should randomly decide who goes first computer or user. Your program should know and inform the user if an illegal move was made (cell already occupied). The program should also announce if one of the players wins...
Python Code Needed Two-Player, Two-Dimensional Tic-Tac-Toe Write a script to play two-dimensional Tic-Tac-Toe between two human...
Python Code Needed Two-Player, Two-Dimensional Tic-Tac-Toe Write a script to play two-dimensional Tic-Tac-Toe between two human players who alternate entering their moves on the same computer. Create a 3-by-3 two-dimensional array. Each player indicates their moves by entering a pair of numbers representing the row and column indices of the square in which they want to place their mark, either an 'X' or an 'O'. When the first player moves, place an 'X' in the specified square. When the second...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT