CODE
Import React, { useReducer, useEffect } from ‘react’;
// — DATA (Vastly Expanded for Longevity) —
const quizDataByDecade = {
“1950s”: [
// Easy
{ quote: “All right, Mr. DeMille, I’m ready for my close-up.”, options: [“All About Eve”, “Sunset Boulevard”, “A Streetcar Named Desire”], correct: 1, actor: “Gloria Swanson”, difficulty: “Easy” },
{ quote: “I coulda been a contender.”, options: [“On the Waterfront”, “Rebel Without a Cause”, “The African Queen”], correct: 0, actor: “Marlon Brando”, difficulty: “Easy” },
{ quote: “Shane. Shane. Come back!”, options: [“High Noon”, “The Searchers”, “Shane”], correct: 2, actor: “Brandon deWilde”, difficulty: “Easy” },
// Medium
{ quote: “Fasten your seatbelts. It’s going to be a bumpy night.”, options: [“The Caine Mutiny”, “Some Like It Hot”, “All About Eve”], correct: 2, actor: “Bette Davis”, difficulty: “Medium” },
{ quote: “Well, nobody’s perfect.”, options: [“Singin’ in the Rain”, “Some Like It Hot”, “The Seven Year Itch”], correct: 1, actor: “Joe E. Brown”, difficulty: “Medium” },
{ quote: “What a glorious feeling, I’m happy again.”, options: [“An American in Paris”, “A Star Is Born”, “Singin’ in the Rain”], correct: 2, actor: “Gene Kelly”, difficulty: “Medium” },
// Hard
{ quote: “You’re tearin’ me apart!”, options: [“East of Eden”, “A Streetcar Named Desire”, “Rebel Without a Cause”], correct: 2, actor: “James Dean”, difficulty: “Hard” },
{ quote: “A boy’s best friend is his mother.”, options: [“Psycho”, “Vertigo”, “North by Northwest”], correct: 0, actor: “Anthony Perkins”, difficulty: “Hard” },
{ quote: “I’ve always depended on the kindness of strangers.”, options: [“The African Queen”, “A Streetcar Named Desire”, “Cat on a Hot Tin Roof”], correct: 1, actor: “Vivien Leigh”, difficulty: “Hard” },
// Expert
{ quote: “Hate is a baggage. Life’s too short to be pissed off all the time.”, options: [“The Defiant Ones”, “12 Angry Men”, “American History X”], correct: 2, actor: “Edward Norton”, difficulty: “Expert” },
{ quote: “I’ll get you, my pretty, and your little dog, too!”, options: [“The Wizard of Oz”, “Snow White and the Seven Dwarfs”, “Cinderella”], correct: 0, actor: “Margaret Hamilton”, difficulty: “Expert” },
{ quote: “Mother of mercy, is this the end of Rico?”, options: [“Key Largo”, “White Heat”, “Little Caesar”], correct: 2, actor: “Edward G. Robinson”, difficulty: “Expert” },
{ quote: “It’s not the men in my life that count, it’s the life in my men.”, options: [“Gilda”, “I’m No Angel”, “Some Like It Hot”], correct: 1, actor: “Mae West”, difficulty: “Expert” }
],
“1960s”: [
// Easy
{ quote: “Bond. James Bond.”, options: [“Goldfinger”, “From Russia with Love”, “Dr. No”], correct: 2, actor: “Sean Connery”, difficulty: “Easy” },
{ quote: “Plastics.”, options: [“Easy Rider”, “The Graduate”, “Bonnie and Clyde”], correct: 1, actor: “Walter Brooke”, difficulty: “Easy” },
{ quote: “A spoonful of sugar helps the medicine go down.”, options: [“The Sound of Music”, “Mary Poppins”, “My Fair Lady”], correct: 1, actor: “Julie Andrews”, difficulty: “Easy” },
// Medium
{ quote: “Gentlemen, you can’t fight in here! This is the War Room!”, options: [“Dr. Strangelove”, “Fail Safe”, “The Bedford Incident”], correct: 0, actor: “Peter Sellers”, difficulty: “Medium” },
{ quote: “Open the pod bay doors, HAL.”, options: [“Planet of the Apes”, “Barbarella”, “2001: A Space Odyssey”], correct: 2, actor: “Keir Dullea”, difficulty: “Medium” },
{ quote: “They’re coming to get you, Barbara.”, options: [“The Haunting”, “Rosemary’s Baby”, “Night of the Living Dead”], correct: 2, actor: “Russell Streiner”, difficulty: “Medium” },
// Hard
{ quote: “What we’ve got here is failure to communicate.”, options: [“Cool Hand Luke”, “The Great Escape”, “The Dirty Dozen”], correct: 0, actor: “Strother Martin”, difficulty: “Hard” },
{ quote: “They call me Mister Tibbs!”, options: [“Guess Who’s Coming to Dinner”, “In the Heat of the Night”, “To Sir, with Love”], correct: 1, actor: “Sidney Poitier”, difficulty: “Hard” },
{ quote: “I’m walking here! I’m walking here!”, options: [“The Producers”, “Midnight Cowboy”, “The Apartment”], correct: 1, actor: “Dustin Hoffman”, difficulty: “Hard” },
// Expert
{ quote: “I’m funny how? I mean, funny like I’m a clown? I amuse you?”, options: [“The Godfather”, “Goodfellas”, “Casino”], correct: 1, actor: “Joe Pesci”, difficulty: “Expert” },
{ quote: “We rob banks.”, options: [“The Wild Bunch”, “Butch Cassidy and the Sundance Kid”, “Bonnie and Clyde”], correct: 2, actor: “Warren Beatty”, difficulty: “Expert” },
{ quote: “Take your stinking paws off me, you damned dirty ape.”, options: [“Planet of the Apes”, “Beneath the Planet of the Apes”, “Conquest of the Planet of the Apes”], correct: 0, actor: “Charlton Heston”, difficulty: “Expert” },
{ quote: “This is my rifle. There are many like it, but this one is mine.”, options: [“The Green Berets”, “Patton”, “Full Metal Jacket”], correct: 2, actor: “R. Lee Ermey”, difficulty: “Expert” }
],
“1970s”: [
// Easy
{ quote: “I’m going to make him an offer he can’t refuse.”, options: [“The French Connection”, “The Godfather”, “Apocalypse Now”], correct: 1, actor: “Marlon Brando”, difficulty: “Easy” },
{ quote: “May the Force be with you.”, options: [“Star Wars”, “Close Encounters of the Third Kind”, “Alien”], correct: 0, actor: “Harrison Ford”, difficulty: “Easy” },
{ quote: “Yo, Adrian!”, options: [“Raging Bull”, “Taxi Driver”, “Rocky”], correct: 2, actor: “Sylvester Stallone”, difficulty: “Easy” },
// Medium
{ quote: “You talkin’ to me?”, options: [“Dog Day Afternoon”, “Network”, “Taxi Driver”], correct: 2, actor: “Robert De Niro”, difficulty: “Medium” },
{ quote: “I love the smell of napalm in the morning.”, options: [“The Deer Hunter”, “Coming Home”, “Apocalypse Now”], correct: 2, actor: “Robert Duvall”, difficulty: “Medium” },
{ quote: “He’s not the Messiah. He’s a very naughty boy!”, options: [“Monty Python and the Holy Grail”, “Life of Brian”, “The Meaning of Life”], correct: 1, actor: “Terry Jones”, difficulty: “Medium” },
// Hard
{ quote: “Forget it, Jake. It’s Chinatown.”, options: [“The Long Goodbye”, “Chinatown”, “The Last Detail”], correct: 1, actor: “Joe Mantell”, difficulty: “Hard” },
{ quote: “I’m as mad as hell, and I’m not going to take this anymore!”, options: [“All the President’s Men”, “Nashville”, “Network”], correct: 2, actor: “Peter Finch”, difficulty: “Hard” },
{ quote: “You’re gonna need a bigger boat.”, options: [“Deliverance”, “The Poseidon Adventure”, “Jaws”], correct: 2, actor: “Roy Scheider”, difficulty: “Hard” },
// Expert
{ quote: “I’m a goddamn marvel of modern science.”, options: [“The Shining”, “Chinatown”, “One Flew Over the Cuckoo’s Nest”], correct: 2, actor: “Jack Nicholson”, difficulty: “Expert” },
{ quote: “Well, what if there is no tomorrow? There wasn’t one today.”, options: [“Harold and Maude”, “Groundhog Day”, “Annie Hall”], correct: 1, actor: “Bill Murray”, difficulty: “Expert” },
{ quote: “The only thing that I do know is that we have to be kind. Please, be kind. Especially when we don’t know what’s going on.”, options: [“Kramer vs. Kramer”, “The Goodbye Girl”, “The Turning Point”], correct: 0, actor: “Dustin Hoffman”, difficulty: “Expert” },
{ quote: “The horror… the horror…”, options: [“The Deer Hunter”, “The French Connection”, “Apocalypse Now”], correct: 2, actor: “Marlon Brando”, difficulty: “Expert” },
{ quote: “I can’t seem to face up to the facts.”, options: [“Serpico”, “Taxi Driver”, “Dog Day Afternoon”], correct: 1, actor: “Robert De Niro”, difficulty: “Expert” },
{ quote: “Viddy well, little brother. Viddy well.”, options: [“Straw Dogs”, “A Clockwork Orange”, “Barry Lyndon”], correct: 1, actor: “Malcolm McDowell”, difficulty: “Expert” },
{ quote: “You ever pick your feet in Poughkeepsie?”, options: [“The French Connection”, “Mean Streets”, “The Conversation”], correct: 0, actor: “Gene Hackman”, difficulty: “Expert” }
],
“1980s”: [
// Easy
{ quote: “I’ll be back.”, options: [“The Terminator”, “Blade Runner”, “RoboCop”], correct: 0, actor: “Arnold Schwarzenegger”, difficulty: “Easy” },
{ quote: “Nobody puts Baby in a corner.”, options: [“Footloose”, “Dirty Dancing”, “Flashdance”], correct: 1, actor: “Patrick Swayze”, difficulty: “Easy”},
{ quote: “E.T. phone home.”, options: [“Close Encounters of the Third Kind”, “E.T. the Extra-Terrestrial”, “Starman”], correct: 1, actor: “Pat Welsh”, difficulty: “Easy” },
// Medium
{ quote: “Go ahead, make my day.”, options: [“Beverly Hills Cop”, “Die Hard”, “Sudden Impact”], correct: 2, actor: “Clint Eastwood”, difficulty: “Medium” },
{ quote: “Snakes. Why’d it have to be snakes?”, options: [“Raiders of the Lost Ark”, “Indiana Jones and the Temple of Doom”, “E.T.”], correct: 0, actor: “Harrison Ford”, difficulty: “Medium”},
{ quote: “I feel the need… the need for speed!”, options: [“Top Gun”, “Ferris Bueller’s Day Off”, “Back to the Future”], correct: 0, actor: “Tom Cruise”, difficulty: “Medium” },
// Hard
{ quote: “All those moments will be lost in time, like tears in rain.”, options: [“Aliens”, “Blade Runner”, “The Thing”], correct: 1, actor: “Rutger Hauer”, difficulty: “Hard” },
{ quote: “Hello. My name is Inigo Montoya. You killed my father. Prepare to die.”, options: [“Labyrinth”, “The Princess Bride”, “Willow”], correct: 1, actor: “Mandy Patinkin”, difficulty: “Hard” },
{ quote: “Yippee-ki-yay, motherf—er.”, options: [“Lethal Weapon”, “Predator”, “Die Hard”], correct: 2, actor: “Bruce Willis”, difficulty: “Hard” },
// Expert
{ quote: “Heineken? F— that s—! Pabst Blue Ribbon!”, options: [“Raising Arizona”, “Repo Man”, “Blue Velvet”], correct: 2, actor: “Dennis Hopper”, difficulty: “Expert” },
{ quote: “The life of a repo man is always intense.”, options: [“Paris, Texas”, “Repo Man”, “Alien”], correct: 1, actor: “Harry Dean Stanton”, difficulty: “Expert” },
{ quote: “Son, you got a panty on your head.”, options: [“Raising Arizona”, “Fast Times at Ridgemont High”, “Ferris Bueller’s Day Off”], correct: 0, actor: “Nicolas Cage”, difficulty: “Expert” },
{ quote: “I have come here to chew bubblegum and kick ass… and I’m all out of bubblegum.”, options: [“Escape from New York”, “They Live”, “RoboCop”], correct: 1, actor: “Roddy Piper”, difficulty: “Expert” },
{ quote: “It’s all in the reflexes.”, options: [“The Goonies”, “Gremlins”, “Big Trouble in Little China”], correct: 2, actor: “Kurt Russell”, difficulty: “Expert” },
{ quote: “These go to eleven.”, options: [“This Is Spinal Tap”, “Rock ‘n’ Roll High School”, “The Blues Brothers”], correct: 0, actor: “Christopher Guest”, difficulty: “Expert” },
{ quote: “F— me gently with a chainsaw. Do I look like Mother Teresa?”, options: [“Pretty in Pink”, “The Breakfast Club”, “Heathers”], correct: 2, actor: “Shannen Doherty”, difficulty: “Expert” }
],
“1990s”: [
// Easy
{ quote: “Show me the money!”, options: [“Forrest Gump”, “Jerry Maguire”, “Pulp Fiction”], correct: 1, actor: “Cuba Gooding Jr.”, difficulty: “Easy”},
{ quote: “To infinity and beyond!”, options: [“The Lion King”, “Aladdin”, “Toy Story”], correct: 2, actor: “Tim Allen”, difficulty: “Easy” },
{ quote: “Life is like a box of chocolates. You never know what you’re gonna get.”, options: [“Forrest Gump”, “The Green Mile”, “Saving Private Ryan”], correct: 0, actor: “Tom Hanks”, difficulty: “Easy” },
// Medium
{ quote: “You can’t handle the truth!”, options: [“A Few Good Men”, “Goodfellas”, “The Usual Suspects”], correct: 0, actor: “Jack Nicholson”, difficulty: “Medium” },
{ quote: “The first rule of Fight Club is: You do not talk about Fight Club.”, options: [“Seven”, “The Matrix”, “Fight Club”], correct: 2, actor: “Brad Pitt”, difficulty: “Medium”},
{ quote: “I’m the king of the world!”, options: [“Braveheart”, “Titanic”, “The Mask of Zorro”], correct: 1, actor: “Leonardo DiCaprio”, difficulty: “Medium” },
// Hard
{ quote: “I’m your huckleberry.”, options: [“Unforgiven”, “Tombstone”, “Dances with Wolves”], correct: 1, actor: “Val Kilmer”, difficulty: “Hard” },
{ quote: “I see dead people.”, options: [“The Sixth Sense”, “The Silence of the Lambs”, “Seven”], correct: 0, actor: “Haley Joel Osment”, difficulty: “Hard” },
{ quote: “It rubs the lotion on its skin, or else it gets the hose again.”, options: [“Misery”, “The Silence of the Lambs”, “Cape Fear”], correct: 1, actor: “Ted Levine”, difficulty: “Hard” },
// Expert
{ quote: “I’m not even supposed to be here today!”, options: [“Mallrats”, “Clerks”, “Chasing Amy”], correct: 1, actor: “Brian O’Halloran”, difficulty: “Expert” },
{ quote: “You know… for kids!”, options: [“The Shawshank Redemption”, “Jacob’s Ladder”, “The Hudsucker Proxy”], correct: 2, actor: “Tim Robbins”, difficulty: “Expert” },
{ quote: “I’m the one who’s got to die when it’s time for me to die, so let me live my life the way I want to.”, options: [“My Own Private Idaho”, “Point Break”, “Drugstore Cowboy”], correct: 0, actor: “River Phoenix”, difficulty: “Expert” },
{ quote: “What’s in the box?”, options: [“The Silence of the Lambs”, “Seven”, “The Game”], correct: 1, actor: “Brad Pitt”, difficulty: “Expert” },
{ quote: “The Dude abides.”, options: [“Fargo”, “Pulp Fiction”, “The Big Lebowski”], correct: 2, actor: “Jeff Bridges”, difficulty: “Expert” },
{ quote: “I’ll show you the life of the mind!”, options: [“Miller’s Crossing”, “The Big Lebowski”, “Barton Fink”], correct: 2, actor: “John Goodman”, difficulty: “Expert” },
{ quote: “Coffee’s for closers only.”, options: [“Boiler Room”, “Glengarry Glen Ross”, “Wall Street”], correct: 1, actor: “Alec Baldwin”, difficulty: “Expert” }
],
“2000s”: [
// Easy
{ quote: “My precious.”, options: [“Harry Potter”, “The Lord of the Rings”, “Pirates of the Caribbean”], correct: 1, actor: “Andy Serkis”, difficulty: “Easy” },
{ quote: “This is Sparta!”, options: [“Gladiator”, “Troy”, “300”], correct: 2, actor: “Gerard Butler”, difficulty: “Easy”},
{ quote: “I live my life a quarter mile at a time.”, options: [“Gone in 60 Seconds”, “The Fast and the Furious”, “Torque”], correct: 1, actor: “Vin Diesel”, difficulty: “Easy” },
// Medium
{ quote: “Why so serious?”, options: [“The Dark Knight”, “No Country for Old Men”, “There Will Be Blood”], correct: 0, actor: “Heath Ledger”, difficulty: “Medium” },
{ quote: “I’m just one stomach flu away from my goal weight.”, options: [“Mean Girls”, “The Devil Wears Prada”, “Bridget Jones’s Diary”], correct: 1, actor: “Emily Blunt”, difficulty: “Medium” },
{ quote: “You shall not pass!”, options: [“The Lord of the Rings: The Fellowship of the Ring”, “Harry Potter and the Chamber of Secrets”, “The Chronicles of Narnia”], correct: 0, actor: “Ian McKellen”, difficulty: “Medium” },
// Hard
{ quote: “I drink your milkshake! I drink it up!”, options: [“The Departed”, “There Will Be Blood”, “No Country for Old Men”], correct: 1, actor: “Daniel Day-Lewis”, difficulty: “Hard” },
{ quote: “Are you not entertained?”, options: [“300”, “Troy”, “Gladiator”], correct: 2, actor: “Russell Crowe”, difficulty: “Hard” },
{ quote: “I’m in a glass case of emotion!”, options: [“Zoolander”, “Old School”, “Anchorman: The Legend of Ron Burgundy”], correct: 2, actor: “Will Ferrell”, difficulty: “Hard” },
// Expert
{ quote: “This is the girl.”, options: [“Lost in Translation”, “Mulholland Drive”, “Eternal Sunshine of the Spotless Mind”], correct: 1, actor: “Naomi Watts”, difficulty: “Expert” },
{ quote: “I know what to do with this play. I have an idea. I think… I think… I think… I’m dying.”, options: [“Capote”, “Synecdoche, New York”, “The Master”], correct: 1, actor: “Philip Seymour Hoffman”, difficulty: “Expert” },
{ quote: “There are no two words in the English language more harmful than ‘good job’.”, options: [“The Social Network”, “Whiplash”, “Birdman”], correct: 1, actor: “J.K. Simmons”, difficulty: “Expert” },
{ quote: “You’re an inanimate f—ing object!”, options: [“Hot Fuzz”, “Shaun of the Dead”, “In Bruges”], correct: 2, actor: “Ralph Fiennes”, difficulty: “Expert” },
{ quote: “I have a competition in me. I want no one else to succeed.”, options: [“The Aviator”, “There Will Be Blood”, “Gangs of New York”], correct: 1, actor: “Daniel Day-Lewis”, difficulty: “Expert” },
{ quote: “We all need mirrors to remind ourselves who we are.”, options: [“Memento”, “The Prestige”, “Insomnia”], correct: 0, actor: “Guy Pearce”, difficulty: “Expert” },
{ quote: “Why are you wearing that stupid bunny suit?”, options: [“Donnie Darko”, “The Jacket”, “Source Code”], correct: 0, actor: “Mary McDonnell”, difficulty: “Expert” }
],
“2010s”: [
// Easy
{ quote: “I volunteer as tribute!”, options: [“Divergent”, “The Maze Runner”, “The Hunger Games”], correct: 2, actor: “Jennifer Lawrence”, difficulty: “Easy” },
{ quote: “Dread it. Run from it. Destiny still arrives.”, options: [“The Dark Knight Rises”, “Avengers: Infinity War”, “Man of Steel”], correct: 1, actor: “Josh Brolin”, difficulty: “Easy” },
{ quote: “I have been falling for 30 minutes!”, options: [“Guardians of the Galaxy Vol. 2”, “Doctor Strange”, “Thor: Ragnarok”], correct: 2, actor: “Tom Hiddleston”, difficulty: “Easy” },
// Medium
{ quote: “I am Groot.”, options: [“Guardians of the Galaxy”, “The Avengers”, “Thor”], correct: 0, actor: “Vin Diesel”, difficulty: “Medium” },
{ quote: “Get out!”, options: [“A Quiet Place”, “It”, “Get Out”], correct: 2, actor: “Daniel Kaluuya”, difficulty: “Medium” },
{ quote: “That’s my secret, Cap: I’m always angry.”, options: [“Iron Man 3”, “Captain America: Civil War”, “The Avengers”], correct: 2, actor: “Mark Ruffalo”, difficulty: “Medium” },
// Hard
{ quote: “There’s been a murder… a murder in Savannah.”, options: [“Gone Girl”, “Knives Out”, “Prisoners”], correct: 1, actor: “Daniel Craig”, difficulty: “Hard” },
{ quote: “I’m the captain now.”, options: [“Zero Dark Thirty”, “Captain Phillips”, “A Hijacking”], correct: 1, actor: “Barkhad Abdi”, difficulty: “Hard” },
{ quote: “If you’re a racist, I’ll attack you with the North.”, options: [“Django Unchained”, “Lincoln”, “12 Years a Slave”], correct: 1, actor: “Daniel Day-Lewis”, difficulty: “Hard” },
// Expert
{ quote: “Wouldst thou like to live deliciously?”, options: [“Hereditary”, “The Lighthouse”, “The Witch”], correct: 2, actor: “Wahab Chaudhry”, difficulty: “Expert” },
{ quote: “Is my daughter in there?”, options: [“Nocturnal Animals”, “Arrival”, “Her”], correct: 1, actor: “Amy Adams”, difficulty: “Expert” },
{ quote: “You don’t get to 500 million friends without making a few enemies.”, options: [“Steve Jobs”, “The Social Network”, “Ex Machina”], correct: 1, actor: “Jesse Eisenberg”, difficulty: “Expert” },
{ quote: “I’m speaking in English, you’re speaking in English, but we’re not speaking the same language.”, options: [“Hell or High Water”, “Wind River”, “Sicario”], correct: 2, actor: “Benicio Del Toro”, difficulty: “Expert” },
{ quote: “One of the things I do is, I do my own stunts.”, options: [“Baby Driver”, “Drive”, “Nightcrawler”], correct: 1, actor: “Ryan Gosling”, difficulty: “Expert” },
{ quote: “If it was never new, and it never gets old, then it’s a folk song.”, options: [“A Star Is Born”, “Once”, “Inside Llewyn Davis”], correct: 2, actor: “Oscar Isaac”, difficulty: “Expert” },
{ quote: “The tea is going out. The interruption is staying right here with me.”, options: [“The Favourite”, “Phantom Thread”, “The Shape of Water”], correct: 1, actor: “Daniel Day-Lewis”, difficulty: “Expert” }
],
“2020s”: [
// Easy
{ quote: “I am… inevitable.”, options: [“Avengers: Endgame”, “Zack Snyder’s Justice League”, “Spider-Man: No Way Home”], correct: 0, actor: “Josh Brolin”, difficulty: “Easy” },
{ quote: “My desert. My Arrakis. My Dune.”, options: [“Dune: Part Two”, “Dune”, “Blade Runner 2049”], correct: 1, actor: “Timothée Chalamet”, difficulty: “Easy” },
{ quote: “I’m vengeance.”, options: [“The Joker”, “The Batman”, “Birds of Prey”], correct: 1, actor: “Robert Pattinson”, difficulty: “Easy” },
// Medium
{ quote: “I’m just Ken.”, options: [“La La Land”, “The Nice Guys”, “Barbie”], correct: 2, actor: “Ryan Gosling”, difficulty: “Medium” },
{ quote: “I can do this all day.”, options: [“Captain America: The First Avenger”, “Avengers: Endgame”, “The Avengers”], correct: 1, actor: “Chris Evans”, difficulty: “Medium” },
{ quote: “So, we’re not saying ‘no,’ we’re saying, ‘not right now.'”, options: [“No Hard Feelings”, “Past Lives”, “Theater Camp”], correct: 2, actor: “Molly Gordon”, difficulty: “Medium” },
// Hard
{ quote: “In another life, I would have really liked just doing laundry and taxes with you.”, options: [“Past Lives”, “Everything Everywhere All at Once”, “Aftersun”], correct: 1, actor: “Michelle Yeoh”, difficulty: “Hard” },
{ quote: “They will not fear it until they understand it. And they will not understand it until they have used it.”, options: [“Tenet”, “Dune”, “Oppenheimer”], correct: 2, actor: “Cillian Murphy”, difficulty: “Hard” },
{ quote: “I’m a star! I’m a star, I’m a star, I’m a star.”, options: [“X”, “Pearl”, “Infinity Pool”], correct: 1, actor: “Mia Goth”, difficulty: “Hard” },
// Expert
{ quote: “This is a family. We’re a family.”, options: [“The Fabelmans”, “CODA”, “Parasite”], correct: 2, actor: “Song Kang-ho”, difficulty: “Expert” },
{ quote: “I have a thing that I do with my… with my… with my students.”, options: [“Tár”, “The Whale”, “The Power of the Dog”], correct: 0, actor: “Cate Blanchett”, difficulty: “Expert” },
{ quote: “I don’t know who you are, but you’re in my seat.”, options: [“John Wick: Chapter 4”, “Nobody”, “Bullet Train”], correct: 1, actor: “Bob Odenkirk”, difficulty: “Expert” },
{ quote: “We live in a twilight world. And there are no friends at dusk.”, options: [“The Gray Man”, “Tenet”, “No Time to Die”], correct: 1, actor: “John David Washington”, difficulty: “Expert” }
]
};
const decades = Object.keys(quizDataByDecade).sort();
const difficulties = [“Easy”, “Medium”, “Hard”, “Expert”];
const TIME_LIMIT = 20; // Time limit in seconds
// — STATE MANAGEMENT (useReducer) —
const initialState = {
gameState: ‘selecting_decade’, // ‘selecting_decade’, ‘selecting_difficulty’, ‘playing’, ‘finished’, ‘game_won’
totalScore: 0,
roundScore: 0,
statueCount: 0,
timer: TIME_LIMIT,
selectedDecade: null,
selectedDifficulty: null,
currentQuestionIndex: 0,
questions: [],
selectedAnswer: null,
bonusAnswer: ”,
showBonus: false,
feedback: ”,
askedQuotes: [],
};
function quizReducer(state, action) {
let newStatueCount;
switch (action.type) {
case ‘SELECT_DECADE’:
return { …state, gameState: ‘selecting_difficulty’, selectedDecade: action.payload };
case ‘SELECT_DIFFICULTY’: {
const questionsForDecade = quizDataByDecade[state.selectedDecade] || [];
const allQuestionsForCategory = questionsForDecade.filter(q => q.difficulty === action.payload);
const availableQuestions = allQuestionsForCategory.filter(q => !state.askedQuotes.includes(q.quote));
const shuffledQuestions = availableQuestions.sort(() => Math.random() – 0.5);
return { …state, gameState: ‘playing’, selectedDifficulty: action.payload, questions: shuffledQuestions, currentQuestionIndex: 0, roundScore: 0, timer: TIME_LIMIT };
}
case ‘ANSWER_QUESTION’: {
const { optionIndex, isCorrect, fromTimeout = false } = action.payload;
const newRoundScore = isCorrect ? state.roundScore + 1 : state.roundScore;
newStatueCount = isCorrect ? state.statueCount + 1 : Math.max(0, state.statueCount – 1);
let feedback;
if (fromTimeout) {
feedback = `Time’s Up! -1 Statue. The correct answer was “${state.questions[state.currentQuestionIndex].options[state.questions[state.currentQuestionIndex].correct]}”.`;
} else {
feedback = isCorrect ? ‘Correct! +1 Point & +1 Statue!’ : `Wrong! -1 Statue. The correct answer was “${state.questions[state.currentQuestionIndex].options[state.questions[state.currentQuestionIndex].correct]}”.`;
}
if (newStatueCount >= 10) {
return { …state, statueCount: newStatueCount, roundScore: newRoundScore, gameState: ‘game_won’ };
}
return { …state, selectedAnswer: optionIndex, roundScore: newRoundScore, feedback, showBonus: true, statueCount: newStatueCount };
}
case ‘ANSWER_BONUS’: {
const { bonusAnswer, isCorrect } = action.payload;
const newRoundScore = isCorrect ? state.roundScore + 1 : state.roundScore;
newStatueCount = isCorrect ? state.statueCount + 1 : Math.max(0, state.statueCount – 1);
const feedback = state.feedback + (isCorrect ? ‘ | Bonus Correct! +1 Statue!’ : ` | Bonus Wrong! -1 Statue. It was ${state.questions[state.currentQuestionIndex].actor}.`);
if (newStatueCount >= 10) {
return { …state, statueCount: newStatueCount, roundScore: newRoundScore, gameState: ‘game_won’ };
}
return { …state, bonusAnswer, roundScore: newRoundScore, feedback, statueCount: newStatueCount };
}
case ‘NEXT_QUESTION’: {
const isLastQuestion = state.currentQuestionIndex === state.questions.length – 1;
if (isLastQuestion) {
const justAskedQuotes = state.questions.map(q => q.quote);
return {
…state,
gameState: ‘finished’,
totalScore: state.totalScore + state.roundScore,
askedQuotes: […state.askedQuotes, …justAskedQuotes]
};
}
return { …state, currentQuestionIndex: state.currentQuestionIndex + 1, selectedAnswer: null, showBonus: false, bonusAnswer: ”, feedback: ”, timer: TIME_LIMIT };
}
case ‘TICK’:
return { …state, timer: state.timer – 1 };
case ‘PLAY_AGAIN’:
return { …initialState, totalScore: state.totalScore, askedQuotes: state.askedQuotes, statueCount: state.statueCount };
case ‘RESET_GAME’:
return initialState;
default:
throw new Error(`Unhandled action type: ${action.type}`);
}
}
// — REUSABLE & FOCUSED COMPONENTS —
const GoldStatue = () => (
<svg xmlns=”http://www.w3.org/2000/svg” className=”w-8 h-8 text-yellow-400 drop-shadow-lg” viewBox=”0 0 24 24″ fill=”currentColor”>
<path d=”M12 2C11.45 2 11 2.45 11 3V4.59C8.28 5.11 6 7.55 6 10.5V15H5C4.45 15 4 15.45 4 16V17H6.09C6.58 19.22 8.57 21 11 21H13C15.43 21 17.42 19.22 17.91 17H20V16C20 15.45 19.55 15 19 15H18V10.5C18 7.55 15.72 5.11 13 4.59V3C13 2.45 12.55 2 12 2M9 15H15V10.5C15 8.57 13.43 7 11.5 7C9.57 7 8 8.57 8 10.5V15H9Z” />
</svg>
);
const StatueCounter = ({ count }) => (
<div className=”absolute top-4 left-4 flex flex-wrap gap-1 p-2 bg-black/20 rounded-lg”>
{Array.from({ length: count }).map((_, i) => <GoldStatue key={i} />)}
</div>
);
const Scoreboard = ({ score }) => (
<div className=”absolute top-4 right-4 bg-white/20 backdrop-blur-sm text-white font-bold py-2 px-4 rounded-lg shadow-md”>
Total Score: {score}
</div>
);
const SelectorScreen = ({ title, items, onSelectItem, colorMap }) => (
<div className=”text-center”>
<h1 className=”text-5xl font-bold text-white mb-4″>Mark’s Movie Quote Quiz Game</h1>
<p className=”text-xl text-yellow-300 mb-8″>{title}</p>
<div className=”grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-8 gap-4″>
{items.map(item => (
<button
key={item}
onClick={() => onSelectItem(item)}
className={`${colorMap[item] || colorMap.default} text-white font-bold py-4 px-6 rounded-lg shadow-lg transform hover:scale-105 transition-all duration-200 text-xl`}
>
{item}
</button>
))}
</div>
</div>
);
const TimerBar = ({ time, totalTime }) => {
const percentage = (time / totalTime) * 100;
return (
<div className=”w-full bg-gray-600 rounded-full h-2.5 mb-4″>
<div
className=”bg-yellow-400 h-2.5 rounded-full transition-all duration-1000 linear”
style={{ width: `${percentage}%` }}
></div>
</div>
);
};
const QuestionScreen = ({ state, dispatch }) => {
const { questions, currentQuestionIndex, selectedAnswer, showBonus, feedback, timer } = state;
const currentQuestion = questions[currentQuestionIndex];
useEffect(() => {
if (selectedAnswer !== null) return; // Stop timer if answered
if (timer > 0) {
const interval = setInterval(() => {
dispatch({ type: ‘TICK’ });
}, 1000);
return () => clearInterval(interval);
} else {
// Time is up, dispatch incorrect answer
dispatch({ type: ‘ANSWER_QUESTION’, payload: { optionIndex: null, isCorrect: false, fromTimeout: true } });
}
}, [timer, selectedAnswer, dispatch]);
const handleAnswerSelect = (optionIndex) => {
dispatch({ type: ‘ANSWER_QUESTION’, payload: { optionIndex, isCorrect: optionIndex === currentQuestion.correct } });
};
const handleBonusSubmit = (e) => {
e.preventDefault();
const answer = e.target.elements.bonus.value;
if (!answer.trim()) return;
dispatch({ type: ‘ANSWER_BONUS’, payload: { bonusAnswer: answer, isCorrect: answer.trim().toLowerCase() === currentQuestion.actor.toLowerCase() } });
e.target.elements.bonus.disabled = true;
e.target.elements.submit.disabled = true;
};
if (!currentQuestion) {
return (
<div className=”text-center bg-gray-800/80 p-8 rounded-xl”>
<h2 className=”text-2xl text-yellow-400 mb-4″>You’ve answered all the questions for this category!</h2>
<p className=”text-white mb-6″>Try another category or reset the game to play these again.</p>
<button onClick={() => dispatch({ type: ‘PLAY_AGAIN’ })} className=”bg-blue-500 text-white font-bold py-3 px-8 rounded-lg”>Try Another</button>
</div>
);
}
return (
<div className=”bg-gray-800/70 backdrop-blur-md p-8 rounded-2xl shadow-2xl”>
<TimerBar time={timer} totalTime={TIME_LIMIT} />
<div className=”mb-6 text-center”>
<div className=”flex justify-between items-center text-lg text-yellow-300 mb-2″>
<span>Question {currentQuestionIndex + 1} of {questions.length}</span>
<span className=”font-mono text-2xl”>{timer}s</span>
</div>
<p className=”text-3xl italic”>”{currentQuestion.quote}”</p>
</div>
<div className=”grid grid-cols-1 gap-4 mb-6″>
{currentQuestion.options.map((option, index) => {
const isSelected = selectedAnswer === index;
const isCorrect = currentQuestion.correct === index;
let buttonClass = ‘bg-blue-600 hover:bg-blue-500’;
if (selectedAnswer !== null) {
buttonClass = isCorrect ? ‘bg-green-600’ : (isSelected ? ‘bg-red-600’ : ‘bg-gray-600 opacity-70’);
}
return <button key={index} onClick={() => handleAnswerSelect(index)} disabled={selectedAnswer !== null} className={`w-full text-left p-4 rounded-lg text-lg font-semibold transition-all duration-200 transform ${selectedAnswer === null ? ‘hover:scale-105’ : ”} ${buttonClass}`}>{option}</button>;
})}
</div>
{feedback && <p className=”text-center text-yellow-400 font-semibold my-4 h-6″>{feedback}</p>}
{showBonus && (
<div className=”mt-6 animate-fade-in”>
<form onSubmit={handleBonusSubmit}>
<label htmlFor=”bonus” className=”block text-lg font-semibold mb-2 text-center”>For one bonus point, name the actor:</label>
<div className=”flex gap-2″>
<input id=”bonus” name=”bonus” type=”text” className=”w-full bg-gray-700 text-white p-3 rounded-lg border-2 border-gray-600 focus:border-yellow-400 focus:outline-none” placeholder=”e.g., Val Kilmer” />
<button type=”submit” name=”submit” className=”bg-yellow-500 text-gray-900 font-bold py-3 px-5 rounded-lg hover:bg-yellow-400 disabled:bg-gray-500 disabled:cursor-not-allowed”>Submit</button>
</div>
</form>
</div>
)}
{selectedAnswer !== null && (
<div className=”text-center mt-8″><button onClick={() => dispatch({ type: ‘NEXT_QUESTION’ })} className=”bg-purple-600 text-white font-bold py-3 px-8 rounded-lg shadow-lg hover:bg-purple-500 transform hover:scale-105 transition-all duration-200 text-lg animate-pulse”>Next</button></div>
)}
</div>
);
};
const EndScreen = ({ state, dispatch }) => (
<div className=”text-center bg-gray-800/80 backdrop-blur-md p-8 rounded-2xl shadow-2xl”>
<h2 className=”text-4xl font-bold text-white mb-2″>Round Complete!</h2>
<p className=”text-2xl text-yellow-400 mb-2″>Round Score: {state.roundScore} / {state.questions.length * 2}</p>
<p className=”text-3xl text-green-400 mb-6″>New Total Score: {state.totalScore}</p>
<div className=”flex justify-center gap-4″>
<button onClick={() => dispatch({ type: ‘PLAY_AGAIN’ })} className=”bg-blue-500 text-white font-bold py-3 px-8 rounded-lg shadow-lg hover:bg-blue-400 transform hover:scale-105 transition-all duration-200 text-lg”>Play Another Round</button>
<button onClick={() => dispatch({ type: ‘RESET_GAME’ })} className=”bg-red-600 text-white font-bold py-3 px-8 rounded-lg shadow-lg hover:bg-red-500 transform hover:scale-105 transition-all duration-200 text-lg”>Reset Game</button>
</div>
</div>
);
const WinScreen = ({ dispatch }) => (
<div className=”text-center bg-gradient-to-br from-yellow-400 to-orange-500 p-8 rounded-2xl shadow-2xl”>
<h2 className=”text-6xl font-bold text-white mb-4 drop-shadow-lg”>YOU WON!</h2>
<p className=”text-2xl text-white mb-6″>You’ve collected 10 gold statues! A true movie master.</p>
<div className=”flex justify-center”>
<button
onClick={() => dispatch({ type: ‘RESET_GAME’ })}
className=”bg-white text-yellow-600 font-bold py-3 px-8 rounded-lg shadow-lg hover:bg-gray-100 transform hover:scale-105 transition-all duration-200 text-lg”
>
Play Again From Start
</button>
</div>
</div>
);
// — MAIN APP COMPONENT —
export default function App() {
const [state, dispatch] = useReducer(quizReducer, initialState);
const renderContent = () => {
switch (state.gameState) {
case ‘selecting_decade’:
return <SelectorScreen title=”Select a Decade” items={decades} onSelectItem={(decade) => dispatch({ type: ‘SELECT_DECADE’, payload: decade })} colorMap={{ default: ‘bg-yellow-500 hover:bg-yellow-400’ }} />;
case ‘selecting_difficulty’:
return <SelectorScreen title={`Decade: ${state.selectedDecade} | Select Difficulty`} items={difficulties} onSelectItem={(difficulty) => dispatch({ type: ‘SELECT_DIFFICULTY’, payload: difficulty })} colorMap={{ “Easy”: “bg-green-500 hover:bg-green-400”, “Medium”: “bg-blue-500 hover:bg-blue-400”, “Hard”: “bg-red-500 hover:bg-red-400”, “Expert”: “bg-purple-600 hover:bg-purple-500” }} />;
case ‘playing’:
return <QuestionScreen state={state} dispatch={dispatch} />;
case ‘finished’:
return <EndScreen state={state} dispatch={dispatch} />;
case ‘game_won’:
return <WinScreen dispatch={dispatch} />;
default:
return null;
}
};
return (
<div className=”min-h-screen bg-gray-900 text-white font-sans flex items-center justify-center p-4 relative overflow-hidden”>
<div className=”absolute top-0 left-0 w-full h-full bg-cover bg-center opacity-20″ style={{backgroundImage: “url(‘https://www.transparenttextures.com/patterns/stardust.png’)”}}></div>
<div className=”absolute -bottom-1/4 -left-1/4 w-1/2 h-1/2 bg-blue-500/20 rounded-full filter blur-3xl”></div>
<div className=”absolute -top-1/4 -right-1/4 w-1/2 h-1/2 bg-yellow-500/20 rounded-full filter blur-3xl”></div>
<Scoreboard score={state.totalScore} />
<StatueCounter count={state.statueCount} />
<div className=”z-10 w-full max-w-3xl mx-auto”>
{renderContent()}
</div>
<style>{`@keyframes fade-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .animate-fade-in { animation: fade-in 0.5s ease-out forwards; }`}</style>
</div>
);
}