0

I am making a quiz and I want to find out which button has the most clicks so I can give the answer

I have these variables in the start set to zero and their scores will increase by user input

var earthScore = 0;
var venusScore = 0;

whenever the button is clicked a fuction runs

q1a4.addEventListener ("click", earth);
q1a5.addEventListener ("click", venus);

this function will add one to the original variables

function earth () {
    earthScore += 1;
    questionCount += 1;
}
function venus () {
    venusScore += 1;
    questionCount += 1;
}

now I want to find out the variable which has the most clicks and give an answer to user so for example; if earth variable has greater score than venus variable then I will change the result to result.innerHTML = 'you are earth' but I don't know how to find the variable with the greatest score

this is actually my first project using js so i dont have that much idea and everything i tried to find seems wrong so i would really appreciate if anyone can give me an answer for my program.

Sadeed_pv
  • 513
  • 1
  • 9
  • 22
dua diy
  • 23
  • 3
  • Please provide your code as one code block, and include your attempt to make it work. Also include the HTML. – trincot Jul 21 '23 at 22:13
  • Does this answer your question? [Javascript max() function for 3 numbers](https://stackoverflow.com/questions/1418569/javascript-max-function-for-3-numbers) – Heretic Monkey Jul 21 '23 at 22:16
  • @LajosArpad Agreed, I have formatted his question in a way that other users can understand – Sadeed_pv Jul 22 '23 at 08:19

2 Answers2

0

You might put the Results into an Array afterwards with:

let tmpArray = [];
tmpArray.push(earth);
tmpArray.push(venus);
tmpArray.sort(function(a, b){return b - a});

Now, you have the highest value in:

tmpArray[0];

Refer to: https://www.w3schools.com/js/js_array_sort.asp

Stef
  • 13
  • 5
  • 1
    Wouldn't it be simpler to just call `Math.max(earth, venus)`? – Lajos Arpad Jul 22 '23 at 00:25
  • All ways work. Thats the answer for coding. It's not the way 'why' - it's the way 'how'. In my example, I thought, to make a scorecard or similar. – Stef Jul 22 '23 at 01:00
-1

Take a look at the solution first:

var earthScore = 0;
var venusScore = 0;
var questionCount = 0;

function handleResult() {
    if (earthScore !== venusScore) result.innerText = "you are " + ((earthScore >= venusScore) ? "earth" : "venus");
    else result.innerText = "";
}

function earth () { earthScore += 1; questionCount += 1; handleResult(); }
function venus () { venusScore += 1; questionCount += 1; handleResult(); }

let q1a4 = document.getElementById("q1a4");
let q1a5 = document.getElementById("q1a5");

q1a4.addEventListener ("click", earth); q1a5.addEventListener ("click", venus);

let result = document.getElementById("result");
<input type="button" id="q1a4" value="EARTH">
<input type="button" id="q1a5" value="VENUS">
<div id="result"></div>

Explanation:

  • we initialize the scores with 0
  • we define handleResult which will update the result with the current winner (or nothing when we have a tie)
  • we have earth and venus like you initially defined, except for calling handleResult as well to handle the result
  • we get the buttons
  • we specify click events for the buttons like you specified
  • we get the result element as well so we can display the result

EDIT

Let's see an example with 8 items, which, by chance corresponds with the number of planets in the solar system (poor Pluto)

function handleResult() {
    let tie = false;
    let maxSoFar = 0;
    let plnt = "";
    for (let planet of Object.keys(counts)) {
        if (counts[planet] > maxSoFar) {
            maxSoFar = counts[planet];
            tie = false;
            plnt = planet;
        } else if (counts[planet] === maxSoFar) {
            tie = true;
        }
    }
    if (tie) {
        result.innerText = ""; //a tie
    } else {
        result.innerText = "You are " + plnt.toLowerCase();
    }
}

let result = document.getElementById("result");
let planets = document.getElementsByClassName("planet");
let counts = {};
for (let planet of planets) {
    counts[planet.value] = 0;
    planet.addEventListener("click", function() {
        counts[this.value]++;
        handleResult();
    });
}
<input type="button" class="planet" value="MERCURY">
<input type="button" class="planet" value="VENUS">
<input type="button" class="planet" value="EARTH">
<input type="button" class="planet" value="MARS">
<input type="button" class="planet" value="JUPITER">
<input type="button" class="planet" value="SATURN">
<input type="button" class="planet" value="URANUS">
<input type="button" class="planet" value="NEPTUNUS">
<div id="result"></div>

Explanation:

  • handleResult now extracts the keys of the object of counts (which are planet names), iterates them and compares their count to the maximum so far; if it's greater, then it's surely not a tie and it's the new maximum and these values are stored; otherwise, if the count of the current planet is equalling the highest count so far, then we have a tie (so far); finally, if the current count is smaller than the maximum so far, then we do nothing and let the loop to step over the item
  • we get the result item exactly like we did so earlier
  • we get the planets by class name, because it would be awkward to get them separately by id, writing 8 lines instead of a single one
  • we initialize counts as an empty object
  • and iterates the planets
  • initializing the count of each planet as a data member of counts having a value of 0, for example, counts["MERCURY"] is 0 at the start
  • we create an event for each planet which will occur when the planet's button is being clicked, incrementing the count of the planet in question and calling handleResult
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Uncaught SyntaxError: Identifier 'result' has already been declared script.js:97 js:97 is this line [let result = document.getElementById("result");] – dua diy Jul 21 '23 at 22:55
  • @duadiy this error is telling you that you already had a `result` variable and it's being duplicated. Please try the snippet I have provided in my answer by clicking on Run code snippet and let me know whether it works for you. If so, then the issue is simply that you have pasted this code into file(s) that you already have and some variables are getting duplicated. – Lajos Arpad Jul 21 '23 at 22:57
  • I see this answer was down-voted. I do not see why this would be down-voted even after re-reading it, as it appears to me correct. If some suggestions would be added as of what shortcomings are to be found in this answer, they would help me improving them. Thanks! – Lajos Arpad Jul 21 '23 at 23:22
  • I fixed the error and the program is working perfectly thanks to you. I also have a question: can I add more variables and use the same format above to find the greatest score from 8 variables? Thanks again for the help I appreciate it :) – dua diy Jul 21 '23 at 23:47
  • @duadiy yes, you can apply it with eight variables as well. Let me edit my answer with a sample example. – Lajos Arpad Jul 22 '23 at 00:01
  • @duadiy Strangely-enough, the other answer, which does not provide a full answer and over-complicates the partial answer it addresses, the whole thought could be done via `Math.max(earth, venus)` (assuming that `earth` and `venus` were properly initialized) instead of creating an array, pushing the two values into it and sorting it. – Lajos Arpad Jul 22 '23 at 00:25
  • i understand your 8 planets answer but the thing is in my program buttons are id=q1a1,q1a2 etc and. the value is a name like red,yellow etc which then corresponds to the planet like this `var q1a1 = document.getElementById ("q1a1");`. `q1a1.addEventListener ("click", mars);` – dua diy Jul 22 '23 at 04:53
  • I am kind of making a BuzzFeed-style quiz where the user gives an answer to random questions which then correspond to a planet. For ease, I have added 8 choices in each question so every choice is linked to a planet and I also have 9 questions so no matter what the result cannot be a tie – dua diy Jul 22 '23 at 04:58
  • I have tried adding this function but the thing is if I choose 2 planets alternatively (earth and venus) then earthScore =4 , venusScore =5 but since the loop is checking for just greater than 2 it stops the loop and gives Earth ass answer even if venus is right and I can't do greater the 4 because if the user choose each planet in every question then in question 9 only one of the planets will have a score of 2 and I won't have an answer. `function updateResult() { if (earthScore >= 2) { result.innerHTML = 'you are earth'} else if (venusScore > 2) { result.innerHTML = "you are venus"` – dua diy Jul 22 '23 at 05:14
  • thanks for helping and sorry for bothering but I am still a beginner in high school and I love doing BuzzFeed quizzes so I thought I will make one. I am watching a course but it only has 3 questions and since I am interested in astronomy I thought I will do planets one but I didn't know how much harder it is going to be than a 3 questions and 2 choices quiz – dua diy Jul 22 '23 at 05:25
  • @duadiy then you can search for your items as `document.querySelectorAll("#q1a1,#q1a2,#q1a3,#q1a4,#q1a5,#q1a6,#q1a7,#q1a8")` I recommend adding a class to your elements to make it more generic. Imagine when you have 200 items. Or 2000. Also, I would not create a function for each element. Imagine when you have 10000 elements. Would it be feasible to have 10000 separate functions or is it better to have very few functions that cover a generalized pattern? Of course it is the latter. This is why I created the `counts` variable and injected keys into it so that I can reuse the same pattern... – Lajos Arpad Jul 22 '23 at 10:58
  • @duadiy ... for each and every element. My second Javascript code would work even if you had 200 or 20000 or whatever number of planets. This is an important lesson in programming. You need your code to be as agnostic to the input as possible, that's how you can write powerful code. There can be a tie even with 9 questions. Imagine the case when Earth and Venus were chosen 4-4 times and Uranus was chosen 1 time. In this case there would be a tie between Earth and Venus. A possible solution to break some ties would be to have an additional bonus question that is only shown in a case of a tie – Lajos Arpad Jul 22 '23 at 11:10
  • @duadiy and only the options of the tied planets would be choosable. So, if there is a tie between Earth and Venus, then you display an additional question and only the Earth and Venus options are being displayed. You might want to ask a new question with your current code. It seems to be a new problem to solve, which surpasses the scope of a comment. In the new question share your exact code as a snippet where the issue can be reproduced and notify me here in the comment-section. Please don't worry about asking questions. I am happy to help – Lajos Arpad Jul 22 '23 at 11:18
  • @duadiy the reason as of why it's more difficult for 3 items than for two is that in the specific case when you only have two items, you can simply compare them, whereas in the case of 3, you need to find the maximum. Luckily, it's not a difficult pattern, so, if you are already at it, you can generalize it. – Lajos Arpad Jul 22 '23 at 11:19
  • i have added class planet to each button but now the buttons are not working since the functions are not defined and I don't understand the document. query because I think you said to add it if I don't have a class planet but now I do – dua diy Jul 22 '23 at 11:57
  • @duadiy please create a new question with your current code and write a comment here. That would enable me to help you. What is the class name that you added? If it's `planet`, then `document.getElementsByClassName("planet")` should yield these elements. – Lajos Arpad Jul 22 '23 at 12:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254626/discussion-between-dua-diy-and-lajos-arpad). – dua diy Jul 22 '23 at 12:35