Error in points calculation and verification of colors

Welcome to the Color Challenge, where you must match the target color from a grid of colors to earn points. However, there seems to be an issue with the color checking and point tracking system. Initially, everything works fine, but as you click on more colors, errors start to creep in and eventually the game breaks down completely.

// script.js
const startBtn = document.getElementById('startBtn');
const startScreen = document.getElementById('startScreen');
const gameScreen = document.getElementById('gameScreen');
const endScreen = document.getElementById('endScreen');

const pointsBox = document.getElementById('pointsBox');
let points = 0;
console.log(points)


const targetClrBox = document.getElementById('targetClr');
const gridClrs = document.getElementById('gridClrs');

startBtn.addEventListener('click', setupColorGame);

function setupColorGame() {
  startScreen.classList.add('hidden');
  gameScreen.classList.remove('hidden');
  gameScreen.style.display = 'flex';

  initializeGame();
}

function initializeGame() {
  const clrs = [
    'rgb(238, 82, 83)',
    'rgb(253, 57, 115)',
    'rgb(87, 101, 116)',
    'rgb(95, 39, 205)',
    'rgb(6, 152, 22)',
    'rgb(29, 209, 161)',
    'rgb(243, 104, 224)',
    'rgb(255, 159, 243)',
    'rgb(230, 126, 34)',
    'rgb(254, 202, 87)',
    'rgb(46, 134, 222)',
    'rgb(84, 160, 255)',
    'rgb(1, 163, 164)',
    'rgb(0, 210, 211)'
  ];

  const targetClr = selectTargetClr(clrs);
  targetClrBox.style.backgroundColor = targetClr;

  const shuffledGridClrs = shuffleArray(clrs);
  setDivBackgroundColors(shuffledGridClrs);
  addBoxEventListeners();
}

function selectTargetClr(clrs) {
  const clrsIndex = Math.floor(Math.random() * clrs.length);
  return clrs[clrsIndex];
}

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

let boxes;

function setDivBackgroundColors(colors) {
  boxes = document.querySelectorAll('.clrBoxes');
  boxes.forEach((box, index) => {
    box.style.backgroundColor = colors[index];
  });
}

function addBoxEventListeners() {
  boxes.forEach(box => {
    box.addEventListener('click', () => {
      if (box.style.backgroundColor === targetClrBox.style.backgroundColor) {
        points++
        pointsBox.innerHTML = points;
        console.log(points);
        initializeGame();
      } else {

        initializeGame();
      }
    });
  });
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.hidden {
  display: none;
}


#gameScreen {
  flex-direction: column;
  justify-content: space-between; /* Changed to space-between */
  align-items: center;
  height: 100vh;
}

.clrBox {
  width: 125px;
  height: 125px;
  border: 1px dashed black;
  border-radius: 7px;
  margin: 3px;
  transition: all ease 0.1s;
}

.clrBox:hover {
  margin-top: -3px;
  margin-left: -1px;
}

#targetClr {
  margin-top: 20px;
  border: 1px solid black;
}

#gridClrs {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-gap: 7px;

  margin-bottom: 20px; 

}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Color Match Chaos</title>

  <link rel="stylesheet" href="./styles/main.css">
</head>
<body>


  <div id="startScreen">
    
    
    <button id="startBtn">Start Game</button>

  </div>


  <div id="gameScreen" class="hidden">

    <div id="targetBox">
      <div id="targetClr" class="clrBox"></div>

    </div>
    
    <div>
      <span id="pointsBox">0</span> / 10
    </div>

    <div id="gridClrs">

      <div class="clrBox clrBoxes" id="1"></div>
      <div class="clrBox clrBoxes" id="2"></div>
      <div class="clrBox clrBoxes" id="3"></div>
      <div class="clrBox clrBoxes" id="4"></div>
      <div class="clrBox clrBoxes" id="5"></div>
      <div class="clrBox clrBoxes" id="6"></div>
      <div class="clrBox clrBoxes" id="7"></div>
      <div class="clrBox clrBoxes" id="8"></div>
      <div class="clrBox clrBoxes" id="9"></div>
      <div class="clrBox clrBoxes" id="10"></div>
      <div class="clrBox clrBoxes" id="11"></div>
      <div class="clrBox clrBoxes" id="12"></div>
      <div class="clrBox clrBoxes" id="13"></div>
      <div class="clrBox clrBoxes" id="14"></div>

    </div>


  </div>



  <div id="endScreen" class="hidden">

  </div>

  <script type="module" src="./scripts/main.js"></script>
  
</body>
</html>

Answer №1

The reason for multiple event listener bindings in each iteration

box.addEventListener('click', () => {

is the absence of removal of previous listeners.

A closer look during debugging reveals that every click activates the handlers N times, with N being the total number of previous clicks.

Answer №2

const startBtn = document.getElementById('startBtn');
const startScreen = document.getElementById('startScreen');
const gameScreen = document.getElementById('gameScreen');
const endScreen = document.getElementById('endScreen');

const pointsBox = document.getElementById('pointsBox');
let points = 0;

const targetClrBox = document.getElementById('targetClr');
const gridClrs = document.getElementById('gridClrs');

startBtn.addEventListener('click', setupColorGame);

function setupColorGame() {
  startScreen.classList.add('hidden');
  gameScreen.classList.remove('hidden');
  gameScreen.style.display = 'flex';

  initializeGame();
}

function initializeGame() {
  const clrs = [
    'rgb(238, 82, 83)',
    'rgb(253, 57, 115)',
    'rgb(87, 101, 116)',
    'rgb(95, 39, 205)',
    'rgb(6, 152, 22)',
    'rgb(29, 209, 161)',
    'rgb(243, 104, 224)',
    'rgb(255, 159, 243)',
    'rgb(230, 126, 34)',
    'rgb(254, 202, 87)',
    'rgb(46, 134, 222)',
    'rgb(84, 160, 255)',
    'rgb(1, 163, 164)',
    'rgb(0, 210, 211)'
  ];

  const targetClr = selectTargetClr(clrs);
  targetClrBox.style.backgroundColor = targetClr;

  const shuffledGridClrs = shuffleArray(clrs);
  setDivBackgroundColors(shuffledGridClrs);
  addBoxEventListeners();
}

function selectTargetClr(clrs) {
  const clrsIndex = Math.floor(Math.random() * clrs.length);
  return clrs[clrsIndex];
}

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

function setDivBackgroundColors(colors) {
  const boxes = document.querySelectorAll('.clrBoxes');
  boxes.forEach((box, index) => {
    box.style.backgroundColor = colors[index];
  });
}

function addBoxEventListeners() {
  const boxes = document.querySelectorAll('.clrBoxes');
  boxes.forEach(box => {
    if (box.style.backgroundColor === targetClrBox.style.backgroundColor) {
      box.addEventListener('click', checkColorMatch);
      box.addEventListener('click', startNewGame);
    }
  });
}

function checkColorMatch(event) {
  const clickedColor = event.target.style.backgroundColor;
  const targetColor = targetClrBox.style.backgroundColor;
  
  if (clickedColor === targetColor) {
    points++;
    pointsBox.textContent = `Points: ${points}`;
    event.target.removeEventListener('click', checkColorMatch);
  }
}

function startNewGame() {
  initializeGame();
}

I made adjustments to only add event listeners to the target color in the grid boxes and remove it after incrementing the points. I also added an event listener to all boxes to create a new game when clicked. It now functions correctly.

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

Make sure to execute observables just once, and afterwards verify if they have finished - angular2 typescript

Completely new to the world of Observables, so please forgive me if this is a simple question. I've done some research online, but I can't seem to find the answer I'm looking for. Take a look at this basic example on Plunker: https://plnk ...

Sharing Angular 4 components in my project - collaboration at its finest

I have been working on an Angular project that consists of a variety of UI components. I would like to make these components available for use in other Angular projects and share them within the npm community. All of the components are located in a shared ...

Prevent a button on my side bar from being clicked until the user has logged in?

How can I use Django and HTML to disable a button in my tab bar until a user is logged in? This is my sidebar: <div id="mySidebar" class="sidebar"> <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a> <a href ...

Incorporating images with JavaScript in Jade templates

Currently I have a layout.jade code that I am looking to modify the javascript for. My goal is to load an image onto the page every time it is reloaded using jade. Here is the existing code: html head title= title script(src='/libs/jquery/j ...

A compilation of web browsers and their compatible versions for the SVG engine

I recently encountered an issue with the org chart I created using getorgchart. Everything was running smoothly until I tested it on IE8. It turns out that getorgchart relies on the SVG engine for rendering, which is not supported by IE8. I attempted to ...

looking to save a service or factory as a variable

I seem to be at a standstill when it comes to finding a solution for my mvc.NET / angularjs project. So far, I believe I've done a good job abstracting the view to use a controller that matches the type name of the specific controller.cs class: < ...

Failed to successfully sort several distinct lists using the ng2-dnd sorting library

Recently, I came across a fantastic drag-and-drop library on GitHub that I decided to use. In my current project, I have created a view with three different buttons, each revealing a list when clicked at the same position but not simultaneously. However, ...

Error encountered while parsing Node.js code for MySQL query execution

I am encountering an error message from Node that reads: Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TIMESTAMPDIFF(second, entered_at, c ...

The jQuery mobile button may occasionally appear selected without triggering a page transition

When using a Phonegap Application with jQuery mobile, I have encountered an issue where clicking a button sometimes only selects it and does not transition to the next page. This even happens with the back buttons generated automatically by the library, re ...

Ways to extract Document ID from a Firestore database collection

Currently, I am in the process of developing a mobile app using React Native and Firebase. My main focus right now is on accessing document data without explicitly specifying the ID, unlike the method shown below: const docRef = db.collection('vehicle ...

It's not possible to add additional options to the select input in a react

Hi there! I'm currently facing an issue while trying to retrieve a list of options from the backend, map them to another list of options, and add them to a main list. Unfortunately, my attempts have not been successful. Could anyone offer some advice ...

Display the page for 10 seconds continuously in a loop

I am currently developing a Node JS guessing game where data is collected on the back-end and sent to the front-end to start the game. The data consists of 10 levels, allowing the game to operate on a single page. Each level lasts for 10 seconds. Once the ...

When attempting to access the shazam API, I encountered an issue where my useTopChartsQuery function was not recognized as a valid function

Welcome to the shazamCore.js file import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const shazamCoreApi = createApi({ reducerPath: "shazamCoreApi", baseQuery: fetchBaseQuery({ baseUrl: "https ...

Utilize JQuery variables for toggling the visibility of various DIV elements

On my webpage's splash page, there are 4 divs but only the home div is initially visible. The other three are hidden. Each of these divs has a button associated with it that triggers a jquery click event to swap out the currently visible div for the ...

The hover effect in CSS is not altering the entire background

I'm looking to change the background color of a div when hovering over it, but I'm running into an issue where only the content inside the div is changing color. The rest of the background remains the same. Here's the HTML code I have: < ...

What is the difference in memory usage for JavaScript objects between Node.js and Chrome?

It's puzzling to me why the size of the heap is twice as large as expected. I meticulously constructed a binary tree with perfection. I suspect v8 recognizes that each node consists of 3 fields. function buildTree(depth) { if (depth === 0) return n ...

Is it possible to execute node.js code within a Java script environment?

I have a javascript code that functions as a discord bot. Typically, to run this bot, I would open the command prompt in the js path and enter node {file_name}.js. Now, let's say I have another javascript code that I want to execute on button click an ...

Attempting to integrate a TypeScript library with a JavaScript Express application

I have been attempting to integrate a TypeScript library like this into an existing Express Node.js application, but unfortunately it is not working as expected. Upon importing the library functions, I keep encountering errors such as "Cannot read property ...

What is the process for incorporating the Angular JS $q service into this specific scenario?

Looking at the example below, it's essential to ensure that the drawFunc method completes before proceeding to add the opacity and ultimately including foregroundPath to the Kinetic layer. Is there a way to effectively "wait" for the value of foregro ...

The issue of numbers not being properly summed in Node.js

I'm currently working on storing product prices in sessions. The issue arises when a product is clicked twice - instead of adding the two prices together, they concatenate into a single value. For example, 15 + 15 results in 01515. I'm unsure why ...