Quiz Game Application

Quiz Game Application in Python with Difficulty Levels and Leaderboard

Project Overview

In this Python-based quiz game, the user can select from different difficulty levels (Easy, Medium, and Hard) and answer a series of multiple-choice questions. The game randomly selects questions based on the difficulty level chosen, keeping track of the user’s score and the time remaining. At the end of the quiz, the user receives feedback on their performance, and the score is added to a leaderboard, where it can be reviewed by other players. This application works by reading a questions.csv file, which stores the quiz questions and answers, and utilizing different Python libraries to provide an engaging quiz experience.

Download the example questions.csv file from here to use in your quiz application.

Key Features:

  • Dynamic Question Selection: Questions are loaded from a CSV file based on the difficulty level chosen by the user.
  • Time-Based Quiz: The user is given a set amount of time to answer each question, creating a sense of urgency.
  • Leaderboard: Scores are stored in a leaderboard file and displayed after each quiz, with rankings based on the user’s points.
  • Feedback System: After completing the quiz, users receive personalized feedback on their performance.

Flow of the Program

  • Loading Questions: The quiz loads questions from the questions.csv file, which contains columns for the question, options, correct answer, and difficulty level. Based on the selected difficulty level, the program filters the questions to display only those that match the user’s choice.
  • Difficulty Selection: The user selects the difficulty level: Easy, Medium, or Hard. This choice dictates the number of questions asked, the time allotted to complete the quiz, and the level of difficulty for each question.
  • Timer and Scorekeeping: Once the quiz starts, a timer begins, and the user is shown each question along with multiple-choice options. The user must select an answer within a set time limit. If the timer runs out, the quiz ends early.
  • Answer Validation: After each question, the program validates the user’s input and records their answer. If the answer is correct, the score increases. The final score is displayed at the end of the quiz.
  • Leaderboard: At the end of the quiz, the user is prompted to enter their name, and their score is saved to the leaderboard, which is displayed after the quiz. The leaderboard ranks players by their points and the difficulty level they completed.
  • Feedback: The program provides feedback based on the user’s score as a percentage of correct answers out of the total questions.

Breaking Down the Code

Let’s dive into the main parts of the Python script and explain the functionality.

Loading Questions from CSV

The load_questions function reads the questions.csv file and filters the questions by difficulty level. It uses the csv.DictReader to read the CSV file and store questions as a list of dictionaries. Each dictionary contains the question, its options, and the correct answer.

  def load_questions(filename, difficulty):
    questions = []
    with open(filename, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            if row["difficulty"] == difficulty:
                questions.append({
                    "question": row["question"],
                    "options": [row["option1"], row["option2"], row["option3"], row["option4"]],
                    "answer": row["answer"]
                })
    return questions
  

Difficulty Selection and Timer

The start_quiz function allows the user to choose the difficulty level. Depending on their choice, it assigns a specific number of questions and time limits for the quiz.

  def start_quiz():
    # Ask the user to select a difficulty level
    print("Welcome to the Quiz Game!")
    print("Please choose the difficulty level:")
    print("1. Easy")
    print("2. Medium")
    print("3. Hard")

    # Input validation for difficulty choice
    while True:
        try:
            difficulty_choice = int(input("Enter the number of your choice: "))
            if difficulty_choice == 1:
                difficulty = "Easy"
                num_questions = 10
                total_time = 120
                break
            elif difficulty_choice == 2:
                difficulty = "Medium"
                num_questions = 15
                total_time = 90
                break
            elif difficulty_choice == 3:
                difficulty = "Hard"
                num_questions = 20
                total_time = 60
                break
            else:
                print("Invalid choice. Please select 1, 2, or 3.")
        except ValueError:
            print("Invalid input. Please enter a number.")
  

Answer Validation and Scoring

For each question, the program displays the options and asks the user to select an answer. The selected answer is validated to ensure it’s a valid option. The user’s score is updated based on whether their answer is correct.

  for index, q in enumerate(questions):
    # Display question and options
    print(f"Question {index + 1}: {q['question']}")
    for i, option in enumerate(q["options"], start=1):
        print(f"{i}. {option}")
    
    # Validate user input and score
    while True:
        try:
            answer = int(input("Enter the number of your answer: "))
            if 1 <= answer <= len(q["options"]):
                break
            else:
                print("Invalid choice. Please select a valid option.")
        except ValueError:
            print("Invalid input. Please enter a number.")
    
    # Store the user's answer for review
    if q["options"][answer - 1] == q["answer"]:
        score += 1
  

Saving and Displaying the Leaderboard

The leaderboard is stored in a text file (leaderboard.txt). The leaderboard is updated after each quiz session and displayed to the user in order of rank.

  def save_leaderboard(filename, leaderboard):
    with open(filename, 'w') as file:
        for entry in leaderboard:
            file.write(f"{entry[0]},{entry[1]},{entry[2]}\n")

def display_leaderboard(leaderboard):
    print("\nLeaderboard:")
    if leaderboard:
        for rank, entry in enumerate(leaderboard, start=1):
            print(f"{rank}. {entry[0]} - {entry[1]} points - Difficulty: {entry[2]}")
    else:
        print("No scores yet!")
  

Feedback System

After the quiz ends, the user receives feedback based on the percentage of correct answers.

  def give_feedback(score, total_questions):
    percentage = (score / total_questions) * 100
    if percentage == 100:
        return "Excellent! Perfect score!"
    elif percentage >= 80:
        return "Great job! You're almost there!"
    elif percentage >= 50:
        return "Good effort! Keep practicing!"
    else:
        return "You can do better. Try again!"
  

Final Code

Here is the complete code for the Quiz Game Application

  import time
import csv
import random
import os

# Function to load questions from a CSV file based on the selected difficulty
def load_questions(filename, difficulty):
    questions = []
    with open(filename, newline='', encoding='utf-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            if row["difficulty"] == difficulty:
                questions.append({
                    "question": row["question"],
                    "options": [row["option1"], row["option2"], row["option3"], row["option4"]],
                    "answer": row["answer"]
                })
    return questions

# Function to load leaderboard
def load_leaderboard(filename):
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            leaderboard = file.readlines()
        leaderboard = [line.strip().split(",") for line in leaderboard]
        return leaderboard
    else:
        return []

# Function to save leaderboard
def save_leaderboard(filename, leaderboard):
    with open(filename, 'w') as file:
        for entry in leaderboard:
            file.write(f"{entry[0]},{entry[1]},{entry[2]}\n")

# Function to display leaderboard
def display_leaderboard(leaderboard):
    print("\nLeaderboard:")
    if leaderboard:
        for rank, entry in enumerate(leaderboard, start=1):
            print(f"{rank}. {entry[0]} - {entry[1]} points - Difficulty: {entry[2]}")
    else:
        print("No scores yet!")

# Function to give feedback based on score
def give_feedback(score, total_questions):
    percentage = (score / total_questions) * 100
    if percentage == 100:
        return "Excellent! Perfect score!"
    elif percentage >= 80:
        return "Great job! You're almost there!"
    elif percentage >= 50:
        return "Good effort! Keep practicing!"
    else:
        return "You can do better. Try again!"

# Function to start the quiz
def start_quiz():
    # Ask the user to select a difficulty level
    print("Welcome to the Quiz Game!")
    print("Please choose the difficulty level:")
    print("1. Easy")
    print("2. Medium")
    print("3. Hard")

    # Input validation for difficulty choice
    while True:
        try:
            difficulty_choice = int(input("Enter the number of your choice: "))
            if difficulty_choice == 1:
                difficulty = "Easy"
                num_questions = 10
                total_time = 120
                break
            elif difficulty_choice == 2:
                difficulty = "Medium"
                num_questions = 15
                total_time = 90
                break
            elif difficulty_choice == 3:
                difficulty = "Hard"
                num_questions = 20
                total_time = 60
                break
            else:
                print("Invalid choice. Please select 1, 2, or 3.")
        except ValueError:
            print("Invalid input. Please enter a number.")
    
    # Start the timer and quiz
    score = 0
    start_time = time.time()  # Record the start time

    # Load questions based on the chosen difficulty level
    questions = load_questions("questions.csv", difficulty)
    
    # Limit the number of questions to be asked
    questions = random.sample(questions, num_questions)  # Randomly select questions

    # List to store user's answers for review
    user_answers = []

    # Loop through each question in the list
    for index, q in enumerate(questions):
        # Display time remaining
        elapsed_time = time.time() - start_time
        remaining_time = total_time - elapsed_time
        print(f"Time Remaining: {round(remaining_time, 2)} seconds")
        
        # If time is up, exit the quiz
        if remaining_time <= 0:
            print("\nTime's up!")
            break
        
        print(f"Question {index + 1}: {q['question']}")
        
        # Display options
        for i, option in enumerate(q["options"], start=1):
            print(f"{i}. {option}")
        
        # Record user input and validate answer
        while True:
            try:
                answer = int(input("Enter the number of your answer: "))
                if 1 <= answer <= len(q["options"]):
                    break
                else:
                    print("Invalid choice. Please select a valid option.")
            except ValueError:
                print("Invalid input. Please enter a number.")
        
        # Store the user's answer for review
        user_answers.append({"question": q['question'], "user_answer": q['options'][answer - 1], "correct_answer": q['answer']})

        # Check if the answer is correct
        if q["options"][answer - 1] == q["answer"]:
            score += 1
        
        print("\n----------------------------\n")

    # Show final score and time taken
    elapsed_time = time.time() - start_time
    print(f"Quiz Over! Your final score is {score}/{len(questions)}")
    print(f"Time taken: {round(elapsed_time, 2)} seconds")
    print(give_feedback(score, len(questions)))

    # Ask if the user wants to review their answers
    review_choice = input("Would you like to review your answers? (y/n): ").strip().lower()
    if review_choice == 'y':
        for answer in user_answers:
            print(f"Question: {answer['question']}")
            print(f"Your Answer: {answer['user_answer']}")
            print(f"Correct Answer: {answer['correct_answer']}")
            print("----------------------------")

    # Ask if the user wants to retry the quiz
    retry_choice = input("Would you like to retry the quiz? (y/n): ").strip().lower()
    if retry_choice == 'y':
        start_quiz()

    # Load the leaderboard
    leaderboard = load_leaderboard("leaderboard.txt")

    # Ask the user if they want to add their score to the leaderboard
    add_to_leaderboard = input("Would you like to add your score to the leaderboard? (y/n): ").strip().lower()
    if add_to_leaderboard == 'y':
        name = input("Enter your name: ").strip()
        leaderboard.append([name, score, difficulty])  # Store name, score, and difficulty
        leaderboard = sorted(leaderboard, key=lambda x: int(x[1]), reverse=True)[:5]  # Top 5 scores only
        save_leaderboard("leaderboard.txt", leaderboard)

    # Display the updated leaderboard
    display_leaderboard(leaderboard)

# Start the quiz
if __name__ == "__main__":
    start_quiz()
  

sample output

Quiz Game Application by python e1734757420494
Quiz Game Application by python02
Quiz Game Application by python03
Quiz Game Application by python04
Quiz Game Application by python05 e1734757573324

Let’s walk through an example of how this quiz program works in a real scenario. For this walkthrough, we’ll assume the user is playing the quiz with the "Medium" difficulty level.1. Starting the Quiz: When the user starts the quiz, the program first prompts them to choose the difficulty level. Since the user selects "2" for "Medium", the program proceeds with the following settings: - 15 questions will be asked. - The total time allotted for the quiz is 90 seconds. The program then loads the questions for the "Medium" difficulty level from the questions.csv file, selecting random questions from the available pool.2. Displaying Questions: The quiz begins, and the user is shown the first question:Time Remaining: 89.5 seconds Question 1: Who was the 16th president of the United States? 1. Abraham Lincoln 2. George Washington 3. John F. Kennedy 4. Theodore RooseveltThe user sees the options and is asked to select one by entering the corresponding number. In this case, the correct answer is "Abraham Lincoln."3. User Input and Answer Checking: The user enters "1" to select "Abraham Lincoln." The program checks if this is the correct answer: - If the answer is correct, the score is incremented by 1. - If the answer is incorrect, no points are awarded.The program then proceeds to the next question, showing the time remaining and the next set of options:Time Remaining: 88.2 seconds Question 2: What is the formula for calculating the area of a circle? 1. πr^2 2. 2πr 3. r^2 4. πdIf the user selects "1" (which is the correct answer), the program increments the score by another 1 point. The user can continue answering the questions in this manner until the quiz is over or time runs out.4. Time Management: As the quiz progresses, the time countdown is displayed at the beginning of each question. For example, after the first question, the time might read:Time Remaining: 87.5 secondsThis gives the user a real-time view of how much time they have left to answer each question. If the time reaches zero, the quiz automatically ends, and the user is informed that the time is up.5. Ending the Quiz: Once all the questions have been answered or the time runs out, the program displays the total score and the corresponding feedback. For example, if the user answers 12 questions correctly out of 15:You scored: 12/15 Feedback: Great job! You're almost there!The feedback is based on the percentage of correct answers, which in this case is:(12 / 15) * 100 = 80%Since 80% falls under the "Great job!" category, the user receives positive feedback encouraging them to continue practicing.6. Leaderboard Update: After receiving feedback, the user is asked if they want to view the leaderboard. If they do, the program displays the list of top scorers. If the user is among the top scorers, their score is added to the leaderboard, which is saved and displayed for future reference. For example:Leaderboard: 1. John Doe - 14 points - Difficulty: Medium 2. Jane Smith - 13 points - Difficulty: Medium 3. You - 12 points - Difficulty: MediumExample with User Interaction: Let’s simulate a session where the user answers three questions.1. User Start:Welcome to the Quiz Game! Please choose the difficulty level: 1. Easy 2. Medium 3. Hard Enter the number of your choice: 22. Question 1:Time Remaining: 89.5 seconds Question 1: Who was the 16th president of the United States? 1. Abraham Lincoln 2. George Washington 3. John F. Kennedy 4. Theodore Roosevelt Enter the number of your answer: 1The user selects "1" (correct answer).3. Question 2:Time Remaining: 84.3 seconds Question 2: What is the formula for calculating the area of a circle? 1. πr^2 2. 2πr 3. r^2 4. πd Enter the number of your answer: 1The user selects "1" (correct answer).4. Question 3:Time Remaining: 78.1 seconds Question 3: Who invented the telephone? 1. Alexander Graham Bell 2. Thomas Edison 3. Michael Faraday 4. Galileo Galilei Enter the number of your answer: 1The user selects "1" (correct answer).5. End of Quiz:You scored: 3/3 Feedback: Excellent! Perfect score!6. Leaderboard:Leaderboard: 1. John Doe - 14 points - Difficulty: Medium 2. Jane Smith - 13 points - Difficulty: Medium 3. You - 3 points - Difficulty: Medium

Conclusion

This Python-based quiz game is a fun and educational project for developers looking to practice file handling, user input validation, and basic game mechanics. The modular approach to loading questions, validating user input, and maintaining a leaderboard ensures scalability and reusability. By using libraries like csv, time, and os, this project demonstrates how to create a fully functional interactive game in Python.

End of Post

Leave a Reply

Your email address will not be published. Required fields are marked *