DEV Community

Den
Den

Posted on

Building a Spooky 🎃 Halloween Quiz with Gemma4: Fun Terminal Trivia

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

What I Built

🎃 Spooky Halloween CLI Quiz Engine — A zero-dependency, standard-library Python command-line quiz application with a Halloween-themed trivia pack exploring ancient Celtic roots, folklore, and spooky pop culture.

The project interprets "spooky" through cultural history rather than jump scares: 12 meticulously researched questions trace Halloween's lineage from Samhain (the Celtic festival marking the thinning veil between worlds) through medieval souling traditions, Irish turnip lanterns, Victorian candy corn marketing, Bram Stoker's Transylvania, Mexican Día de los Muertos contrasts, and Scottish hearth divination rituals. Each question includes an educational explanation — turning a quiz into a micro-history lesson.

Inspiration: I wanted to build something that felt seasonal but intellectually satisfying — a tool that makes you learn while you play. The Halloween theme gave me a perfect excuse to dive into folklore archives and surface lesser-known facts (like candy corn's original "Chicken Feed" branding or the hazelnut marriage-divination custom).

Demo

The application runs entirely in your terminal — no web deployment needed. Here's what the experience looks like:

Main Menu & Quiz Selection

 ╔═══════════════════════════════════════════════════════════════════╗
 ║   ⚡  PYTHON CLI QUIZ ENGINE  🎮  🎃  🧠  🏆                      ║
 ║   Standard-Library Terminal Trivia with Persistent Leaderboards   ║
 ╚═══════════════════════════════════════════════════════════════════╝

Available Quizzes Found: 2

MAIN NAVIGATION:
  [1] 🎮 Play a Quiz
  [2] 🏆 View Persistent Leaderboards
  [3] 🔍 Validate & Diagnose Quiz Files
  [4] 📝 How to Add Custom Quizzes (JSON Schema Guide)
  [5] 🚪 Exit
Enter fullscreen mode Exit fullscreen mode

In-Game Question Card (with streak multiplier & live scoring)

Question 3/12 │ Score: 300 │ 🔥 Streak: 3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

3. What medieval practice involved poor citizens visiting houses to offer
   prayers for the dead in exchange for small pastries called 'soul cakes'?

   [A] Wassailing
   [B] Souling
   [C] Mumming
   [D] Barrowing

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Your answer ([A]-[D], [Q] to quit): B

✅ CORRECT! 🎉 (+150 points)
🔥🔥 ON FIRE! 3 in a row! (+50 streak bonus!)

💡 Explanation & Context:
   'Souling' was a medieval All Hallows' Eve and All Souls' Day custom
   that evolved into modern trick-or-treating.
Enter fullscreen mode Exit fullscreen mode

Game Over Screen with Rank Badge & Auto-Saved Leaderboard

╔═══════════════════════════════════════════════════════════════════════════╗
║                        🏁 QUIZ COMPLETED! 🏁                              ║
╚═══════════════════════════════════════════════════════════════════════════╝

👤 Player:         PumpkinKing
📚 Quiz:           🎃 Spooky Halloween & Ancient Folklore Trivia
🎯 Final Score:    1,300 points
✅ Correct:        12 / 12 (100.0%)
🔥 Longest Streak: 12 questions
⏱️ Time Taken:     2m 15s
🎖️ Rank Awarded:   🏆 Grandmaster Legend (Flawless Victory!)

💾 Your high score has been saved to 'high_scores.txt'!

╔═══════════════════════════════════════════════════════════════════════════╗
║                     🏆 Updated Leaderboard for 🎃 Spooky H... 🏆                    ║
╚═══════════════════════════════════════════════════════════════════════════╝

📌 Topic / Quiz ID: HALLOWEEN
───────────────────────────────────────────────────────────────────────────────
Rank   Player                 Score      Accuracy    Streak    Date
───────────────────────────────────────────────────────────────────────────────
🥇     PumpkinKing           1,300      100.0%      🔥 12     2026-10-31 02:05:10
───────────────────────────────────────────────────────────────────────────────
Enter fullscreen mode Exit fullscreen mode

Code

The entire application lives in a single quiz.py (~890 lines) with zero external dependencies — just the Python standard library. The Halloween quiz content is in quizzes/halloween.json.

Key architectural highlights:

Component Purpose
QuizValidator Discovers, parses, and validates JSON quiz files with graceful error reporting (syntax errors, schema violations, out-of-bounds answers) — never crashes on bad files
QuizGame Interactive game loop with streak multipliers (25pts × consecutive correct), instant feedback, educational explanations, and rank badges
LeaderboardManager Persistent pipe-delimited text database (high_scores.txt) with formatted tables, medals, and per-quiz filtering
QuizCLIApp Main controller with interactive menu, direct-launch CLI flags (--quiz, --leaderboard, --validate), and schema guide

Extensibility: Drop any valid JSON file into quizzes/ and it auto-discovers. The schema supports flexible answer formats (0-index, 1-index, letter, or literal text).


How I Built It

Open-weight model used: gemma-4-31b-it (via Ollama local inference)

Development workflow:

  1. Content generation: Prompted Gemma to research and author 12 Halloween trivia questions with historically accurate explanations, multiple-choice options, and verified answers. The model's knowledge of folklore, etymology, and cultural history was essential for surfacing obscure details (e.g., the hazelnut divination custom, candy corn's "Chicken Feed" origin).
  2. Code scaffolding: Used Gemma to draft the initial QuizValidator schema logic — handling the messy reality of JSON answer formats (int vs string vs letter) with comprehensive edge-case coverage.
  3. Refinement loop: Iterated on ANSI color handling (cross-platform Windows VT100 enablement), streak-scoring math, and leaderboard persistence through conversational debugging with the model.
  4. Final polish: Manual review for terminal UX — progress bars, color-blind safe palettes, graceful NO_COLOR/TERM fallbacks, and keyboard-interrupt hygiene.

Why local inference mattered: Running Gemma locally via Ollama meant zero API costs, no rate limits, full privacy for proprietary logic, and the ability to iterate rapidly on prompts without network latency. The 31B parameter size struck the sweet spot for complex reasoning (schema validation logic, historical fact-checking) while fitting in 24GB VRAM.


Why Does Open Innovation Matter?

This project exists because of open innovation at three levels:

  1. Open-weight model (Gemma): A closed API would have introduced per-token costs, latency, and data privacy concerns for iterative development. With Gemma running locally, I could prompt 50+ times to refine quiz content and validation logic without a bill or usage cap. The model weights being downloadable meant I owned the inference stack entirely.

  2. Open-source ecosystem (Python stdlib + Ollama): Zero pip install required. The app runs on any Python 3.10+ installation. Ollama's open-source model runner made local Gemma inference a single ollama pull gemma4:31b away — no Docker, no cloud GPU, no vendor lock-in.

  3. Open knowledge (folklore research): The quiz content draws from centuries of public-domain cultural history — Celtic festivals, medieval customs, literary history. An LLM trained on open corpora could synthesize this; a closed model trained on proprietary data might hallucinate or refuse "niche" folklore queries.

What closed APIs couldn't enable:

  • Offline-first distribution: Users clone and run — no API keys, no internet, no account creation.
  • Remixability: The JSON quiz schema is human-editable. Teachers, event organizers, or hobbyists can fork the repo, swap halloween.json for their own topic, and have a working branded quiz in minutes.
  • Archival permanence: The high_scores.txt plain-text format will be readable in 20 years. No database migrations, no SaaS shutdown risk.

Open innovation turned a weekend hack into a durable, distributable, hackable tool — exactly the spirit of Hacktoberfest.


Happy Halloween! 🎃👻

Top comments (0)