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.
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...
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...
Write a class (and a client class to test it) that encapsulates a tic-tac-toe board. A...
Write a class (and a client class to test it) that encapsulates a tic-tac-toe board. A tic-tac-toe board looks like a table of three rows and three columns partially or completely filled with the characters X and O. At any point, a cell of that table could be empty or could contain an X or an O. You should have one instance variable, a two-dimensional array of values representing the tic-tac-toe board. This game should involve one human player vs....
If anyone can please write a code for a 5x5 tic tac toe game in matlab...
If anyone can please write a code for a 5x5 tic tac toe game in matlab I would greatly appreciate it. Its extra credit. PLEASE HELP ME :(
C# (Tic-Tac-Toe) Create class TicTacToe that will enable you to write a complete app to play...
C# (Tic-Tac-Toe) Create class TicTacToe that will enable you to write a complete app to play the game of Tic-Tac-Toe. The class contains a private 3-by-3 rectangular array of integers. The constructor should initialize the empty board to all 0s. Allow two human players. Wherever the first player moves, place a 1 in the specified square, and place a 2 wherever the second player moves. Each move must be to an empty square. After each move, determine whether the game...
please create a tic tac toe game with python using only graphics.py library
please create a tic tac toe game with python using only graphics.py library
Perk Company produces three products: Tic, Tac, and Toe. Tic requires 90 machine setups, Tac requires...
Perk Company produces three products: Tic, Tac, and Toe. Tic requires 90 machine setups, Tac requires 80 setups, and Toe requires 330 setups. Berk has identified an activity cost pool with allocated overhead of $18,000 for which the cost driver is machine setups. How much overhead is assigned to the Tic product?
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT