Info Assignments Office Hours Hall of Fame Notes
Info Assignments Office Hours Hall of Fame Notes

Amazing Adventures

Assigned: 2020-09-09
Due Date: 2020-09-15 by 11:59PM U.S. Central Time

Assignment

Get your copy of the assignment here: https://classroom.github.com/a/xUq-14uj

You may encounter "Non-managed pom.xml file found". You should select "Add as Maven Project"

This week's assignment is a creative exercise where you get to build a text adventure game! In the previous assignment, we asked you to find a JSON and parse it. This time, you'll actually be creating the JSON to our specifications and using it in a console adventure game.

Gradescope

There is no autograder for this assignment, but you still must submit your GitHub repository to Gradescope.

Goals

Instructions

Background

The Adventure Game is a classic video game genre that generally features a protagonist exploring a map and solving puzzles. From Wikipedia:

Initial adventure games developed in the 1970s and early 1980s were text-based, using text parsers to translate the player's input into commands. As personal computers became more powerful with better graphics, the graphic adventure-game format became popular, initially by augmenting player's text commands with graphics, but soon moving towards point-and-click interfaces. Further computer advances led to adventure games with more immersive graphics using real-time or pre-rendered three-dimensional scenes or full-motion video taken from the first- or third-person perspective.

You'll be designing a text-based adventure game, where the user will input commands and your game engine will parse them into actions. You'll send back the feedback in text form to the user.

You'll also be designing a map for the game (no, not a Map<K, V>; the normal kind of map). Your map should have rooms with paths/connections to other rooms, and there should be a goal room that when reached, the player wins the game. However, you can also interpret this to be more of a story-based format where "paths" represent dialogue options; you have a lot of freedom here so long as you can interact with the world or story in some meaningful way.

Part 0 - Designing JSON

It's time to put your JSON knowledge to the test. We are going to describe the basic interactions an Adventure game needs to support, and it's up to you to include the relevant data in your JSON. Because of this, it is critical that you read through all the parts of this assignment before starting to write JSON, especially Part 2's command structure.

When designing a schema, you should always try to relate concepts in the simplest way possible. This simplicity may come from grouping certain fields together (e.g. creating a JSON object to group data about a game element), making the schema easily expandable to include new fields, and designing the schema to translate well to a Java object.

For designing an Adventure state schema, a good place to start is with nouns. Think about what the state needs to know and write it down. Then think of how all those things can be organized into groups. For example, the state would definitely include your current room. What fields would a room have and how do they translate to JSON?

Part 1 - Loading Game Data

You just created a JSON schema with all the data that your game needs, but now you need to load it for your game engine to consume.

The first thing you should tackle is creating POJOs corresponding to the objects in your JSON. Because you are the architect of the schema, you can go back and change the JSON if you find a better way of expressing your objects.

You should have experience loading JSON from the last assignment; in this assignment, you may use GSON or Jackson again to preform this task. However, this time loading JSON is part of your application, so you must handle & test it. Pay attention to what happens when:

, and be sure to handle these cases gracefully.

Part 2 - The Game Engine

You now need to write the brains of your game. Once again, we are giving you a lot of freedom in how exactly you accomplish this, but we have some basic interactions we would like to see. The game should accept input from the user in the console, and should output data back to the console.

Because you are requesting user input, it would be helpful to have a prompt. A prompt is a small string that gets printed at the beginning of the line in the console to indicate that the user should type input. Before you request input from the user, we'd like you to print this prompt: "> " (a greater than sign followed by a space). To accomplish this, think about what System.out.print does differently than System.out.println.

Below are the interactions your game must support. Note that the examples are collapsed for ease of reading purposes, but they represent exactly how we want your console interaction to work, so pay close attention to them.

Quitting

If the input is either quit or exit, then the game should wrap-up and the program should exit.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> quit

Moving Around

If the input matches the pattern go <direction_name>, then the current room that the user is in should change to the room in that direction.

Whenever a room is visited, it should print the room's information, including its name, description, possible directions, and items.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> go East
You are in the west entry of Siebel Center. You can see the elevator, the ACM office, and hallways to the north and east.
From here, you can go: West, Northeast, North, or East
Items visible: sweatshirt, key

If the user inputs an invalid direction, then the game should inform them it can't go that way by saying: I can't go "<direction_name>"!

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> go Eastward
I can't go "Eastward"!

Reaching the ending room should result in the room description being displayed (this could be some "win" text; it's up to you), and the program should exit.

Click to see an example
You are in your room, in front of your computer.
From here, you can go: log in to Zoom
Items visible: keyboard, mouse
> go log in to Zoom
You've made it on time to code review; you win!

Examining a Room

If the input is examine, the game should repeat the information about the room, including its name, description, possible directions, and items.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> examine
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin

Items

If the input matches the pattern take <item_name>, the room should attempt to give that item to the user.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> take coin
> examine
You are on Matthews, outside the Siebel Center
From here, you can go: East

If no such item exists in the room, then the game should respond with There is no item "<item_name>" in the room.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> take icard
There is no item "icard" in the room.

If the input matches the pattern drop <item_name>, the user should remove an item from their inventory and place it in the room.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> drop icard
> examine
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin, icard

If the user doesn't have the item, the game should respond with You don't have "<item_name>!".

If the room already has that item, the game should respond with The item "<item_name>" is already in this room!, and it should not add the duplicate.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> drop proof that P=NP
You don't have "proof that P=NP"!
> drop coin
The item "coin" is already in this room!

User-Friendly Commands

Your goal should be to design a consistent yet user-friendly experience for your players. As such, you should be able to handle casing errors and extra whitespace.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: East
Items visible: coin
> go       East
You are in the west entry of Siebel Center. You can see the elevator, the ACM office, and hallways to the north and east.
From here, you can go: West, Northeast, North, or East
Items visible: sweatshirt, key
> TAKE SWEaTSHIRt
> examine
You are in the west entry of Siebel Center. You can see the elevator, the ACM office, and hallways to the north and east.
From here, you can go: West, Northeast, North, or East
Items visible: key

Note you don't need to worry whitespace handling for stored values like direction names, item names, etc, as shown below.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: up and out, East
Items visible: coin
> go   up    and   out
I can't go "up    and   out"!

Unknown Commands

If the user types anything that doesn't match the above specification, then you should inform the user that they typed an invalid command.

Click to see an example
You are on Matthews, outside the Siebel Center
From here, you can go: up and out, East
Items visible: coin
> fly airplane
I don't understand "fly airplane"!

Part 3: Custom Feature

In addition to the features listed above (movement, items, and quitting), you should implement your own custom feature. You have a lot of freedom on what this feature can be, however there are a couple stipulations:

  1. The feature cannot be trivial to implement. It cannot be a slight variation of a required command nor can it rely on the code used in those commands for the most part.
  2. This isn’t the main part of the assignment; It shouldn’t take more than 1-2 hours so don’t stress out over it.

Here are a few examples of valid custom features to inspire you:

Testing

Testing might seem a little bit nebulous for a large user-facing project like this. Certain designs will be more testable than others, so try to think about how you can design your classes & methods to be easily testable. You should be able to isolate smaller units of your total operation into unit tests.

Deliverables and Grading

For the project to be considered complete, your submission must:

As always, many points on this assignment are made up of aspects of your physical code and your design. Keep using correct style conventions according to the Google Java Style Guide, and think about how you can make a large application like this modular.

We're also paying a lot of attention to Object Decomposition on this assignment, as you will be working with a variety of objects. Make sure you are placing methods in the classes where they make the most sense, and also make sure data flows through your objects in a clean, extensible manner.

Assignment Rubric

Click here to view

Note! New items in bold

Readability and flexibility of code

  • Modularity: each method should perform one distinct task
  • It should be easy to read through each method, follow its control flow, and verify its correctness
  • The code should be flexible/ready for change (no magic numbers, no violations of DRY)

Object decomposition

  • Choice of classes to create

    • Classes should be coherent units and have clear purposes
    • Classes should not be too “big” or be responsible for too much functionality
      • If a “big” class contains things which aren’t closely related, it may be appropriate to break off part of it into a new class. (This is similar to decomposing long functions into modular units.)
    • If a group of global/static functions are all operating on the same data/object, they should probably be bundled together into a class
    • As an example, the information stored in parallel arrays is often closely related, so it’s usually good design to group the information into a class and combine the parallel arrays into a single array
  • Placement of methods

    • Functionality should be placed in the class that it's most related to
  • Member variables stored by each class

    • Classes should store their data using the most intuitive data structure
    • No "missing" member variables
    • No member variables which should be local variables
    • No redundancy / storing multiple copies of the same data in different formats
  • Encapsulation

    • Appropriate access modifiers
    • Member variables should generally only modified by member functions in the same class
    • The interface of a class should be intuitive/abstract, and external code should only interact with the class via the interface
      • By intuitive, we mean that it should be easy to understand and use the class, and there shouldn’t be any hidden assumptions about how the class should be used
      • By abstract, we mean that an external client shouldn’t need to worry about the internal details of the class
    • No unnecessary getters/setters
    • In Java, getters should not return a mutable member variable

Documentation

  • Specifications
    • Specifications are required for all functions which are part of the public interface of a class
    • Specifications should precisely describe the inputs and outputs of a function, and should also describe what the function does (e.g. mutating state of object)
    • Specifications should also be formatted properly (e.g. follow Javadoc style for Java assignments)
  • Inline comments should not describe things which are obvious from the code, and should describe things which need clarification

Naming

  • Semantics: names should effectively describe the entities they represent; they should be unambiguous and leave no potential for misinterpretation. However, they should not be too verbose.
  • Style: names should follow the Google Java/C++ Style Guide

Layout

  • Spacing should be readable and consistent; your code should look professional
    • Vertical whitespace should be meaningful
      • Vertical whitespace can help create paragraphs
      • Having 2+ empty lines in a row, or empty lines at the beginning or end of files, is usually a waste of space and looks inconsistent
    • Horizontal whitespace should be present where required by the Google Style Guide
  • Lines should all be under 100 characters; no horizontal scrolling should be necessary

Testing

  • You should make sure all types of inputs and outputs are tested.
    • If category A of inputs is likely to cause different behavior than category B, then you should test inputs from both categories
  • Boundary/edge cases often cause different/unexpected behavior, and thus, they should be tested
  • Your tests should ensure that the application state is correctly updated. For example, if a function mutates an object, you can’t just check that the return value is correct. You must also ensure that the object reflects those changes.
  • Your tests should cover all of the functionality that you’ve implemented. In other words, every line of code should be exercised by some test case, unless the assignment documentation says otherwise
  • Each individual test case should only serve one coherent purpose. Individual test cases should not have assertions testing unrelated things
  • Your tests, like your code, should be organized and easy to understand. This includes:
    • Easy to verify thoroughness / all possibilities covered
    • Easy to verify the correctness of each test case
    • Clear categories of test cases, where similar tests are grouped together
      • In Java, this can be accomplished by inserting comments to separate groups
    • Test case names make the purpose of each test case clear
      • Here is one possible way to name test methods in JUnit
    • Different test files for different source files

Process

  • Commit modularity
    • Code should be checked-in periodically/progressively in logical chunks
    • Unrelated changes should not be bundled in the same commit
  • Commit messages
    • Should concisely and accurately describe the changes made
    • Should have a consistent style and look professional
      • First word of the message should be a verb, and it should be capitalized

Presentation

  • Arrived on time with all necessary materials and ready to go
  • Good selection of topics to focus on
  • Logical order of presentation
  • Appropriate pacing and engagement of the fellow students
  • Speaking loud enough and enunciating clearly

Participation

  • Each student should contribute at least one meaningful comment or question for every other student who presents in his/her code review
  • Students must behave respectfully to moderator and other students

Weightings

Your grades for each section of the rubric will be weighted as follows:

  • Readability and flexibility of code (15%)
  • Object decomposition (20%)
  • Documentation (10%)
  • Naming (10%)
  • Layout (5%)
  • Testing (20%)
  • Process (10%)
  • Presentation (5%)
  • Participation (5%)