How to increase the size of an array on individual element clicks

51 Views Asked by At

I've decided to get out of tutorial hell and challenge myself by making an X an O'S (tic-tac-toe) game by myself. As shown below. I have managed to make the functions that will display X and O on click. But now I need to enable the display of X and O to alternate on every click. I am trying to make an array whose length increases on every button click. If the array's length is even O is displayed, if array's length is odd, X is displayed. But the array's length is only 1 on every click. How do I get the array's size to actually increase on every click?

Also for some odd reason the X is not being displayed on every odd click. What could the problem be?

JavaScript code:

for (let num = 1; num <= 9; num++) {
  const text = document.querySelector("#box" + num + " h1");
  const box = document.querySelector("#box" + num);
  // let boxCounted = document.getElementsByClassName("square");

  //current click
  const xclick = function setToX() {
    text.innerHTML = "X";
  };

  //next click
  const oclick = function setToO() {
    text.innerHTML = "O";
  };

  let trackCounter = [];
  let clickcount = 0;
  
  box.onclick = () => {
    trackCounter.push(clickcount);
    console.log(trackCounter);

    if (trackCounter.length % 2 == 0) {
      box.onclick = oclick; //not carried out/working
      console.log("Even");
    } else if (trackCounter.length % 2 == 1) {
      box.onclick = xclick; //not carried out/working
      console.log("odd");
    } else {
      console.log("error");
    }
  };
}

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>TicTacToe</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <section id="xosection">
      <div id="xogrid">
        <div class="row">
          <div id="box1" class="square">
            <h1></h1>
          </div>
          <div id="box2" class="square">
            <h1></h1>
          </div>
          <div id="box3" class="square">
            <h1></h1>
          </div>
        </div>
        <div class="row">
          <div id="box4" class="square">
            <h1></h1>
          </div>
          <div id="box5" class="square">
            <h1></h1>
          </div>
          <div id="box6" class="square">
            <h1></h1>
          </div>
        </div>
        <div class="row">
          <div id="box7" class="square">
            <h1></h1>
          </div>
          <div id="box8" class="square">
            <h1></h1>
          </div>
          <div id="box9" class="square">
            <h1></h1>
          </div>
        </div>
      </div>
    </section>
    <script src="index2.js"></script>
  </body>
</html>

Here is a link to some previous progress of the code on github: text

As mentioned I tried using an array hoping its length would increase. But it does not.

I may have incorporated some poor coding practices- like using a for loop to name the variables? Please let me know if I have and show me the best practices kindly. But also show me how to work around my thought process. Thank you so much in advance

Edit: I have deleted a variable called loopCount. It was there when I first asked the question.

2

There are 2 best solutions below

2
Ammad Hadi Ehsan On

I have tried to make trackcounter array global or outside loop so your loop will be updated in every for loop iteration

var trackCounter = [];
for (let num = 1; num <= 9; num++) {
  const text = document.querySelector("#box" + num + " h1");
  const box = document.querySelector("#box" + num);
  // let boxCounted = document.getElementsByClassName("square");

  //current click
  const xclick = function setToX() {
    text.innerHTML = "X";
  };

  //next click
  const oclick = function setToO() {
    text.innerHTML = "O";
  };

  //let trackCounter = [];
  let clickcount = 0;
  
  box.onclick = () => {
    trackCounter.push(clickcount);
    console.log(trackCounter);

    if (trackCounter.length % 2 == 0) {
      box.onclick = oclick; //not carried out/working
      console.log("Even");
    } else if (trackCounter.length % 2 == 1) {
      box.onclick = xclick; //not carried out/working
      console.log("odd");
    } else {
      console.log("error");
      console.log(countResult);
    }
  };
}

Try it, Hopefully it will resolve your problem

0
CodeThing On

You can add event listener to the squares and maintain counter outside to determine what you need to print inside the square. Here same logic of even's and odd's are applied.

const squares = document.querySelectorAll('.square');
const squareContainer = document.querySelector('#xogrid');
let count = 0;

squareContainer.addEventListener('click', function(e) {
  const target = e.target;
  if (target.classList.contains('square')) {
    if (count > squares.length - 1 || target.classList.contains('checked')) return;

    const displayElem = target.querySelector('h1');
    displayElem.innerText = count % 2 ? 'x' : 'o';
    target.classList.add('checked');
    count++;
  }
});