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

Homework 6 - Connections.js

Due: Thursday, April 11, 2024 at 11:59pm

Purpose:

  • Gain experience writing in JavaScript
  • Handle form data and manipulate the DOM in JavaScript
  • Maintain persistent storage with localStorage

Overview

Based on the success of our earlier Connections game from Homework 5, we’ll again implement a Connections-like game—this time, in JavaScript! For this homework, you may work alone or with another student in this course. Specifically, you will implement a game that picks 4 categories which each have 4 associated words, displays the 16 words shuffled in a 4x4 table, and requires the user to guess which words belong to the same category. It then provides feedback on if the user guessed correctly or how close their guess was, as well as a list of their prior guesses. You may use your Homework 5 as a starting point, or you may implement everything from scratch. However, unlike Homework 5, in this version the entire game will be played client-side using JavaScript.

Connections.js Requirements

Review Homework 5 for the description of how the Connections game is played. This client-side version will consist of only one page, index.html, and will display a game page as well as the user’s game stats. For the game, the user will be presented with a 4x4 table/grid of words or phrases. Unlike Homework 5, the user will be able to interact directly with the table of words. The user may select (or deselect) a word in the table by clicking on its cell. Selected words should be highlighted so that the user knows which have been selected. The user will also be presented a button to submit their guess. If they do not have exactly 4 words selected when they submit their guess, the page should be updated to display an error message to the user. If they do have 4 words selected, the game should check if they correctly guessed 4 words in the same category.

  • If they are incorrect, the game page will be updated, showing their previous guesses and how close they were. That is, if at least two of words (or phrases) the user guessed are in the same category, we’ll tell the user how many of the other words (or phrases) in their guess were not part of the category. It will also deselect their current words so that they can select again.
  • If they are correct, and guess all the words in a particular category, those words (or phrases) are removed from the table and the table shrinks by one row. But remember, we will still show them all their prior guesses. Users may continue guessing until they guess all the words (or phrases) in all the categories, at which point they will be shown the results of their game.

For this assignment, you must implement the following components. (You may implement more functionality if you wish, but remember that we’ll be grading on effort in implementing these components below.)

  1. Your index.html should have at least the following three sections (i.e., portions of the page) for the user. You may choose to include more.
    1. Game. This section will display information about the current in-progress game. It will include a form with the following input and functionality. Note that the action of the form should not be a PHP page, you should have an event handler instead to update the page when the user submits the form.
      • Instructions asking the user to choose 4 words from the table.
      • The 4x4 table/grid of words with event handlers to update the page when the user clicks to select any word
      • A button for the user to submit the current guess.
      • A list of all the user’s prior guesses. Please be creative! You are encouraged to determine how best to organize the display, but for each prior guess, the application must display:
        • how many of the other words (or phrases) in their guess were not part of the category (if at least two words (or phrases) were from the same category)
      • An option for the user to shuffle (or randomize) the current table of words.
      • An option (link, button, etc) for the user to start a new game (which will end the current game, if applicable).
    2. User Game Statistics. This section will display the user’s game statistics:
      • The number of games played
      • The number of games won
      • The length of the current win streak (how many games they have won in a row)
      • Average number of guesses per game
    3. Clear History. In a separate section, provide the users a button to clear out their data from the application.
  2. You must implement the following event handlers in JavaScript:
    1. New game functionality. The user must be able to start a new game.
      • When the user clicks the new game button/link, the event handler should load a new set of random categories using the provided getRandomCategories() function (see below) and redraw the game board.
      • If a game was currently in progress when this event handler is called:
        • Update the game statistics to clear the win streak and the average number of guesses per game. Hint: you may want to keep track of the overall number of guesses.
        • Remove any display of the prior guesses for the in-progress game
      • Update the game statistics to increase the number of games played
    2. Guess words functionality. The user must be able to make a guess.
      • When the user selects words in the table, and enters their guess, the 4 words they chose must be compared with the words across current categories to determine if the words were in the same category. In particular, this event handler should calculate:
        • if all four words are in the same category, or
        • if two or more words belong to the same category and
        • how many words were not in the majority category in the guess.
      • Clear (deselect or unhighlight) the selected words so that the user can enter their next guess.
      • Provide validation and feedback if the user selects fewer than or more than 4 words for their guess.
      • If the user correctly guesses all 4 categories, update the game statistics, hide the game grid, and disable the submission and randomize buttons until the user starts a new game.
    3. Page load and unload. The user’s data must be stored between views of the page.
      • When the page unloads, store the current game and game statistics in localStorage.
      • When the page loads, if there is a game or game statistics stored in localStorage, then repopulate the display with the stored version.
    4. Clear history. The user must be able to clear the game statistics (and any current game) from the browser.
      • When the user clicks the clear history button, your application should remove any game and game statistics information stored in localStorage, clear the stats from the DOM, and start a new game.
  3. You should use an object or array object to store the game and game statistics. By creating an object to store them, you will be able to store the current state more easily in localStorage by converting the object to a JSON string. See JSON.stringify() and JSON.parse().
  4. Download and include the following connections.js JavaScript into your index.html file. This JavaScript library contains a function, getRandomCategories(), that queries our categroy list and returns an object with 4 random categories with 4 random words each. You should use this function to get a new set of categories when starting a new game.
    • connections.js
    • You must write a separate function that handles the setup of the new game. This function must take one parameter: an object that contains the categories and words to start the game.
    • In the event handler for when the user chooses to start a new game, call getRandomCategories() and pass in your separate function above as the only parameter. getRandomCategories() will then call your function with the new category object.

Note: as the user is playing the game, your application must not require the browser to reload the page or redirect the user to a different page. All interactions of the user with the game must stay on index.html until the user decides to leave the game.

We have explicitly left some requirements of the assignment vague to provide freedom of design. You are encouraged to be creative in your implementations!

Additional JavaScript Notes

  1. You may include your JavaScript code directly in your index.html file or write a separate .js file and include it in index.html.
  2. For this submission, you may NOT use jQuery.

Submission

The submission will consist of two parts:

  1. Submit your code (HTML, CSS, JavaScript, etc) to Gradescope in the “Homework 6” submission. You may choose to upload the files individually, upload a zip folder, or upload from a GitHub repository.
    • You must include a link to your published version in the comments of your index.html page
  2. Publish your web site to the cs4640 server under a folder titled “hw6”. Therefore, we should be able to access your work at https://cs4640.cs.virginia.edu/yourid/hw6. If you work with a partner, each person should publish the work to their web space.

Grading Rubric

This homework is worth 50 points, based on the following rubric:

  • 5 points - Game display
  • 5 points - User Stats display
  • 10 points - New game event handler
  • 10 points - Guess/submit words event handler
  • 10 points - Clear history event handler
  • 5 points - Maintain state in Local Storage across page loads
  • 5 points - Publishing your site to the cs4640 server

Academic Integrity

For this assignment, you are welcome to share/publish your website! You’ll be doing that on our cs4640 server as well. We only ask that you not make any GitHub projects public until after the deadline.

Note: You must cite any sources you use in a comment at the top of your index.html file. For example:

<!DOCTYPE html>
<!--
Sources used: https://cs4640.cs.virginia.edu, ...
-->
<html lang="en">
    <head>
    ...

Use of Generative AI

For Homework 6, you are not allowed to use generative AI tools to help you solve this problem.

Other Notes

In case you are interested, here is the PHP code of our API endpoint. It reads from a our connections.json file, then prints out json containing 4 categories with 4 words each.

<?php
// Allow Cross-Origin Scripting so that we can develop
// on our local Docker environments
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Methods: GET, OPTIONS");

// Let the browser know we're sending back JSON instead of HTML
header("Content-Type: application/json");

// Load all connections categories
$data = json_decode(file_get_contents("connections.json"), true);

// Pick 4 categories at random
$categories = array_rand($data, 4);

// Build the return data structure
$output = [
    "result"=> "success",
    "categories"=> []
];

foreach ($categories as $cat) {
    $keys = array_rand($data[$cat], 4);
    $words = [];
    foreach ($keys as $key)
        array_push($words, $data[$cat][$key]);

    array_push($output["categories"], [
        "category" => $cat,
        "words" => $words
    ]);
}

// Print out JSON 
echo json_encode($output, JSON_PRETTY_PRINT);