Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Trivia Game

Here is our example Trivia game code, using a Front Controller design.

index.php

Our index file is in the web/www directory. If we were to deploy it to the cs4640 server, it would be in our public_html directory.

<?php

// DEBUGGING ONLY! Show all errors.
error_reporting(E_ALL);
ini_set("display_errors", 1);

// Class autoloading by name.  All our classes will be in a directory
// that Apache does not serve publicly.  They will be in /opt/src/, which
// is our src/ directory in Docker.
spl_autoload_register(function ($classname) {
        include "/opt/src/trivia/$classname.php";
});

// Other global things that we need to do
// (such as starting a session, coming soon!)

// Instantiate the front controller
$trivia = new TriviaController($_GET);

// Run the controller
$trivia->run();

TriviaController.php

The TriviaContoller class is defined in a file that resides in the src/ directory. This means that Apache cannot directly serve the file. Note that when it is deployed to the cs4640 server, this file will need to be placed outside the public_html directory.

<?php

class TriviaController {

    private $questions = [];
    
    private $db;

    /**
     * Constructor
     */
    public function __construct($input) {
        $this->db = new Database();
        $this->input = $input;
        $this->loadQuestions();
    }

    /**
     * Run the server
     * 
     * Given the input (usually $_GET), then it will determine
     * which command to execute based on the given "command"
     * parameter.  Default is the welcome page.
     */
    public function run() {
        // Get the command
        $command = "example";
        if (isset($this->input["command"]))
            $command = $this->input["command"];

        switch($command) {
            case "question":
                $this->showQuestion();
                break;
            case "answer":
                $this->answerQuestion();
                break;
            default:
                $this->showWelcome();
                break;
        }
    }

    /**
     * Load questions from a file, store them as an array
     * in the current object.
     */
    public function loadQuestions() {
        $this->questions = json_decode(
            file_get_contents("/opt/src/trivia/data/trivia-s24.json"), true);

        if (empty($this->questions)) {
            die("Something went wrong loading questions");
        }
    }
    
    /**
     * Our getQuestion function, now as a method!
     */
    public function getQuestion($id=null) {

        if ($id === null) {
            $id = array_rand($this->questions);
            return [ "id" => $id, "question" => $this->questions[$id]["question"]];
        }
        if (is_numeric($id) && isset($this->questions[$id])) {
            return $this->questions[$id];
        }
        return false;
    }

    /**
     * Show a question to the user.  This function loads a
     * template PHP file and displays it to the user based on
     * properties of this object.
     */
    public function showQuestion($message = "") {
        $question = $this->getQuestion();
        include("/opt/src/trivia/templates/question.php");
    }

    /**
     * Show the welcome page to the user.
     */
    public function showWelcome() {
        include("/opt/src/trivia/templates/welcome.php");
    }

    /**
     * Check the user's answer to a question.
     */
    public function answerQuestion() {
        $message = "";
        if (isset($_POST["questionid"]) && is_numeric($_POST["questionid"])) {

            $question = $this->getQuestion($_POST["questionid"]);

            if (strtolower(trim($_POST["answer"])) == strtolower($question["answer"])) {
                $message = "<div class=\"alert alert-success\" role=\"alert\">
                    Correct!
                    </div>";
            }
            else {
                $message = "<div class=\"alert alert-danger\" role=\"alert\">
                    Incorrect! The correct answer was: {$question["answer"]}
                    </div>";
            }
        }

        $this->showQuestion($message);
    }

}

templates/question.php

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="CS4640 Spring 2024">
  <meta name="description" content="Our Front-Controller Trivia Game">  
  <title>PHP Form Example - Trivia</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"  integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"  crossorigin="anonymous">       
</head>

<body>
    
<div class="container" style="margin-top: 15px;">
        <div class="row">
                <div class="col-xs-12">
                <h1>Trivia Game</h1>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                <?=$message?>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">

                <div class="card">
                    <div class="card-header">
                        Question
                    </div>
                    <div class="card-body">
                        <h5 class="card-title"><?=$question["question"]?></h5>
                    </div>
                </div>
                </div>
                
            </div>
            <div class="row">
                <div class="col-xs-12">
                <form action="?command=answer" method="post">
                    <input type="hidden" name="questionid" value="<?=$question["id"]?>">

                    <div class="mb-3">
                        <label for="answer" class="form-label">Trivia Answer: </label>
                        <input type="text" class="form-control" id="trivia-answer" name="answer">
                    </div>

                    <button type="submit" class="btn btn-primary">Submit Answer</button>
                </form>
                </div>
            </div>
        </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>

template/welcome.php

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="CS4640 Spring 2024">
  <meta name="description" content="Our Front-Controller Trivia Game">  
  <title>PHP Form Example - Trivia</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"  integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"  crossorigin="anonymous">       
</head>

<body>

<div class="container" style="margin-top: 15px;">
            <div class="row">
                <div class="col-xs-12">
                <h1>Welcome to our Trivia Game!</h1>
                <p>Please answer the questions below to begin playing</p>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-12">
                <form action="?command=question" method="post">
                    <div class="mb-3">
                        <label for="name" class="form-label">Name</label>
                        <input type="text" class="form-control" id="name" name="fullname">
                    </div>
                    <div class="mb-3">
                        <label for="email" class="form-label">Email address</label>
                        <input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp">
                        <div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
                    </div>
                    <div class="mb-3">
                        <label for="passwd" class="form-label">Password</label>
                        <input type="password" class="form-control" id="passwd" name="passwd">
                    </div>

                    <button type="submit" class="btn btn-primary">Start</button>
                </form>
                </div>
            </div>
        </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>

trivia-s24.json

Here is the JSON file used to populate the trivia questions.

[
    {
        "question": "How many floors does the Eiffel Tower have?",
        "answer": "3"
    },
    {
        "question": "Where must Frodo Baggins take the ring in order to destroy it?",
        "answer": "Mt. Doom"
    },
    {
        "question": "What are the spots on dice called?",
        "answer": "Pips"
    },
    {
        "question": "What beverage does Mr. D drink instead of wine in Percy Jackson?",
        "answer": "Diet Coke"
    },
    {
        "question": "What are the two landlocked countries in South America?",
        "answer": "Bolivia and Paraguay"
    },
    {
        "question": "What is the national animal of Scotland?",
        "answer": "Unicorn"
    },
    {
        "question": "Willem Dafoe has appeared in what number of feature films as of March 1, 2024?",
        "answer": "147"
    },
    {
        "question": "What's the only WGS class that counts as an CS integration elective?",
        "answer": "Sex and Resistance on the Internet"
    },
    {
        "question": "What is the oldest animal on Earth?",
        "answer": "Seychelles giant tortoise"
    },
    {
        "question": "What country has Latin as one of its official languages?",
        "answer": "The Vatican (It qualifies as an independent country)"
    },
    {
        "question": "Freddie Prinze Jr. and Sarah Michelle Gellar, now married, starred together in this classic 2002 adventure comedy movie.",
        "answer": "Scooby-Doo"
    },
    {
        "question": "What was Daffy Duck's job on his business card in the Looney Tune's show?",
        "answer": "Wizard"
    },
    {
        "question": "In what year were the first Air Jordan sneakers released?",
        "answer": "1984"
    },
    {
        "question": "230 - 220 * 0.5",
        "answer": "5!"
    },
    {
        "question": "What do you call fake spaghetti?",
        "answer": "an impasta"
    },
    {
        "question": "What planet was the final battle in Star Wars Episode 6 fought on?",
        "answer": "Endor"
    },
    {
        "question": "To the nearest degree, how far does the Leaning Tower of Pisa lean?",
        "answer": "4"
    },
    {
        "question": "who was the times person of the year for 2023",
        "answer": "taylor swift"
    },
    {
        "question": "What is the capital of Papua New Guinea?",
        "answer": "Port Moresby"
    },
    {
        "question": "What is the name of Games Workshop's premier tabletop game?",
        "answer": "Warhammer"
    },
    {
        "question": "What is a group of crows called?",
        "answer": "A murder"
    },
    {
        "question": "What is the most populated capital city in the world?",
        "answer": "Beijing"
    },
    {
        "question": "How many legs does a lobster have?",
        "answer": "10"
    },
    {
        "question": "What is the meaning of life?",
        "answer": "42"
    },
    {
        "question": "What is Shaggy from Scooby Doo's real name?",
        "answer": "Norville Rogers"
    },
    {
        "question": "Which national park is home to the largest known tree in the world?",
        "answer": "Sequoia National Park"
    },
    {
        "question": "What work of literature is regarded as the \"first novel\"?",
        "answer": "Genji Monogatari (The Tale of Genji)"
    },
    {
        "question": "What color is scooby's tag?",
        "answer": "Blue"
    },
    {
        "question": "Who wrote the short story Bartleby, The Scrivener",
        "answer": "Herman Melville"
    },
    {
        "question": "What's the name of the student radio on grounds?",
        "answer": "WXTJ"
    },
    {
        "question": "Who created the first computer?",
        "answer": "Charles Babbage"
    },
    {
        "question": "What vehicle is Volkswagen best known for in the world?",
        "answer": "The Beetle"
    },
    {
        "question": "This hit late 90s-early 00s fantasy action tv show starring Sarah Michelle Gellar and David Boreanaz involved vampires, magic, and doomsdays.",
        "answer": "Buffy the Vampire Slayer"
    },
    {
        "question": "What year was Kermit the Frog first shown on TV?",
        "answer": "1955"
    },
    {
        "question": "Which month of the year is National Ice Cream Month?",
        "answer": "July"
    },
    {
        "question": "What is the speed of light",
        "answer": "300,000,000 m\/s!"
    },
    {
        "question": "In which year did the Berlin Wall fall, symbolizing the end of the Cold War division between East and West Germany?",
        "answer": "Nov-89"
    },
    {
        "question": "What soccer team has won the most Champions League Titles in history?",
        "answer": "Real Madrid"
    },
    {
        "question": "What was the first submarine to complete a submerged circumnavigation of the Earth?",
        "answer": "USS Triton"
    },
    {
        "question": "what performer played at coachella 2023 after a long hiatus",
        "answer": "frank ocean"
    },
    {
        "question": "What is the largest landlocked country in the world?",
        "answer": "Kazakhstan"
    },
    {
        "question": "Is the program League of Legends considered malware?",
        "answer": "Yes"
    },
    {
        "question": "What is the largest desert in the world?",
        "answer": "Antarctica"
    },
    {
        "question": "What type of cloud produces thunderstorms?",
        "answer": "Cumulonimbus clouds"
    }
]