Skip to main content

My reset button not resetting the game mode in Tic Tac Toe (Noughts and Crosses)

I have created a Tic Tac Toe game (Noughts and Crosses in the UK!) and have finished almost everything except perhaps improving the computer AI (its just random at the moment).

However, there is one bug that I can't seem to fix. When you first play the game you get the choice of playing against another human (player 2) or computer. Once this "human" or "computer" button is pressed it will save the information in a variable "let choiceComp" as either "human" or "comp". This will then call their respective functions, computerGame() or humanGame(), once the player enters their details and the subsequent start button is pressed.

This works fine the first time around but when the reset button is pressed and the alternative game mode is selected (e.g. human first, then computer second - or vice versa), the same game mode will continue as the first time. I've reset the choiceComp variable as an empty string, along with everything else I can think of, but this doesn't reset the game mode. Just wondering if someone can help me. I've added everything I can think of into the reset button but there is still something that I am missing, but I cannot figure out what.

Here is my HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Noughts & Crosses</title>
  <link rel="stylesheet" href="styles.css" />
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Black+Ops+One&display=swap" rel="stylesheet">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
  <script src="script.js" defer></script>
</head>
<body>
  <div class="outer-container">
    <div class="title-container">
      <img src="noughts.PNG" alt="noughts-image">
      <h1 class="title">NOUGHTS & CROSSES</h1>
      <img src="crosses.PNG" alt="crosses-image">
    </div>

    <button class="reset-button">Reset</button>

    <div class="container">
      <div id="0" class="square"></div>
      <div id="1" class="square"></div>
      <div id="2" class="square"></div>
      <div id="3" class="square"></div>
      <div id="4" class="square"></div>
      <div id="5" class="square"></div>
      <div id="6" class="square"></div>
      <div id="7" class="square"></div>
      <div id="8" class="square"></div>
    </div>

    <div>
      <div>
        <div class="display"></div>
        <div class="display2"></div>
        <div>
          <div class="display-images-container">
            <img class="player1-display-pic" src="player1.PNG" alt="player1-image">
            <img class="player2-display-pic" src="player2.PNG" alt="player2-image">
            <img class="comp-display-pic" class="computer-button" src="computer.PNG" alt="computer-image">
          </div>
        </div>
      </div>

      <div class="human-or-comp-container">
        <div class="human-or-comp-title">Play against Human or Computer?</div>
        <div class="image-container">
          <img class="human-button" src="human.PNG" alt="human-image">
          <img class="computer-button" src="computer.PNG" alt="computer-image">
        </div>
      </div>
    </div>
    <form>
      <div class="input-container">
        <div class="player-input-container" id="player-one-form">
          <p>Player One</p>
          <div class="player-image-container">
            <img src="player1.PNG" alt="player1-image">
          </div>
          <input type="text" id="nameOne" placeholder="Player 1" />
          <div class="radio-buttons-container">
            <label for="radio">Selection</label>
            <input type="radio" name="typeSelectOne" id="noughtsOne" value="0"></input>
            <label for="noughtsOne">0's</label>
            <input type="radio" name="typeSelectOne" id="crossesOne" value="X"></input>
            <label for="crossesOne">X's</label>
          </div>
        </div>

        <div class="player-input-container" id="player-two-form">
          <p>Player Two</p>
          <div class="player-image-container">
            <img src="player2.PNG" alt="player2-image">
          </div>
          <div>
            <input type="text" id="nameTwo" placeholder="Player 2" />
          </div>
        </div>

        <div class="player-input-container" id="computer-form">
          <p>Computer</p>
          <div class="computerForm">
            <img class="computer-button" src="computer.PNG" alt="computer-image">
          </div>
        </div>
      </div>
      <div class="button-container">
        <button class="start-button" type="start" id="start-button">Start</button>
      </div>
    </form>
  </div>
</div>
</body>
</html>

My JS

const container = document.querySelector(".container");
const squares = document.querySelectorAll(".square");
const playerOneName = document.querySelector("#nameOne");
const playerTwoName = document.querySelector("#nameTwo");
const startButton = document.querySelector("#start-button");
const display = document.querySelector(".display");
const display2 = document.querySelector(".display2");
const inputContainer = document.querySelector(".input-container");
const noughtsSymbol = document.getElementById("noughts");
const humanOrComp = document.querySelector(".human-or-comp-container");
const playerOneForm = document.querySelector("#player-one-form");
const playerTwoForm = document.querySelector("#player-two-form");
const computerForm = document.querySelector("#computer-form");
const resetButton = document.querySelector(".reset-button");
const playerOnePic = document.querySelector(".player1-display-pic");
const playerTwoPic = document.querySelector(".player2-display-pic");
const compPic = document.querySelector(".comp-display-pic");

const humanButton = document.querySelector(".human-button");
const computerButton = document.querySelector(".computer-button");

// Create Player Object (Factory)humanOrComp

function createPlayer(name, type) {
  const newPlayer = {};
  newPlayer.name = name;
  newPlayer.type = type;
  return newPlayer;
}

let playerOne;
let playerTwo;
let player;

// GameBoard (IIFE Module)

const GameBoard = (function () {
  const gameBoardArr = ["", "", "", "", "", "", "", "", ""];

  let squareID = "";

  const computerGame = function () {
    squares.forEach((square) => {
      square.addEventListener("click", (event) => {
        if (square.innerText === "") {
          player = playerOne.type;
          square.innerText = playerOne.type;
          squareID = event.target.id;
          gameBoardArr[squareID] = playerOne.type;
          computerAI();
          winner();
        }
      });
    });
  };

  const humanGame = function () {
    let turn = 0;
    squares.forEach((square) => {
      square.addEventListener("click", (event) => {
        if (turn == 0 && square.innerText === "") {
          player = playerOne.type;
          square.innerText = playerOne.type;
          squareID = event.target.id;
          gameBoardArr[squareID] = playerOne.type;
          turn = 1;
          winner();
          display2.innerText = `${playerTwo.name}'s turn`;
        } else if (turn === 1 && square.innerText === "") {
          player = playerTwo.type;
          square.innerText = playerTwo.type;
          squareID = event.target.id;
          gameBoardArr[squareID] = playerTwo.type;
          turn = 0;
          winner();
          display2.innerText = `${playerOne.name}'s turn`;
        }
      });
    });
  };

  let choiceComp = "";

  humanButton.addEventListener("click", () => {
    choiceComp = "human";
    inputContainer.style.display = "flex";
    humanOrComp.style.display = "none";
    playerOneForm.style.display = "flex";
    playerTwoForm.style.display = "flex";
    startButton.style.display = "block";
  });

  computerButton.addEventListener("click", () => {
    choiceComp = "comp";
    inputContainer.style.display = "flex";
    humanOrComp.style.display = "none";
    playerOneForm.style.display = "flex";
    computerForm.style.display = "flex";
    startButton.style.display = "block";
  });

  startButton.addEventListener("click", (event) => {
    event.preventDefault();
    playerOne = createPlayer(playerOneName.value, document.querySelector(`input[name="typeSelectOne"]:checked`).value);
    playerTwo = createPlayer(playerTwoName.value, playerOne.type === "X" ? "0" : "X");
    container.style.display = "grid";
    resetButton.style.display = "block";
    display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;

    if (choiceComp === "human") {
      playerOnePic.style.display = "block";
      playerTwoPic.style.display = "block";
      display2.innerText = `${playerOne.name}'s turn`;
      humanGame();
    } else if (choiceComp === "comp") {
      playerTwo.name = "Computer";
      display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
      playerOnePic.style.display = "block";
      compPic.style.display = "block";
      computerGame();
    }
    inputContainer.style.display = "none";
    startButton.style.display = "none";
  });

  resetButton.addEventListener("click", () => {
    playerOne = {};
    playerTwo = {};
    GameBoard.gameBoardArr = ["", "", "", "", "", "", "", "", ""];
    display.innerText = "";
    display2.innerText = "";
    clearBoard();
    container.style.display = "none";
    playerOneForm.style.display = "none";
    playerTwoForm.style.display = "none";
    computerForm.style.display = "none";
    humanOrComp.style.display = "flex";
    playerOneName.value = "";
    playerTwoName.value = "";
    choiceComp = "";
    resetButton.style.display = "none";
    playerOnePic.style.display = "none";
    playerTwoPic.style.display = "none";
    compPic.style.display = "none";
  });

  const computerAI = function () {
    const emptySquares = [];
    for (let i = 0; i < gameBoardArr.length; i++) {
      if (gameBoardArr[i] === "") {
        emptySquares.push(i);
      }
    }
    if (emptySquares.length > 0) {
      const randomIndex = Math.floor(Math.random() * emptySquares.length);
      const squareID = emptySquares[randomIndex];
      document.getElementById(squareID).innerText = playerTwo.type;
      gameBoardArr[squareID] = playerTwo.type;
    }
  };

  const winner = function () {
    const winnerLines = [
      [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 isDraw = true;

    for (const line of winnerLines) {
      const [a, b, c] = line;
      if (gameBoardArr[a] === "0" && gameBoardArr[b] === "0" && gameBoardArr[c] === "0") {
        setTimeout(function () {
          display.innerText = `${playerOne.name} wins`;
        }, 200);
        setTimeout(function () {
          display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
          clearBoard();
        }, 3000);
        isDraw = false;
      } else if (gameBoardArr[a] === "X" && gameBoardArr[b] === "X" && gameBoardArr[c] === "X") {
        setTimeout(function () {
          display.innerText = `${playerTwo.name} wins`;
        }, 200);
        setTimeout(function () {
          display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
          clearBoard();
        }, 3000);
        isDraw = false;
      }
    }
    if (isDraw && gameBoardArr.every((el) => el !== "")) {
      setTimeout(function () {
        display.innerText = "Draw";
      }, 200);
      setTimeout(function () {
        display.innerText = `${playerOne.name} is ${playerOne.type}'s. ${playerTwo.name} is ${playerTwo.type}'s.`;
        clearBoard();
      }, 3000);
    }
  };

  const clearBoard = function () {
    for (let i = 0; i < gameBoardArr.length; i++) {
      gameBoardArr[i] = "";
    }
    squares.forEach((square) => (square.innerText = ""));
  };

  return { gameBoardArr };
})();

And CSS

.outer-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.title-container {
  display: flex;
  align-items: center;
}

.title {
  font-size: 60px;
  font-family: "Black Ops One";
  margin: 20px;
}

p {
  font-size: 30px;
  font-weight: bold;
  font-family: "Black Ops One";
}

/* Main Square Grid */

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  padding: 30px 30px;
  display: none;
}

.square {
  border: 1px solid black;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 80px;
  font-family: "Black Ops One";
}

.square:hover {
  background-color: yellow;
  opacity: 0.5;
  cursor: pointer;
}

/* Human or Computer Form */

.human-or-comp-container {
  margin-top: 100px;
  display: flex;
  flex-direction: column;
}

.human-or-comp-title {
  font-size: 30px;
  margin-bottom: 20px;
  font-family: "VT323", monospace;
}

.image-container {
  display: flex;
  justify-content: space-between;
}

.human-or-comp-container img {
  cursor: pointer;
}

.human-or-comp-container img:hover {
  width: 120px;
  height: 120px;
}

img {
  width: 100px;
  height: 100px;
}

/* Display */

.display,
.display2 {
  font-size: 30px;
  font-size: 40px;
  text-align: center;
  margin-bottom: 20px;
  font-family: "VT323", monospace;
}

.display-images-container {
  display: flex;
  justify-content: space-between;
}

.player1-display-pic,
.player2-display-pic,
.comp-display-pic {
  display: none;
}

/* Input forms */

.input-container {
  display: flex;
  justify-content: space-between;
  width: 600px;
  margin-top: 100px;
}

.player-input-container {
  display: flex;
  flex-direction: column;
  width: 250px;
  text-align: center;
}

#player-one-form {
  display: none;
}

#player-two-form {
  display: none;
}

#computer-form {
  display: none;
}

.button-container {
  display: flex;
  justify-content: center;
}

.radio-buttons-container {
  display: flex;
}

input[type="text"] {
  background-color: #f5f5f5;
  height: 25px;
  width: 90%;
  padding: 2px 23px 2px 30px;
  border: 1px solid grey;
  border-radius: 10px;
  margin-bottom: 10px;
  margin-top: 20px;
}

label {
  font-family: "Black Ops One";
}

#nameOne,
#nameTwo {
  font-family: "VT323", monospace;
}

#nameOne::placeholder,
#nameTwo::placeholder {
  font-family: "VT323", monospace;
}

.start-button,
.reset-button,
.decide-button {
  display: inline-block;
  outline: 0;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  position: relative;
  color: #000;
  background: #fff;
  line-height: 30px;
  border-radius: 40px;
  padding: 20px;
  font-size: 30px;
  font-weight: 600;
  box-shadow: rgb(255, 198, 0) -2px -2px 0px 2px, rgb(246, 84, 174) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 0px 2px 7px;
  transition: all 0.2s;
}

.start-button:hover,
.reset-button:hover,
.decide-button:hover {
  box-shadow: rgb(246, 84, 174) -2px -2px 0px 2px, rgb(255, 198, 0) 0px 0px 0px 4px, rgba(0, 0, 0, 0.05) 0px 0px 2px 7px;
  transform: scale(1.01);
}

.start-button {
  display: none;
}

.reset-button {
  display: none;
}

Via Active questions tagged javascript - Stack Overflow https://ift.tt/VZvXegw

Comments

Popular posts from this blog

Prop `className` did not match in next js app

I have written a sample code ( Github Link here ). this is a simple next js app, but giving me error when I refresh the page. This seems to be the common problem and I tried the fix provided in the internet but does not seem to fix my issue. The error is Warning: Prop className did not match. Server: "MuiBox-root MuiBox-root-1" Client: "MuiBox-root MuiBox-root-2". Did changes for _document.js, modified _app.js as mentioned in official website and solutions in stackoverflow. but nothing seems to work. Could someone take a look and help me whats wrong with the code? Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console