Trouble Arising in Showing the "X" Symbol upon Initial Click in Tic-Tac-Toe Match

Description:

I'm currently developing a tic-tac-toe game, and I've run into an interesting issue. When I click on any box for the first time, the "X" symbol doesn't show up. However, it works fine after the initial click.

Problem Details:

  1. Issue 1: "X" not appearing on initial click

    • Upon clicking on a box in the game, the "X" symbol fails to display initially. Subsequent clicks work as expected without any issues.

If you come across any other issues or have suggestions for improvement, please share them with me as I am relatively new to coding.

Code Snippets:

Below is the essential code snippet for my tic-tac-toe game:

... (code has been omitted for brevity)

Regards

A big thank you to those who are trying to help me solve this problem!

What I've Tried:

In response to advice from an experienced user on the OpenAI platform, I meticulously checked the turner and tosswinner functions. I confirmed that the tosswinner function is properly triggered upon box clicks.

Additional Information:

This game is being developed using HTML, CSS, and JavaScript. There seems to be a potential conflict with event handling or timing, but I haven't been able to pinpoint the exact cause of the problem.

Request for Help:

Any guidance or recommendations on resolving the aforementioned issues would be highly appreciated. If you can detect any errors in my code or propose alternative solutions, your assistance would be invaluable.

Thank you for your support!

Answer №1

Your issue stems from the fact that your click event listener is only activated after the initial click, as it is part of the tosswinner function.

To resolve this, you need to relocate the click event listener for boxes to the global scope. This way, even if the first click is not triggered, the event will still be registered in advance.

//move the click event listener to the global scope
boxes.forEach((box) => {
  box.addEventListener("click", function() {
    tosswinner.call(this);
  });
});

let boxes = document.querySelectorAll('.boxes');
let arr = Array.from(boxes);
console.log(arr);
let pop = document.getElementById("pop");
let tossing = document.getElementById("tossing");
let tosser = document.getElementById("tosser");
let toss1 = document.getElementById("toss1");
let tossing1 = document.getElementById("tossing1");
setTimeout(() => {
  pop.classList.add("popup");
}, 3000);
let botTurn = "";
let choosedToss = "";
let count = 0;

//move the click event listener to the global scope
boxes.forEach((box) => {
  box.addEventListener("click", function() {
    tosswinner.call(this);
  });
});

async function turner() {
  let selected = arr[Math.floor(Math.random() * arr.length)];
  setTimeout(() => {
    if (selected.innerHTML == "") {
      setTimeout(() => {
        selected.innerHTML = "O";
      }, 50);
    } else {
      return turner();
    }
  }, 50);
  count++;
}

function tosswinner() {
  let box = this;
  if (box.innerHTML === "") {
    box.innerHTML = "X";
  }
  boxes.forEach((box) => {
    //you don't need this anymore
    //box.addEventListener("click", function() {
    //  tosswinner.call(this);
    //});
    count++;
  });
}

async function FinalFunc() {
  let Hulk = new Promise((resolve, reject) => {
    setTimeout(() => {
      toss1.classList.remove("open1");
      resolve(1);
    }, 2000);
  });
  const result = await Hulk;
  console.log(result);
}

async function R() {
  let THOR = new Promise((resolve, reject) => {
    setTimeout(() => {
      if (choosedToss == botTurn) {
        tossing1.innerHTML = "you won , first turn is yours";
      } else {
        tossing1.innerHTML =
          "you have losted , you will play next to the winner ";
      }
      tossing1.classList.add("text1");
      resolve("Thor");
    }, 1500);
  });
  const result = await THOR;
  console.log(result);
}

async function botTurns() {
  let TOSS = ["Heads", "Tail"];
  botTurn = TOSS[Math.floor(Math.random() * TOSS.length)];
  tossing1.innerHTML = `<h1>${botTurn}</h1>`;
  tossing1.classList.add("text");
}

async function Messi() {
  let cap = new Promise((resolve, reject) => {
    setTimeout(() => {
      tossing1.classList.remove("load");
      botTurns();
      resolve(botTurn);
    }, 3000);
  });
  const result = await cap;
  console.log(result);
}

async function Message() {
  let stark = new Promise((resolve, reject) => {
    setTimeout(() => {
      tossing.classList.remove("load");
      tossing.innerHTML = `you choosed ${choosedToss} !`;
      resolve(`you choosed ${choosedToss}`);
    }, 1000);
  });
  const result = await stark;
  console.log(result);
}

async function popdown() {
  let tony = new Promise((resolve, reject) => {
    setTimeout(() => {
      tosser.classList.remove("tosseropen");
      resolve("rate");
    }, 2000);
  });
  const result = await tony;
  console.log(result);
}

async function Heads() {
  choosedToss = "Heads";
  pop.classList.remove("popup");
  tosser.classList.add("tosseropen");
  await Message();
  await popdown();
  toss1.classList.add("open1");
  await Messi();
  await R();
  await FinalFunc();
}

async function Tail() {
  choosedToss = "Tail";
  pop.classList.remove("popup");
  tosser.classList.add("tosseropen");
  await Message();
  await popdown();
  toss1.classList.add("open1");
  await Messi();
  await R();
  await FinalFunc();
}
body {
  display: flex;
  justify-content: center;
  height: 100vh;
  width: 100vw;
  align-items: center;
}

#mainbox { 
  width: 240px;
  height: 240px;
  display: flex;
  position: absolute;
  right: 60px;
  flex-flow: row wrap;
  background-color: yellow;
}

.boxes {
  height: 75px;
  width: 75px;
  background: red;
  margin: 2px;
  color: white;
  font-size: 25px;
}

#pop,
#tosser,
#toss1 {
  height: 200px;
  width: 280px;
  background: skyblue;
  position: absolute;
  top: 0%;
  left: 12.5%;
  visibility: hidden;
  transform: translate(0px, 0px) scale(0.01);
  transition: transform 0.4s, top 0.4s;
  display: flex;
  flex-flow: column wrap;
  border-radius: 20px;
  justify-content: space-between;
  align-items: center;
}

#pop.popup,
#tosser.tosseropen,
#toss1.open1 {
  visibility: visible;
  display: flex;
  top: 0%;
  transform: translate(0px, 100px) scale(1);
}

.head {
  width: 280px;
  height: 50px;
  background: darkblue;
  color: white;
  font-size: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bolder;
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
}

#para {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  color: white;
  font-weight: bold;
}

.toss {
  height: 40px;
  width: 90px;
  margin: 0px 20px 30px 18px;
  background: royalblue;
  color: white;
  font-size: 20px;
  border: none;
  border-radius: 10px;
  font-weight: bold;
  
}

#tossing {
  color: white;
  font-size: 27px;
  font-weight: bolder;
  margin-bottom: 60px;
}

.text {
  color: white;
  font-size: 15px;
  font-weight: bolder;
  margin-bottom: 38px;
}

.text1 {
  color: white;
  font-size: 15px;
  font-weight: bolder;
  margin-bottom: 65px;
}

.load {
  height: 50px;
  width: 50px;
  border: 5px black solid;
  border-top: 5px royalblue solid;
  border-radius: 50%;
  position: fixed;
  top: 80px;
  animation: SpinAnimate 1s linear 0s infinite normal;
}

@keyframes SpinAnimate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
<div id="mainbox">
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>
  <div class="boxes" onclick="tosswinner(this);turner();"></div>

</div>

<div id="pop">
  <div class="head">TOSS</div>
  <div id="para">HEADS OR TAILS ? </div>
  <br />
  <div>
    <button class="toss" onclick="Heads()">HEADS</button>
    <button class="toss" onclick="Tail()">TAIL</button>
  </div>

</div>

<div id="tosser">
  <div class="head">CHOOSED</div>
  <div id="tossing" class="load"> </div>

</div>

<div id="toss1">
  <div class="head">TOSSING</div>
  <div id="tossing1" class="load">
  </div>

</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Protecting Node.js Files

As I prepare to embark on creating a new website, my main goal is to collect form input values such as dropdowns and radio boxes from the client without requiring user accounts. These values will be used for sensitive calculations, making security a top pr ...

Adjusting the decimal points of numbers within a table to create the illusion of a "centered" alignment within the cell

Looking for a table design featuring a column of decimal numbers, each with varying lengths before and after the decimal point, while keeping the decimal points aligned. The width of the column should be flexible, expanding to accommodate long numbers in ...

Adding a CSS style to specific sections of a string that is quoted in a Razor ASP.NET file

Is it possible to format a specific part of a string? I'm trying to only stylize the word within quotation marks. This is my cshtml code: { <div class="h-44 overflow-auto text-left mx-4 mb-4"> <p ...

The integration of Express server with static ejs files, CSS, and JavaScript is experiencing technical difficulties

I am currently working on a website using node.js and have created two routes: /home and /contact. Everything was functioning properly until I added CSS and JS files to both routes. For some reason, the second call does not work as expected. When I access ...

Guide to creating a CSS horizontal line with square elements on either side of a title

I am currently working on how to create a horizontal line with small squares on each side of an h1 title. I have managed to achieve the horizontal line using code from a similar question, but I am struggling to add the square elements to the design. https ...

produce in the element that is invoked within an each function

This snippet is a key part of my component's template: {{#each displayResults}} <li {{action addSelection this}} {{bindAttr class=\":result active\"}}> {{#if controller.template}} {{yield}} {{else}} <span class=\ ...

Present a pop-up notification box with a countdown of 30 seconds prior to the expiration of a session timeout in JSF

Our task is to create a timeout window that appears 30 seconds before the session expires. If the user remains inactive, they will be automatically redirected to the home page. We already have the maximum allowed duration of inactivity defined. I would l ...

The functionality of $watch in AngularJS is not meeting the desired outcomes

Within my controller, I am looking to receive notifications when the value of a certain variable changes. Specifically, I want a function to be triggered whenever this variable is updated. To achieve this, I am utilizing the $watch method in AngularJS. Her ...

Encountering an issue with state setting - Experiencing an excessive amount of re-renders in a

If you want to see the solution in action, check out the Code Sandbox link provided below for better clarity on the issue at hand. Currently facing an issue with setting my mymoviegenreobjects as the mymoviegenreinfo state within the useFetchMovieGenreRes ...

Form using Ajax technology, including two drop-down menus sourced externally

Is there a way to automatically populate a second drop-down list with all models once a selection is made in the first drop-down on a form? Below is the code snippet: <form> <div class="landing_quote_left"> ...

Customize the appearance of parent components based on the content of their child elements

I am currently working on a component that contains multiple instances, each with its own unique internal component (acting as a modal wrapper). I need to customize the size of each modal instance independently. How can I achieve this customization when th ...

Unable to capture screenshot of hovered element using Cypress

Having an issue with taking a screenshot of an element with a hover effect. The screenshots always come out without the hover effect applied. tableListMaps.lineWithText('Hello world', 'myLine'); cy.get('@myLine').realH ...

When hovering, transition occurs unless the cursor is over a specific element

I have created a small box element with a close button that looks like this: ___ | X| ‾‾‾ In order to make it more interactive, I applied some CSS so that when hovered, the box expands like this: ___________________ | X| ‾ ...

Is the callback for a request always invoked?

When using the npm module request, I often encounter situations where some requests are not called back, leading to various issues. This has raised a question in my mind - is it expected for the request function to always callback? For instance, if my req ...

Turn off the special treatment of the "class" attribute

The Background: When using BeautifulSoup to parse HTML, the attribute class is considered a multi-valued attribute and is treated differently: It's important to remember that a single tag can have multiple values for its "class" attribute. When se ...

Transferring an array from JavaScript to PHP, encountering an issue with determining the length

I'm having an issue passing an array from my .js file to a PHP file. In JavaScript, the array is structured as follows: theBlock[0 - 79] with color, x, and y values. For example, theBlock[10].color or theBlock[79].x The data is sent using the follow ...

Using VML for background images in Outlook using HAML: A step-by-step guide

I am currently working on formatting an email digest using HAML and tables. My goal is to set a background-image to a table-cell in the email, but I've come to realize that Outlook requires VML in order to display a background-image correctly. After ...

What is the best way to generate a JSON output that contains the entire

The use of {foo|json} is effective for displaying only part of the $scope. Is there a way to pass the entire scope to the json filter? ...

Injecting SVG styling into HTML using the content tag and CSS

I am working with 3 different files: index.html <!DOCTYPE html> <html> <head> <link type="text/css" rel="stylesheet" href="style.css" /> </head> <body> <i class="logo myRed" aria-hidden="true"></i> ...

The Angular 1.x Ajax request is not triggering the expected update in the view

I am encountering an issue with my Angular application where the data retrieved from a JSON file is not updating in the view when the JSON file is updated. It seems like the JSON file and the view are out of sync. As a newcomer to Angular, I am struggling ...