quiz.js

//Variable Declaration
const question = document.querySelector('#question'); //This variable represents the HTML element with the id "question".
const cardContainer = document.querySelector('.card-container'); //class "card-container"
const dropText = document.querySelector('.drop-text'); //class "drop-text"
const progressText = document.querySelector('#progressText'); //id "progressText"
const scoreText = document.querySelector('#score'); //id "score"
const progressBarFull = document.querySelector('#progressBarFull'); //id "progressBarFull"

const declaration - creates block-scoped constants, much like variables declared using the let keyword. Document method querySelector() - returns the first Element within the document that matches the specified selector, or group of selectors.

//Variable Initialization
let currentQuestion = {}; //this variable stores the currently displayed question object
let acceptingAnswers = true; //this variable determines whether the user's answers are accepted or not
let score = 0; //score variable holds current score
let questionCounter = 0; //this variable keeps track of the number of questions answered
let availableQuestions = []; //this variable stores the array of available questions
let selectedChoice = null; //this variable holds the selected choice by the user
//Array of Questions
let questions = [ //declared and initialized the array "questions" with properties like "question" "choice1" to "choice4" and "answer"
    {
        question: 'Which of the following expressions evaluate to 3.5? \n I. (double) 2 / 4 + 3  \n  II. (double) (2 / 4) + 3  \n III.(double) (2 / 4 + 3) ',
        choice1: 'I only',
        choice2: 'II and III only',
        choice3: 'I and II only',
        choice4: 'I, II, and III',
        answer: 1,  
    },
    {
        question: 'Assume that a, b, and c are boolean variables that have been properly declared and initialized. Which of the following boolean expressions is equivalent to !(a && b) || c ?',
        choice1: 'a || b || c',
        choice2: '!a && !b || c',
        choice3: '!a && !b && c',
        choice4: '!a || !b || c',
        answer: 4, 
    },
    ...
];
//Constants
const SCORE_POINTS = 100; // points awarded for each correct answer
const MAX_QUESTIONS = 9; // maximum number of questions in the game
// Function to start the game
startGame = () => { //initializes the game by resetting the question counter, score, and available questions
    questionCounter = 0;
    score = 0;
    availableQuestions = [...questions]; //spread operator to get all the question values in the array
    getNewQuestion(); //calls getNewQuestion function to display a new questions
};

startGame = () => { ... };

Arrow functions allow us to write shorter function syntax (w3schools)

The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places.

// Function to retrieve and display a new question
getNewQuestion = () => {
    if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) {
        localStorage.setItem('mostRecentScore', score); //save to local storage (not working)

        return (window.location.href = 'https://tianbinliu.github.io/CSA-FinalProject/');  //redirect to the menu page
    }

    questionCounter++;  //increment question counter
    //update progress text and progress var
    progressText.innerText = `Question ${questionCounter} of ${MAX_QUESTIONS}`; //question 1 of 4, 2 of 4, etc. incrementing by 1 each time
    progressBarFull.style.width = `${(questionCounter / MAX_QUESTIONS) * 100}%`; //calculate what question we are on and correspond w/ the percentage

    //select a random question form the available questions
    const questionsIndex = Math.floor(Math.random() * availableQuestions.length); //calculate value of the question index
    currentQuestion = availableQuestions[questionsIndex]; //keep track of what questions we are on
    question.innerText = currentQuestion.question; //know what the question asked


    cardContainer.innerHTML = ''; // Clear the card container, remove previous answer choices
    for (let i = 1; i <= 4; i++) { //loop 4 times creating answer choice elements for each iteration
        const choiceCard = document.createElement('div'); //create new div and assign it to the choiceCard variable
        choiceCard.classList.add('choice-card'); //adds css class choice-card to the choiceCard element
        choiceCard.draggable = true; //allow card to be dragged and dropped
        choiceCard.dataset.number = i; 
        choiceCard.innerText = currentQuestion['choice' + i]; //set text to corresponding choice text from currentQuestion object
        cardContainer.appendChild(choiceCard);  //make answer choice visible within the container
    }

    availableQuestions.splice(questionsIndex, 1); //splice(start, deleteCount) - remove elements from an array

    acceptingAnswers = true; 

    cardContainer.addEventListener('dragstart', (e) => {
        selectedChoice = e.target.dataset.number; //assign data-number attribute from the dragged element to the selectedChoice variable
    });
};
const dropArea = document.getElementById('drop-area'); //represent drop area

// Drag and drop event listeners
dropArea.addEventListener('dragover', (e) => { //triggered when card is dragged over the drop area, allowing element to be dropped
    e.preventDefault();
  });

  dropArea.addEventListener('drop', (e) => { //triggered when card is dropped on the drop area
    e.preventDefault(); 
    if (!acceptingAnswers) return; //if accpetingAnswers = false, end game

    // Get the selected choice from the stored variable
    const selectedAnswer = selectedChoice;

    let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'; //compare selectedAnswer with the correct answer, if match, classToApply = "correct"

    console.log('classToApply:', classToApply); //console (for checking)

    if (classToApply === 'correct') { //correct answer, called incrementScore function
        incrementScore(SCORE_POINTS); 
    }

    dropArea.classList.add(classToApply); //apply styling to indicate whether the answer is correct or not

    setTimeout(() => {
        dropArea.classList.remove(classToApply);
        getNewQuestion();
    }, 1000); //delay 1 second, allow user to see visual feedback before moving on to the next question
});

e.preventDefault();

By default, dropping an element onto another element reloads the page or opens the dropped file.

// Function to increment the score
incrementScore = (num) => { 
    score += num; //adding num to score
    scoreText.innerText = score; //innerText - display score
}

startGame(); //initialize the game and display the first questions