javascriptfunctiondomconstructor

Switching users in tic tac toe game


I am currently working on tic tac toe project with javascript html css. The problem is I did set the constructors by the input of the user but I cannot switch over the user when I play my game

My expectations are be able to switch user when you play your turn. I tried if else by assigning currentplayer to player 1 if player 1 - I want to change it to player2

const gameBoard = (function() {
  // Select DOM elements
  const playerInput1 = document.querySelector("#player-select1");
  const playerButton = document.querySelector(".add-player");
  const playerInput2 = document.querySelector("#player-select2");
  const playerPara1 = document.querySelector(".player1");
  const playerPara2 = document.querySelector(".player2");
  const showPlayers = document.querySelector(".player-shows");
  const boxes = document.querySelectorAll(".box");

  // Game markers
  const gameMarker = ["O", "X"];
  let currentPlayer;
  let player1, player2;

  // Player factory function
  const playerSelection = (name, marker) => {
    let score = 0;
    return {
      name,
      marker,
      getScore: function() {
        return score;
      },
      scorePlus: function() {
        score++;
        return score;
      }
    };
  };

  // Initialize players
  player1 = playerSelection("Name", gameMarker[0]);
  player2 = playerSelection("Name", gameMarker[1]);

  // Event listener for player names
  playerButton.addEventListener("click", () => {
    player2.name = playerInput2.value.trim();
    player1.name = playerInput1.value.trim();

    if (player1.name === "" || player2.name === "") {
      alert("Please enter a name");
    } else {
      playerPara1.textContent = `First Player is: ${player1.name} (${player1.marker})`;
      playerPara2.textContent = `Second Player is: ${player2.name} (${player2.marker})`;
      showPlayers.innerHTML = "";
      showPlayers.append(playerPara1);
      showPlayers.append(playerPara2);

      // Start the game by setting the initial player
      playGame();
    }
  });

  // Add event listeners to boxes
  boxes.forEach((element) => {
    element.addEventListener("click", () => {
      if (element.textContent === "" && currentPlayer) { // Ensure box is empty and a player is set
        element.textContent = currentPlayer.marker; // Mark the box with the current player's marker
        playGame(); // Switch to the next player
      }
    });
  });

  // Function to switch current player
  const playGame = () => {
    if (currentPlayer === player1) {
      player1
    } else if (currentPlayer === player2) {
      player2
    }


  };

  // Return public methods
  return {
    playerSelection,
    playGame
  };
})();
<input type="text" id="player-select1">
<buttton class="add-player">Add</button>
<input type="text" id="player-select2">
<p class="player1"></p>
<p class="player2"></p>

<div class="player-shows"></div>

<div id="board">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<br>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<br>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<br>
</div>


Solution

  • I used @mplungjan's snippet as the point of departure. First, I fixed the CSS so we can actually see something. Next, I have realized that you check whether current player equals with player1 in which case you evaluate to player1 instead of setting the current player to player2 and vice versa, second, you missed the initial initialization, you need to handle the case when current player is still undefined, finally, you are calling game play upon any click as well as upon clicking on a square, so you are switching the player twice when someone clicks on a box, because it's a click on a box as well as a click per se.

    const gameBoard = (function() {
      // Select DOM elements
      const playerInput1 = document.querySelector("#player-select1");
      const playerButton = document.querySelector(".add-player");
      const playerInput2 = document.querySelector("#player-select2");
      const playerPara1 = document.querySelector(".player1");
      const playerPara2 = document.querySelector(".player2");
      const showPlayers = document.querySelector(".player-shows");
      const boxes = document.querySelectorAll(".box");
    
      // Game markers
      const gameMarker = ["O", "X"];
      let currentPlayer;
      let player1, player2;
    
      // Player factory function
      const playerSelection = (name, marker) => {
        let score = 0;
        return {
          name,
          marker,
          getScore: function() {
            return score;
          },
          scorePlus: function() {
            score++;
            return score;
          }
        };
      };
    
      // Initialize players
      player1 = playerSelection("Name", gameMarker[0]);
      player2 = playerSelection("Name", gameMarker[1]);
    
      // Event listener for player names
      playerButton.addEventListener("click", () => {
        showPlayers.innerHTML = "";
        player2.name = playerInput2.value.trim();
        player1.name = playerInput1.value.trim();
    
        if (player1.name === "" || player2.name === "") {
          showPlayers.innerHTML = "Please add two players to start";
          return;
        }  
        playerPara1.textContent = `First Player is: ${player1.name} (${player1.marker})`;
        playerPara2.textContent = `Second Player is: ${player2.name} (${player2.marker})`;
        
        showPlayers.append(playerPara1);
        showPlayers.append(playerPara2);
        currentPlayer = player1; // initialise
    
      });
    
      // Add an event listener to the board
      board.addEventListener("click", (e) => {
        let element = e.target.closest('.box'); // handle nested elements
        if (!element || !currentPlayer || element.textContent.trim() !== "") return;
        element.textContent = currentPlayer.marker;
        playGame();
      });
      // Function to switch current player - using a ternary
      const playGame = () =>  currentPlayer = (currentPlayer === player2) ? player1 : player2;
    
      // Return public methods
      return {
        playerSelection,
        playGame
      };
    })();
    #board {
      display: table;
    }
    
    #board .row {
      display: flex;
    }
    
    .box {
      background-color: gray;
      font-size: xx-large;
      width: 100px;
      height: 100px;
      border: 1px solid black;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <input type="text" id="player-select1" placeholder="please enter a name">
    <button class="add-player">Add</button>
    <input type="text" id="player-select2" placeholder="please enter a name">
    <p class="player1"></p>
    <p class="player2"></p>
    
    <div class="player-shows">Please add two players to start</div>
    
    <div id="board">
      <div class="row">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
      </div>
      <div class="row">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
      </div>
      <div class="row">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
      </div>
    </div>