How would I return a paragraph value into HTML in a tic tac toe game?

Viewed 91

I'm currently trying to learn JS in the browser for one of my college classes. I pretty much have everything functional except for one major thing. I can't get the program to actually register the victory message when the player or PC wins, and after a solution is found it becomes the player's turn infinitely. I tried moving things around in my code and I was able to find a way to bypass this, but it also caused tie games to crash the page because the computer would run calculations forever. Would there be a way to get the victory message without the page crashing?

HTML:

<!DOCTYPE html>
<html lang="en">
   <title>Tic-Tac-Toe</title>
   <style>
      td {
         border: 1px solid lightblue;
         padding: 10px;
         font-size: 64pt;
         font-family: Courier;
         width: 100px;
         height: 100px;
         text-align: center;
      }
   </style>
   <script src="tictactoe.js"></script>

   <body>
      <h1>Tic-Tac-Toe</h1>

      <!-- 3x3 table for the game board -->
      <table id="gameBoard">
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
      </table>
      <p id="turnInfo">TURN INFO</p>
      <input id="newGameButton" type="button" value="New game">
   </body>
</html>

JS:

let playerTurn = true;
let computerMoveTimeout = 0;

window.addEventListener("DOMContentLoaded", domLoaded);

function domLoaded() {
    // Setup the click event for the "New game" button
    let newBtn = document.getElementById("newGameButton");
    newBtn.addEventListener("click", newGame);

    // Create click-event listeners for each cell in the game board
    let cells = getGameBoard();
    for (let cell of cells) {
        cell.addEventListener("click", function () { cellClicked(cell); });
    }

    // Call newGame() to make sure the board is clear
    newGame();
}

// Returns an array of 9 <td> elements that make up the game board. The first 3 
// elements are the top row, the next 3 the middle row, and the last 3 the 
// bottom row. 
function getGameBoard() {
    let gameBoardTable = document.getElementById("gameBoard");
    let result = [];
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            result.push(gameBoardTable.rows[i].cells[j]);
        }
    }
    return result;
}

function newGame() {
    let paragraph = document.getElementById("turnInfo");
    let cells = document.getElementsByTagName("td");
    
    clearTimeout(computerMoveTimeout);
    computerMoveTimeout = 0;
    
    for(i=0; i<cells.length; i++) {
        cells[i].innerHTML = "&nbsp;";
    }
    
    playerTurn = true;
    paragraph.innerHTML = "Your turn";
    
}

function cellClicked(cell) {
    if(playerTurn && cell.innerHTML == "&nbsp;") {
        cell.innerHTML = "X";
        cell.style.color = "red";
        
        switchTurn();
    }
}

function switchTurn() {
    let paragraph = document.getElementById("turnInfo");
    let selector = document.getElementsByTagName("td");
    let counter = 0;
    
    winningRows("X", 0, 1, 2);
    winningRows("X", 0, 3, 6);
    winningRows("X", 0, 4, 8);
    winningRows("X", 1, 4, 7);
    winningRows("X", 2, 5, 8);
    winningRows("X", 2, 4, 6);
    winningRows("X", 3, 4, 5);
    winningRows("X", 6, 7, 8);
    
    winningRows("O", 0, 1, 2);
    winningRows("O", 0, 3, 6);
    winningRows("O", 0, 4, 8);
    winningRows("O", 1, 4, 7);
    winningRows("O", 2, 5, 8);
    winningRows("O", 2, 4, 6);
    winningRows("O", 3, 4, 5);
    winningRows("O", 6, 7, 8);
    
    for(i=0; i<selector.length; i++) {
        if(selector[i].innerHTML == "X" || selector[i].innerHTML == "O") {
            counter++;
        }
    }
    
    if(counter > 8) {
        paragraph.innerHTML = "TIE!";
        playerTurn = false;
        return;
    }
    
    else {
        if(playerTurn) {
            paragraph.innerHTML = "Computer's turn";
            playerTurn = false;
            computerMoveTimeout = setTimeout(makeComputerMove, 1000);
        }
        else {
            paragraph.innerHTML = "Your turn";
            playerTurn = true;
        }
    }
    
}

function winningRows(letter, num1, num2, num3) {
    let selector = document.getElementsByTagName("td");
    let paragraph = document.getElementById("turnInfo");
    
    if(letter == "X" && selector[num1].innerHTML == letter) {
        if(selector[num1].innerHTML == selector[num2].innerHTML && selector[num2].innerHTML == selector[num3].innerHTML) {
            paragraph.innerHTML = "You win!";
            playerTurn = false;
            return;
        }
    }
    if(letter == "O" && selector[num1].innerHTML == letter) {
        if(selector[num1].innerHTML == selector[num2].innerHTML && selector[num2].innerHTML == selector[num3].innerHTML) {
            paragraph.innerHTML = "Computer wins!";
            playerTurn = false;
            return;
        }
    }
}

function makeComputerMove() {
    let selector = document.getElementsByTagName("td");
    let paragraph = document.getElementById("turnInfo");
    let freespot;
    let found = false;
    
    while(found == false) {
        freespot = Math.floor(Math.random() * selector.length);
        
        console.log(freespot);
        if(selector[freespot].innerHTML != "X" && selector[freespot].innerHTML != "O") {
            selector[freespot].innerHTML = "O";
            selector[freespot].style.color = "blue";
            found = true;
        }
    }
    
    switchTurn();
}
1 Answers

let playerTurn = true;
let gameFinished = false;
let computerMoveTimeout = 0;

window.addEventListener("DOMContentLoaded", domLoaded);

function domLoaded() {
    // Setup the click event for the "New game" button
    let newBtn = document.getElementById("newGameButton");
    newBtn.addEventListener("click", newGame);

    // Create click-event listeners for each cell in the game board
    let cells = getGameBoard();
    for (let cell of cells) {
        cell.addEventListener("click", function () { cellClicked(cell); });
    }

    // Call newGame() to make sure the board is clear
    newGame();
}

// Returns an array of 9 <td> elements that make up the game board. The first 3 
// elements are the top row, the next 3 the middle row, and the last 3 the 
// bottom row. 
function getGameBoard() {
    let gameBoardTable = document.getElementById("gameBoard");
    let result = [];
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            result.push(gameBoardTable.rows[i].cells[j]);
        }
    }
    return result;
}

function newGame() {
    gameFinished = false;
    let paragraph = document.getElementById("turnInfo");
    let cells = document.getElementsByTagName("td");
    
    clearTimeout(computerMoveTimeout);
    computerMoveTimeout = 0;
    
    for(i=0; i<cells.length; i++) {
        cells[i].innerHTML = "&nbsp;";
    }
    
    playerTurn = true;
    paragraph.innerHTML = "Your turn";
    
}

function cellClicked(cell) {
    if(playerTurn && cell.innerHTML == "&nbsp;") {
        cell.innerHTML = "X";
        cell.style.color = "red";
        
        switchTurn();
    }
}

function switchTurn() {
    let paragraph = document.getElementById("turnInfo");
    let selector = document.getElementsByTagName("td");
    let counter = 0;
    
    winningRows("X", 0, 1, 2);
    winningRows("X", 0, 3, 6);
    winningRows("X", 0, 4, 8);
    winningRows("X", 1, 4, 7);
    winningRows("X", 2, 5, 8);
    winningRows("X", 2, 4, 6);
    winningRows("X", 3, 4, 5);
    winningRows("X", 6, 7, 8);
    
    winningRows("O", 0, 1, 2);
    winningRows("O", 0, 3, 6);
    winningRows("O", 0, 4, 8);
    winningRows("O", 1, 4, 7);
    winningRows("O", 2, 5, 8);
    winningRows("O", 2, 4, 6);
    winningRows("O", 3, 4, 5);
    winningRows("O", 6, 7, 8);
    
    if (gameFinished) {
       return;
    }
    
    for(i=0; i<selector.length; i++) {
        if(selector[i].innerHTML == "X" || selector[i].innerHTML == "O") {
            counter++;
        }
    }
    
    if(counter > 8) {
        paragraph.innerHTML = "TIE!";
        playerTurn = false;
        return;
    }
    
    else {
        if(playerTurn) {
            paragraph.innerHTML = "Computer's turn";
            playerTurn = false;
            computerMoveTimeout = setTimeout(makeComputerMove, 1000);
        }
        else {
            paragraph.innerHTML = "Your turn";
            playerTurn = true;
        }
    }
    
}

function winningRows(letter, num1, num2, num3) {
    let selector = document.getElementsByTagName("td");
    let paragraph = document.getElementById("turnInfo");
    
    if(letter == "X" && selector[num1].innerHTML == letter) {
        if(selector[num1].innerHTML == selector[num2].innerHTML && selector[num2].innerHTML == selector[num3].innerHTML) {
            paragraph.innerHTML = "You win!";
            playerTurn = false;
            gameFinished = true;
            return;
        }
    }
    if(letter == "O" && selector[num1].innerHTML == letter) {
        if(selector[num1].innerHTML == selector[num2].innerHTML && selector[num2].innerHTML == selector[num3].innerHTML) {
            paragraph.innerHTML = "Computer wins!";
            playerTurn = false;
            gameFinished = true;
            return;
        }
    }
}

function makeComputerMove() {
    let selector = document.getElementsByTagName("td");
    let paragraph = document.getElementById("turnInfo");
    let freespot;
    let found = false;
    
    while(found == false) {
        freespot = Math.floor(Math.random() * selector.length);
        
        console.log(freespot);
        if(selector[freespot].innerHTML != "X" && selector[freespot].innerHTML != "O") {
            selector[freespot].innerHTML = "O";
            selector[freespot].style.color = "blue";
            found = true;
        }
    }
    
    switchTurn();
}
<!DOCTYPE html>
<html lang="en">
   <title>Tic-Tac-Toe</title>
   <style>
      td {
         border: 1px solid lightblue;
         padding: 10px;
         font-size: 64pt;
         font-family: Courier;
         width: 100px;
         height: 100px;
         text-align: center;
      }
   </style>
   <script src="tictactoe.js"></script>

   <body>
      <h1>Tic-Tac-Toe</h1>

      <!-- 3x3 table for the game board -->
      <table id="gameBoard">
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
         <tr>
            <td></td>
            <td></td>
            <td></td>
         </tr>
      </table>
      <p id="turnInfo">TURN INFO</p>
      <input id="newGameButton" type="button" value="New game">
   </body>
</html>

Related