Require assistance with debugging an issue in an online game played through a web browser

Experience a simple browser memory game where you must flip all matching cards to emerge victorious.

The glitch :

In the game, if you click quickly enough, you can uncover more than two cards at a time.

I've spent ample time attempting to rectify this issue on my own, but it has proven to be quite challenging. Any assistance in resolving this bug would be greatly appreciated since I am still relatively new to JavaScript and struggle with fixing these fundamental errors.

Game files:

HTML:

<!doctype html>
<html lang="en>

<head>
  <meta charset="utf-8">
  <title>My App</title>
  <link rel="stylesheet" href="css/game.css" />
</head>

<body>
  <button class="Change User" onclick="change(this)">Change User</button>
  <div class="header">
    <img src="img/layout/logo.png">
    <h1>Memory Monsters</h1>
    <p id="Play Again"></p>
  </div>
  <div class="card" data-card="1" onclick="cardClicked(this)">
    <img src="img/cards/1.png">
    <img class="back" src="img/cards/back.png">
  </div>
  <div class="card" data-card="7" onclick="cardClicked(this)">
    <img src="img/cards/7.png">
    <img class="back" src="img/cards/back.png">
  </div>
  <div class="card" data-card="1" onclick="cardClicked(this)">
    <img src="img/cards/1.png">
    <img class="back" src="img/cards/back.png">
  </div>
  <div class="card" data-card="7" onclick="cardClicked(this)">
    <img src="img/cards/7.png">
    <img class="back" src="img/cards/back.png">
  </div>
  <div class="card" data-card="5" onclick="cardClicked(this)">
    <img src="img/cards/5.png">
    <img class="back" src="img/cards/back.png">
  </div>
  <div class="card" data-card="5" onclick="cardClicked(this)">
    <img src="img/cards/5.png">
    <img class="back" src="img/cards/back.png">
  </div>

  <script src="js/game.js"></script>  
</body>

</html>

Javascript:

var getElementsByClassName = prompt('What is your name?');
window.localStorage.setItem('name', 'dan');
function change(username) {
    prompt('What is your name?');
}

// Global variables keeping track of the game state
var elPreviousCard = null;
var flippedCouplesCount = 0;

// Constant value for total number of card pairs
var TOTAL_COUPLES_COUNT = 3;

// Load audio file
var audioWin = new Audio('sound/win.mp3');

// Function called when a card is clicked
function cardClicked(elCard) {

    // Exit function if user clicks on an already flipped card
    if (elCard.classList.contains('flipped')) {
        return;
    }

    // Flip the card
    elCard.classList.add('flipped');

    if (elPreviousCard === null) {
        elPreviousCard = elCard;
    } else {
        var card1 = elPreviousCard.getAttribute('data-card');
        var card2 = elCard.getAttribute('data-card');

        if (card1 !== card2) {
            setTimeout(function() {
                elCard.classList.remove('flipped');
                elPreviousCard.classList.remove('flipped');
                elPreviousCard = null;
            }, 1000)

        } else {
            flippedCouplesCount++;
            elPreviousCard = null;

            if (TOTAL_COUPLES_COUNT === flippedCouplesCount) {
                audioWin.play();
    
        document.getElementById("Play Again").innerHTML =
        '<button onclick="resetCard();">Play Again</button>';
            }

        }

    }

}

function resetCard() {// to erase the flipped classes
    var cardclass = document.getElementsByClassName("card");
    for (i = 0; i < cardclass.length; i++) {
      cardclass[i].classList.remove("flipped");
      document.getElementById("Play Again").innerHTML = "";
    }
}

CSS:

.header {
    background-color: lightblue;
    padding: 20px;
    border-bottom: 10px solid darkcyan;
    color:darkcyan;
    font-size: 1.5em;
    text-align: center;
}

.header img {
    float:right;
}

.card {
    background-color: pink;
    height: 165px;
    width: 165px;    
    float: left;
    margin: 5px;

}

.card img {
    position: absolute;
}

.flipped .back {
    display: none;
}

Answer №1

I created a similar game where you must initialize a variable starting at 0.

let attempts = 0;

Increment the variable each time a card is chosen, ensuring that clicking on a flipped card doesn't count. Below is some code snippet from my onclick function. I implemented this in a React framework, but you can use this logic in your JS function to make it work:

selected = (event) => {

        if (canClick === true) {
            let id = event.currentTarget.id; //card0
            let idString = id.toString(); //"card0"

            //ALLOW ONLY FACE-DOWN CARDS TO BE CLICKED
            if (this.state[idString] === cardBack) {

                idString = idString.replace(/card/g, ''); //"0"
                this.setState({[id] : arrayRandom[idString]});

                //FIRST SELECTION
                if (counter % 2 == 1) {
                    curCard1 = arrayRandom[idString].toString();
                    id1 = id;
                    counter++;
                //SECOND SELECTION
                } else {
                    //PREVENT SAME CARD FROM BEING SELECTED TWICE IN A ROW AND REMAIN FACE UP
                    if (id === id1) {
                        console.log("Pick a different card for your second selection");
                    } else {
                        counter++;
                        attempts++;
                        canClick = false; //PREVENT USER FROM PICKING ANOTHER CARD
                        curCard2 = arrayRandom[idString].toString();
                        id2 = id;
                        setTimeout(() => {canClick = true}, 1000); //USER CAN PICK AGAIN AFTER 1 SECOND
                        //IF MATCH IS FOUND - CARDS STAY FLIPPED, SCORE INCREASES BY 1
                        if (curCard1 == curCard2) {
                            score = score + 1;
                        //IF NO MATCH - CARDS FLIP BACK AFTER A SECOND
                        } else {
                            setTimeout(() => {
                                this.setState({[id1]: cardBack});
                                this.setState({[id2]: cardBack});
                            }, 1000);
                        }
                    }
                }
            } else {
                console.log("This card has already been flipped, choose another one");
            }
        }
    }

Check out my game here:

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

What are the best practices for handling image titles and alt text to ensure accessibility?

The description in JAWS is repeated verbatim: "Back to Google's website link graphic. Google's Test Lon and dash back to Google's website". Upon investigation, it seems that this repetition occurs because the description is given once for t ...

Tips for passing a false boolean state value back to the parent component in ReactJS

parent.tsx const [modal, setModal] = useState(false); const [detail, setDetail] = useState({}); <confirmation state={setModal(true)} data={detail} /> confirmation return ( <SweetAlert show={state} success title="Confirm ...

Capturing the dynamic server response with nested JSON structures

I am in the process of creating a dynamic data-binding function named assemble that requires two input parameters: server response (JSON) - nested JSON object. instruction set (JSON) - a configuration object that dictates the binding. The Issue: The cur ...

Tips for modifying string in key-value pairs on the client side (example using Paypal checkout demo)

Looking to integrate an online payment system into my small online business, I have decided on using PayPal. Their solution is user-friendly and can be found here: https://developer.paypal.com/demo/checkout/#/pattern/client However, I am facing an issue w ...

Navigating a Bootstrap carousel with buttons: A step-by-step guide

Here is the code snippet I am currently working with: <!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-2.1.4.js"></script> <link href="https://code.jquery.com/ui/1.11.4/them ...

Double f span causing unusual behavior in Chrome browser

Why does the highlight focus on "ort" instead of "fort"? It appears this occurs when there are two f's. When I substitute f with other letters, like d, it shows correctly. Could this be a bug in Chrome? Chrome version is chrome83. add: It seems to be ...

Struggle arising from the clash between a customized image service and the built-in image element

Dealing with a custom Angular service called Image, I realized that using this name poses a problem as it clashes with Javascript's native Image element constructor, also named Image. This conflict arises when attempting to utilize both the custom Im ...

Definitions have not been declared

My coding is as follows: var data = JSON.parse(http.responseText); var weatherData = new Weather(cityName, data); weatherData.temperature = data.main.temp; updateWeather(weatherData); function Weather(cityName, data) { this.cityName = cityNa ...

The forecast button seems to be malfunctioning. Each time I attempt to click on it, a message pops up saying, "The server failed to comprehend the request sent by the browser (or proxy)."

Even though I provided all the necessary code, including the Flask app, predictionmodel.py, and HTML code, I am still encountering an error when running it locally after clicking submit. The browser (or proxy) sent a request that this server could not un ...

Change the behavior of JavaScript so that it executes when clicked, not when the

This script is currently set to run when the page loads: <script language="JavaScript"> j=parseInt(Math.random()*ranobjList.length); j=(isNaN(j))?0:j; document.write(unescape(ranobjList[j])); </script> Is there a way I can mak ...

I am looking to download a file from a server and showcase it in a browser using React.js. The file will be received as a response from the

**I am looking to retrieve a file from the server by sending the file name through the body and then receiving the requested file from the server.** I have successfully received the file in response from the server, which I tested using Postman. What I a ...

The server is being bottlenecked by the calculation of distances between numerous Nodejs coordinates

With a list containing hundreds of coordinates (lat,lon), I face the challenge of calculating the distance between each pair of points for every client request. This process is currently blocking my nodejs server as it takes 500ms to do so with a list of 1 ...

Combining two arrays containing objects in JavaScript

Imagine having 2 arrays of objects that you want to merge in a parallel manner. For instance var array = [{foo: 2} , {boo: 3}] var array2 = [{foo2: 2}, {boo2: 4}] The outcome would be var array3 = [{foo:2,foo2:2},{boo:3,boo2:4}] In what way can this be ...

Bootstrap overrides the color of the calendar year in jQuery UI

I am facing an issue where the CSS styles of my jQuery UI calendar are being overridden by the Bootstrap CSS styles. Take a look at the screenshot provided. As you can see, the text color of the calendar's year is not black as intended. https://i.ss ...

Unlocking keys of JavaScript class prior to class initialization

My constructor was becoming too large and difficult to maintain, so I came up with a solution to start refactoring it. However, even this new approach seemed bulky and prone to errors. constructor(data: Partial<BusinessConfiguration>) { if(!d ...

Tips for keeping a div centered even when the window is resized to smaller than the background width

I need help with centering a background image within a content div that is inside a wrapper container. When the browser window is resized to less than 500px, the background image starts to cut off from the right side. How can I ensure the background image ...

Tips for implementing the quill-image-drop-module with Vue 3

I am currently utilizing the vueup/vue-quill package for Vue 3 and I would like to incorporate the kensnyder/quill-image-drop-module. This is the snippet of my code: Main.js import { QuillEditor } from '@vueup/vue-quill'; import '@vueup/vu ...

Creating a personalized cursor transition with CSS styling

I have an unordered list (ul) with items on each list item (li) having a different cursor. While it works fine, the transition is not smooth. Is there a way to make the transition from the default cursor to a custom image smoother? HTML <section class ...

When the tailwind utilities are implemented, they do not appear on the screen

Recently, I embarked on a project using Tailwindcss/Next.js and encountered an issue when trying to apply a box-like shadow to a button with a new utility in pure CSS. Despite my efforts, the changes don't seem to take effect. Can you spot what I migh ...

Protecting Angular Routes: Verifying HTTP-Only Cookie Authentication on the Server- CanActivate Function

I am utilizing an HTTP only cookie for authentication in my server: export const checkCookie = async (req: Request, res: Response) => { const token = req.cookies["token"]; if (!token) { return res.status(401).json({ message: "Unau ...