From 259224822b64bcb6f02bf37581548404337ae398 Mon Sep 17 00:00:00 2001
From: Ruchit <56220571+ruchit-t@users.noreply.github.com>
Date: Sun, 3 Dec 2023 17:57:08 -0500
Subject: [PATCH] Add General Quiz Game
Added Python Script to create a web-based quiz game with more than 20 categories and 3 levels of difficulties
---
Games/General Quiz Game/README.md | 94 +++++++++++++++
Games/General Quiz Game/quiz.py | 147 +++++++++++++++++++++++
Games/General Quiz Game/requirements.txt | 6 +
3 files changed, 247 insertions(+)
create mode 100644 Games/General Quiz Game/README.md
create mode 100644 Games/General Quiz Game/quiz.py
create mode 100644 Games/General Quiz Game/requirements.txt
diff --git a/Games/General Quiz Game/README.md b/Games/General Quiz Game/README.md
new file mode 100644
index 0000000..b5548ea
--- /dev/null
+++ b/Games/General Quiz Game/README.md
@@ -0,0 +1,94 @@
+# Welcome to Quiz Master, a fun and interactive quiz game built in Python using the Pygame library Streamlit.
+
+You can try out the game here =======> https://quiz-master.streamlit.app/
+
+ This README will provide you with all the information you need to understand the game's objective, rules, technology stack, and setup instructions.
+
+## Game Objective and Rules
+
+The objective of this game is to answer the most questions correctly. Each round will have ten questions that will come from categories and difficulty levels of your choosing. Take your time as you answer the questions. There is no time limit. Above all else, have fun! You have full autonomy over the questions you receive.
+
+ Step 1: Select a Category
+
+You will start the game by selecting the category you want your questions to be randomly generated from. These categories could range from Entertainment to Science. Please select a category that would provide the most enjoyable experience for this round. After the game starts, you can change your category if you desire for each question.
+
+When a category has been selected, the first question and corresponding answer choices will appear. You will have the opportunity to change your category after previewing a question.
+
+ Step 2: Select the Level of Difficulty
+
+For the best experience, you should select the difficulty level after selecting the category. The first question will default to the easy difficulty level. The levels of difficulty range from Easy to Medium to Hard. Please be sure to pick a level of difficulty that would provide the most enjoyable experience for you. If you change from the default difficulty level, the question will change to reflect the new chosen level.
+
+Please review the question before you submit your answer. When an answer has been submitted, it will count towards your final score. You will not be able to go back and change the difficulty level or category for any previous question.
+
+Most importantly, challenge yourself and your friends and have fun! Correct answers will be displayed for every wrong answer. At the end of the game, your score will be revealed. To start a new round, please refresh the page.
+
+ Will you be the next Quiz Master? Play this game and find out!
+
+
+
+## Technology Stack
+
+The Quiz-Master game is developed in Python language and uses [Streamlit](https://streamlit.io/), which is an open-source Python library that is designed to make it easy to create web applications. It allows you to turn data scripts into shareable web apps quickly and with minimal effort. Streamlit is gaining popularity because it offers a simple and intuitive way to build interactive data-driven applications. It is mainly used for creating the user interface of the game. It allows for easy web app development with Python. Packages like Requests, used for making HTTP requests, JSON library is used for encoding and decoding JSON data are included in the project. Other general libraries like datetime, pandas, numpy, and plotly are used.
+
+The modules and functions used in the game development are discussed below:
+
+The code begins with import statements to bring in the necessary libraries and packages.
+
+get_category(): This function fetches all the available quiz categories from the Open Trivia Database API and returns them as a dictionary.
+
+get_question(): Based on the selected category and difficulty, it returns a list of questions.
+
+initialize_session_state(): It initializes the game state, which includes the current question index and player score, using Streamlit’s session state.
+
+update_score(): This function compares the player's choice with the correct answer and updates the player's score accordingly. If the player's choice matches the correct answer, the score is incremented. Streamlit components like "st.success" and "st.error" are used to provide feedback to the player
+
+UI Setup: The code sets up the user interface using Streamlit. It allows the user to select a quiz category, difficulty level, and provides options to answer questions and navigate through the quiz.
+
+calculate_score(): This function includes most of the functionality of the application. It calculates the player’s score by comparing their choices with the correct answer and then updates the session. This part has Streamlit’s UI components for creating the game, such as st.title, st.subheader, st.sidebar, st.radio, and st.button. Inside the function, it compares player_choice with correct_answer and decides whether to increase the player's score or not. The updated player score is stored in Streamlit’s session state so that it persists across different questions in the game.
+
+Category Selection: A Streamlit select box allows the user to choose from among the various categories that the code has retrieved.
+
+Selection of Difficulty Level: Using a choose box, the user may select between three difficulty levels: easy, medium, and hard.
+
+Question Fetching: Questions are retrieved from the API based on the chosen category and level of difficulty. The "quiz_questions" list is where these questions are processed and kept.
+
+Question Display: The code controls how questions are shown, letting the player choose their response by pressing a radio button.
+
+Answer Submission: The "calculate_score" function is triggered when the player submits an answer.
+
+Getting Around the Quiz: After submitting an answer, the code shows the next question, allowing players to move around the quiz. The quiz ends and the final score is shown once every question has been answered.
+
+
+
+## Setup and Deployment Instructions
+
+👨🏻💻 How to run the app?
+
+Step 1: Clone the repo
+
+Step 2: Create virtual environment: 'python -m venv '
+
+Step 3: Activate the environment: '\Scripts\activate'
+
+Step 4: Install the dependencies: pip install -r requirements.txt
+
+step 5: Run it on local host: 'streamlit run QuizMaster.py'
+
+The Dashboard can be accessed via following link: https://quiz-master.streamlit.app/
+
+## Credits & Acknowledgements
+
+Streamlit v1.27.0
+https://streamlit.io | Copyright 2023 Snowflake Inc. All rights reserved.
+
+Numpy v1.19.1
+https://numpy.org/ | Harris, C.R., Millman, K.J., van der Walt, S.J. et al. Array programming with NumPy. Nature 585, 357–362 (2020). DOI: 10.1038/s41586-020-2649-2. (Publisher link).
+
+Pandas v1.2.0
+https://pandas.pydata.org/docs/index.html | 2023 pandas via NumFOCUS, Inc. Hosted by OVHcloud.
+
+Requests v2.24.0
+https://requests.readthedocs.io/en/latest/ | ©MMXVIX. A Kenneth Reitz Project.
+
+
+----------------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/Games/General Quiz Game/quiz.py b/Games/General Quiz Game/quiz.py
new file mode 100644
index 0000000..0625313
--- /dev/null
+++ b/Games/General Quiz Game/quiz.py
@@ -0,0 +1,147 @@
+'''
+Project 1: Web Based Game
+Author: Ruchit Tripathi
+'''
+
+import streamlit as st
+import plotly.express as px
+import plotly.graph_objects as go
+import numpy as np
+import pandas as pd
+import json as js
+import requests as rq
+import time
+from datetime import datetime, timedelta
+import altair as alt
+import random
+
+# Logic to add background images (Future Enhancement)
+# def set_bg_hack_url():
+# '''
+# A function to unpack an image from url and set as bg.
+# Returns
+# -------
+# The background.
+# '''
+
+# st.markdown(
+# f"""
+#
+# """,
+# unsafe_allow_html=True
+# )
+
+def get_category():
+ category_dict = dict()
+ category_json_list = rq.get("https://opentdb.com/api_category.php").json()
+ for item in category_json_list['trivia_categories']:
+ category_dict[item['name']] = item['id']
+ return category_dict
+
+@st.cache_data(ttl= 75, max_entries=1)
+def get_question(category,difficulty):
+ questions = rq.get("https://opentdb.com/api.php?amount=10"+"&category="+str(category)+"&difficulty="+str(difficulty)).json()["results"]
+ return questions
+
+def initialize_session_state():
+ if 'current_question' not in st.session_state:
+ st.session_state.current_question = 0
+ # st.snow()
+ if 'player_score' not in st.session_state:
+ st.session_state.player_score = 0
+
+def update_score(player_choice, correct_answer):
+ if str(player_choice) == str(correct_answer):
+ st.success("It was a correct answer! Great Job! 😁✌")
+ st.session_state.player_score += 1
+ st.balloons()
+ else:
+ st.error("It was an incorrect answer! 😕")
+
+if "page" not in st.session_state:
+ st.session_state.page = 0
+if "submit_key" in st.session_state and st.session_state.submit_key == True:
+ st.session_state.running = True
+else:
+ st.session_state.running = False
+
+if "running" not in st.session_state:
+ st.session_state.running = False
+
+def nextpage(): st.session_state.page += 1
+def restart(): st.session_state.page = 0
+
+# set_bg_hack_url()
+st.markdown("",unsafe_allow_html = True)
+st.title(":orange[Welcome to the] :violet[QuizMaster!] 🧩")
+st.subheader("_Engage, Entertain, and Educate with QuizMaster - Where Knowledge Meets Fun!_", divider= 'rainbow')
+st.sidebar.title("Tune the Options to Play the Game")
+st.sidebar.markdown("---")
+initialize_session_state()
+
+def calculate_score(player_choice):
+ correct_answer = quiz_questions[st.session_state.current_question]["answer"]
+ # st.write("inside calculate_score" + str(correct_answer))
+ update_score(player_choice, correct_answer)
+ st.session_state.current_question += 1
+
+categories_option = get_category()
+category = st.sidebar.selectbox("Category: ", list(categories_option.keys()), index= None, placeholder= "Select one: ", disabled=(st.session_state.running))
+# st.session_state.disable_opt = True
+# category = st.sidebar.selectbox("Category: ", list(categories_option.keys()), index= None, placeholder= "Select one: ", disabled=(st.session_state.running))
+if category is None:
+ st.warning('Please select one category to start the game', icon="⚠️")
+else:
+ levels = st.sidebar.selectbox("Difficulty Level: ", ['Easy', 'Medium', 'Hard'], disabled=(st.session_state.running))
+ QuestionList = get_question(categories_option[category], levels.lower())
+ # st.write(QuestionList)
+ len_response = len(QuestionList)
+ if len_response == 0:
+ st.error("This Category has no question for the given difficulty mode at the source side! Please select another difficulty level or category to start the game! 😕😔")
+ st.stop()
+ quiz_questions = []
+ for item in range(len_response):
+ temp_dict = dict()
+ temp_dict['text'] = QuestionList[item].get("question")
+ temp_dict['options'] = tuple(QuestionList[item].get("incorrect_answers") + [QuestionList[item].get("correct_answer")])
+ temp_dict['answer'] = QuestionList[item].get("correct_answer")
+ quiz_questions.append(temp_dict)
+ placeholder = st.empty()
+ ind = st.session_state.current_question
+ if ind > len(quiz_questions):
+ st.stop()
+ else:
+ current_question = quiz_questions[ind]
+ st.subheader(quiz_questions[ind]["text"])
+ player_choice = st.radio("Select your answer:",
+ options= current_question["options"],
+ key=f"question_{ind}", disabled=(st.session_state.running))
+ submitted = st.button("Submit", key="submit_key", disabled=(st.session_state.running))
+ if submitted:
+ calculate_score(player_choice)
+ st.markdown("Correct Answer: "+ current_question["answer"])
+ # st.empty()
+ if st.button("Next",on_click=nextpage,disabled=(st.session_state.page >= 9)):
+ if st.session_state.current_question < len(quiz_questions):
+ st.rerun()
+ if st.session_state.current_question >= len(quiz_questions):
+ # st.session_state.clear
+ st.empty()
+ st.success("Quiz Finished!")
+ st.subheader(f"_Your_ _Score_: :blue[{st.session_state.player_score}] :sunglasses:")
+ st.snow()
+
+st.markdown("---")
+st.info("Reload the page or press F5 to restart the game!")
+st.sidebar.markdown("---")
+st.sidebar.markdown("### About Developer", unsafe_allow_html=True)
+st.sidebar.markdown("Visit Ruchit's LinkedIn and Github profiles for more information & updates.", unsafe_allow_html=True)
+st.sidebar.markdown("### About Contributors", unsafe_allow_html=True)
+st.sidebar.markdown("Stephanie's LinkedIn", unsafe_allow_html=True)
+st.sidebar.markdown("Gayatri's LinkedIn", unsafe_allow_html=True)
+st.sidebar.markdown("Thanks for visiting the site! 😃 Have Fun 😉")
\ No newline at end of file
diff --git a/Games/General Quiz Game/requirements.txt b/Games/General Quiz Game/requirements.txt
new file mode 100644
index 0000000..4a286d1
--- /dev/null
+++ b/Games/General Quiz Game/requirements.txt
@@ -0,0 +1,6 @@
+pandas >=1.2.0
+plotly>=4.9.0
+requests==2.24.0
+numpy >=1.19.1
+streamlit>=1.27.0
+altair<5
\ No newline at end of file