Skip to content

Commit 321320e

Browse files
Merge pull request #122 from akshat-chd/Added_GK
Added GK Quiz to Games
2 parents 92b9176 + ec69e91 commit 321320e

3 files changed

Lines changed: 403 additions & 0 deletions

File tree

src/data/content.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import numberblocs from "../assets/numberblocks.png";
2121
import wordleicon from "../assets/games/Wordle/wordlejpg.png";
2222
import flagger from "../assets/games/flag guess/flagger.png";
2323
import Calculator from "../pages/activities/Calculator";
24+
import GKQuiz from "../pages/games/Gk_quiz"
2425
import { DogHttpCode } from "../pages/activities/DogHttpCode";
2526
import { CatHttpCode } from "../pages/activities/CatHttpCode";
2627
import FlappyBird from "../pages/games/FlappyBird";
@@ -148,6 +149,13 @@ export const games = [
148149
urlTerm: "meme-caption-maker",
149150
element: <MemeCaptionMaker />,
150151
},
152+
{
153+
title: "GK Quiz",
154+
description:"Test your general knowledge with some cool questions",
155+
icon: "https://play-lh.googleusercontent.com/5PyR8hatywCKFQV4wFfsvyK97UrgSn5S1SQILV7zs7rBP5p9VhMEIyjfp_Vdybjk8Qc",
156+
urlTerm:"Gk Quiz",
157+
element:<GKQuiz/>,
158+
},
151159
{
152160
title: "Flappy Bird",
153161
description: "Fly the bird and avoid obstacles!",

src/pages/games/Gk_quiz.js

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import React, { useEffect, useState, useRef } from "react";
2+
import "../../styles/pages/games/Gk_quiz.css";
3+
4+
const ALL_QUESTIONS = [
5+
{ q: "Which is the largest planet in our Solar System?", options: ["Earth", "Jupiter", "Saturn", "Mars"], ans: 1 },
6+
{ q: "Who wrote the national anthem of India?", options: ["Bankim Chandra Chatterjee", "Rabindranath Tagore", "Sarojini Naidu", "Jawaharlal Nehru"], ans: 1 },
7+
{ q: "Which is the longest river in the world?", options: ["Nile", "Amazon", "Ganga", "Yangtze"], ans: 0 },
8+
{ q: "The Red Planet is:", options: ["Mars", "Mercury", "Venus", "Jupiter"], ans: 0 },
9+
{ q: "Who is known as the Father of Computers?", options: ["Charles Babbage", "Alan Turing", "Tim Berners-Lee", "Bill Gates"], ans: 0 },
10+
{ q: "Which gas do plants absorb during photosynthesis?", options: ["Oxygen", "Nitrogen", "Carbon dioxide", "Hydrogen"], ans: 2 },
11+
{ q: "Which country is called the ‘Land of the Rising Sun’?", options: ["India", "Japan", "China", "South Korea"], ans: 1 },
12+
{ q: "What is the currency of the United Kingdom?", options: ["Euro", "Pound sterling", "Dollar", "Yen"], ans: 1 },
13+
{ q: "Taj Mahal is located in:", options: ["Delhi", "Agra", "Jaipur", "Varanasi"], ans: 1 },
14+
{ q: "Which organ purifies blood in the human body?", options: ["Heart", "Lungs", "Kidneys", "Brain"], ans: 2 },
15+
{ q: "What is the capital of Australia?", options: ["Sydney", "Melbourne", "Canberra", "Perth"], ans: 2 },
16+
{ q: "Which is the smallest prime number?", options: ["0", "1", "2", "3"], ans: 2 },
17+
{ q: "Who invented the light bulb?", options: ["Thomas Edison", "Alexander Graham Bell", "Nikola Tesla", "James Watt"], ans: 0 },
18+
{ q: "Which is the largest ocean on Earth?", options: ["Indian Ocean", "Atlantic Ocean", "Arctic Ocean", "Pacific Ocean"], ans: 3 },
19+
{ q: "What is the national animal of India?", options: ["Lion", "Tiger", "Elephant", "Peacock"], ans: 1 },
20+
{ q: "Which festival is known as the Festival of Lights?", options: ["Holi", "Diwali", "Eid", "Baisakhi"], ans: 1 },
21+
{ q: "How many continents are there in the world?", options: ["5", "6", "7", "8"], ans: 2 },
22+
{ q: "Which is the highest mountain in the world?", options: ["K2", "Kangchenjunga", "Mount Everest", "Nanda Devi"], ans: 2 },
23+
{ q: "Who was the first woman Prime Minister of India?", options: ["Indira Gandhi", "Sarojini Naidu", "Pratibha Patil", "Sushma Swaraj"], ans: 0 },
24+
{ q: "Which is the hardest natural substance?", options: ["Gold", "Iron", "Diamond", "Silver"], ans: 2 }
25+
];
26+
27+
const QUESTION_TIME = 15; // seconds
28+
29+
function shuffleArray(arr) {
30+
const copy = [...arr];
31+
for (let i = copy.length - 1; i > 0; i--) {
32+
const j = Math.floor(Math.random() * (i + 1));
33+
[copy[i], copy[j]] = [copy[j], copy[i]];
34+
}
35+
return copy;
36+
}
37+
38+
export default function GKQuiz() {
39+
const [questions, setQuestions] = useState([]);
40+
const [current, setCurrent] = useState(0);
41+
const [correct, setCorrect] = useState(0);
42+
const [wrong, setWrong] = useState(0);
43+
const [answered, setAnswered] = useState(false);
44+
const [chosenIndex, setChosenIndex] = useState(null);
45+
const [showResult, setShowResult] = useState(false);
46+
const [timeLeft, setTimeLeft] = useState(QUESTION_TIME);
47+
48+
// to clear interval when question changes or component unmounts
49+
const timerRef = useRef(null);
50+
51+
useEffect(() => {
52+
startQuiz();
53+
}, []);
54+
55+
// start timer whenever question changes
56+
useEffect(() => {
57+
if (questions.length === 0) return;
58+
startTimer();
59+
return () => {
60+
clearInterval(timerRef.current);
61+
};
62+
}, [current, questions]);
63+
64+
function startTimer() {
65+
clearInterval(timerRef.current);
66+
setTimeLeft(QUESTION_TIME);
67+
timerRef.current = setInterval(() => {
68+
setTimeLeft((prev) => {
69+
if (prev <= 1) {
70+
clearInterval(timerRef.current);
71+
if (!answered) {
72+
handleTimeUp();
73+
}
74+
return 0;
75+
}
76+
return prev - 1;
77+
});
78+
}, 1000);
79+
}
80+
81+
function handleTimeUp() {
82+
const qObj = questions[current];
83+
setAnswered(true);
84+
setChosenIndex(null);
85+
setWrong((w) => w + 1);
86+
}
87+
88+
function startQuiz() {
89+
const shuffled = shuffleArray(ALL_QUESTIONS).slice(0, 5);
90+
setQuestions(shuffled);
91+
setCurrent(0);
92+
setCorrect(0);
93+
setWrong(0);
94+
setAnswered(false);
95+
setChosenIndex(null);
96+
setShowResult(false);
97+
setTimeLeft(QUESTION_TIME);
98+
}
99+
100+
function handleOptionClick(index) {
101+
if (answered) return;
102+
const qObj = questions[current];
103+
setChosenIndex(index);
104+
setAnswered(true);
105+
clearInterval(timerRef.current);
106+
if (index === qObj.ans) setCorrect((c) => c + 1);
107+
else setWrong((w) => w + 1);
108+
}
109+
110+
function handleNext() {
111+
if (current === questions.length - 1) {
112+
setShowResult(true);
113+
clearInterval(timerRef.current);
114+
return;
115+
}
116+
setCurrent((c) => c + 1);
117+
setAnswered(false);
118+
setChosenIndex(null);
119+
}
120+
121+
if (questions.length === 0) return <div className="gk-quiz-loading">Loading quiz…</div>;
122+
123+
if (showResult) {
124+
const total = questions.length;
125+
const score = Math.round((correct / total) * 100);
126+
return (
127+
<div className="gk-quiz-wrapper">
128+
<div className="gk-quiz-container">
129+
<div className="gk-quiz-header">
130+
<h2 className="gk-quiz-title">Quiz Completed!</h2>
131+
<p className="gk-quiz-subtitle">Your performance summary</p>
132+
</div>
133+
<div className="gk-quiz-result">
134+
<p>Total Questions: {total}</p>
135+
<p>Correct: {correct}</p>
136+
<p>Wrong: {wrong}</p>
137+
<p>Score: {score}%</p>
138+
<button className="gk-quiz-btn" onClick={startQuiz}>Play Again</button>
139+
</div>
140+
</div>
141+
</div>
142+
);
143+
}
144+
145+
const qObj = questions[current];
146+
const pct = Math.round((timeLeft / QUESTION_TIME) * 100);
147+
148+
return (
149+
<div className="gk-quiz-wrapper">
150+
<div className="gk-quiz-container">
151+
<div className="gk-quiz-header">
152+
<h2 className="gk-quiz-title">General Knowledge Quiz</h2>
153+
<p className="gk-quiz-subtitle">Answer the questions and check instantly</p>
154+
</div>
155+
<div className="gk-quiz-body">
156+
<div className="gk-top-row">
157+
<p className="gk-quiz-progress">Question {current + 1} of {questions.length}</p>
158+
<div className={`gk-timer ${timeLeft <= 5 ? "low" : ""}`}>
159+
<div className="gk-timer-bar" style={{ width: pct + "%" }}></div>
160+
<span className="gk-timer-text">{timeLeft}s</span>
161+
</div>
162+
</div>
163+
<h3 className="gk-quiz-question">{qObj.q}</h3>
164+
<div className="gk-quiz-options">
165+
{qObj.options.map((opt, idx) => {
166+
const isCorrect = idx === qObj.ans;
167+
const isChosen = idx === chosenIndex;
168+
let extraClass = "";
169+
if (answered) {
170+
if (isCorrect) extraClass = "gk-correct";
171+
else if (isChosen && !isCorrect) extraClass = "gk-wrong";
172+
}
173+
return (
174+
<button
175+
key={idx}
176+
onClick={() => handleOptionClick(idx)}
177+
className={`gk-quiz-option ${extraClass}`}
178+
disabled={answered}
179+
>
180+
{opt}
181+
</button>
182+
);
183+
})}
184+
</div>
185+
{answered && (
186+
<div className="gk-quiz-feedback">
187+
{chosenIndex === qObj.ans
188+
? <>✅ Correct! The right answer is: {qObj.options[qObj.ans]}</>
189+
: <>❌ Time up / wrong! The correct answer is: {qObj.options[qObj.ans]}</>}
190+
</div>
191+
)}
192+
{answered && (
193+
<button className="gk-quiz-btn" onClick={handleNext}>
194+
{current === questions.length - 1 ? "Show Result" : "Next"}
195+
</button>
196+
)}
197+
</div>
198+
</div>
199+
</div>
200+
);
201+
}

0 commit comments

Comments
 (0)