Quiz Game with Leaderboard 🎮

import tkinter as tk

from tkinter import messagebox

import random

import json


# Load questions from a JSON file or use a dictionary

questions = [

    {"question": "What keyword is used to define a function in Python?", 

     "options": ["func", "define", "def", "function"], 

     "answer": "def"},

    

    {"question": "Which of the following is used to create a loop in Python?", 

     "options": ["for", "while", "do-while", "Both A and B"], 

     "answer": "Both A and B"},

    

    {"question": "What is the correct way to open a file in read mode?", 

     "options": ["open('file.txt', 'r')", "open('file.txt', 'w')", "open('file.txt', 'rw')", "open('file.txt')"], 

     "answer": "open('file.txt', 'r')"},

    

    {"question": "Which data structure follows the Last In, First Out (LIFO) principle?", 

     "options": ["Queue", "Stack", "List", "Dictionary"], 

     "answer": "Stack"},

    

    {"question": "Which method is used to add an element to a list?", 

     "options": ["append()", "insert()", "extend()", "add()"], 

     "answer": "append()"},

    

    {"question": "Which library is commonly used for data analysis in Python?", 

     "options": ["NumPy", "Pandas", "Matplotlib", "Seaborn"], 

     "answer": "Pandas"},

    

    {"question": "Which symbol is used to comment a single line in Python?", 

     "options": ["//", "#", "/*", "--"], 

     "answer": "#"},

    

    {"question": "What will be the output of `len(['Python', 'Java', 'C++'])`?", 

     "options": ["2", "3", "4", "Error"], 

     "answer": "3"},

    

    {"question": "What does the `range(5)` function return?", 

     "options": ["[1,2,3,4,5]", "[0,1,2,3,4]", "(0,1,2,3,4)", "None"], 

     "answer": "[0,1,2,3,4]"},

    

    {"question": "Which of the following is a mutable data type in Python?", 

     "options": ["Tuple", "String", "List", "Integer"], 

     "answer": "List"}

]



# Load leaderboard from file

def load_leaderboard():

    try:

        with open("leaderboard.json", "r") as f:

            return json.load(f)

    except FileNotFoundError:

        return {}


# Save leaderboard to file

def save_leaderboard(leaderboard):

    with open("leaderboard.json", "w") as f:

        json.dump(leaderboard, f, indent=4)


class QuizGame:

    def __init__(self, root):

        self.root = root

        self.root.title("Quiz Game with Leaderboard")

        self.root.geometry("500x400")


        self.score = 0

        self.current_question = 0

        self.username = ""


        self.start_screen()


    def start_screen(self):

        """Start screen to enter player's name."""

        self.clear_window()

        

        tk.Label(self.root, text="Enter Your Name:", font=("Arial", 14)).pack(pady=10)

        self.name_entry = tk.Entry(self.root, font=("Arial", 12))

        self.name_entry.pack(pady=5)

        

        tk.Button(self.root, text="Start Quiz", command=self.start_quiz, font=("Arial", 12)).pack(pady=20)


    def start_quiz(self):

        """Start the quiz after getting the user's name."""

        self.username = self.name_entry.get()

        if not self.username:

            messagebox.showerror("Error", "Please enter your name!")

            return

        

        random.shuffle(questions)

        self.score = 0

        self.current_question = 0

        self.show_question()


    def show_question(self):

        """Display a question and answer options."""

        self.clear_window()

        

        if self.current_question < len(questions):

            q_data = questions[self.current_question]

            self.correct_answer = q_data["answer"]


            tk.Label(self.root, text=f"Q{self.current_question + 1}: {q_data['question']}", font=("Arial", 14), wraplength=400).pack(pady=10)

            

            self.answer_var = tk.StringVar()


            for option in q_data["options"]:

                tk.Radiobutton(self.root, text=option, variable=self.answer_var, value=option, font=("Arial", 12)).pack(anchor="w", padx=20)

            

            tk.Button(self.root, text="Submit", command=self.check_answer, font=("Arial", 12)).pack(pady=10)

        

        else:

            self.show_result()


    def check_answer(self):

        """Check the selected answer."""

        selected_answer = self.answer_var.get()

        

        if not selected_answer:

            messagebox.showerror("Error", "Please select an answer!")

            return

        

        if selected_answer == self.correct_answer:

            self.score += 1

        

        self.current_question += 1

        self.show_question()


    def show_result(self):

        """Display the final score and update leaderboard."""

        self.clear_window()

        

        leaderboard = load_leaderboard()

        leaderboard[self.username] = self.score

        save_leaderboard(leaderboard)


        tk.Label(self.root, text=f"Quiz Over! {self.username}, your score: {self.score}/{len(questions)}", font=("Arial", 14)).pack(pady=10)


        tk.Button(self.root, text="View Leaderboard", command=self.show_leaderboard, font=("Arial", 12)).pack(pady=10)

        tk.Button(self.root, text="Play Again", command=self.start_screen, font=("Arial", 12)).pack(pady=5)

        tk.Button(self.root, text="Exit", command=self.root.quit, font=("Arial", 12)).pack(pady=5)


    def show_leaderboard(self):

        """Display the leaderboard."""

        self.clear_window()

        leaderboard = load_leaderboard()

        sorted_leaderboard = sorted(leaderboard.items(), key=lambda x: x[1], reverse=True)


        tk.Label(self.root, text="🏆 Leaderboard 🏆", font=("Arial", 16, "bold")).pack(pady=10)


        for rank, (player, high_score) in enumerate(sorted_leaderboard, start=1):

            tk.Label(self.root, text=f"{rank}. {player} - {high_score}", font=("Arial", 12)).pack()


        tk.Button(self.root, text="Back to Menu", command=self.start_screen, font=("Arial", 12)).pack(pady=10)


    def clear_window(self):

        """Clear the window for new content."""

        for widget in self.root.winfo_children():

            widget.destroy()


# Run the application

if __name__ == "__main__":

    root = tk.Tk()

    app = QuizGame(root)

    root.mainloop()

No comments: