Assigned: 2019-09-19
Due Date: 2019-09-24 by 11:59PM U.S. Central Time
Uses bicycle indoors
"Oak's words echoed... Trainer! There's a time and place for everything! But not now."
— Pokémon Red/Blue
Master Worrywort: You! Mr. Bilbo, where're you off to?
Bilbo: Can't stop! I'm already late.
Master Worrywort: Late for what?
Bilbo: [excited] I'm going on an adventure!
— The Hobbit: An Unexpected Journey (2012)
Fiction Interactive has been extremely lucky to have you on their team. After your manager heard about the work you did developing a prototype game engine, you were promoted to Senior Game Developer! There's only one problem: the games you've been running on your engine are a bit dull, so your coworkers have challenged you to improve your engine with additional features and to write your own game to demonstrate its capabilities.
You will develop this assignment in the same repository as last week, using your existing code. You should a) create a new branch in your repository, and b) work, commit, and push your engine modifications to that branch (and not to the master branch). See here and here for some instructions that may help.
You will not be reusing the siebel.json
file from last week;
instead, you will need to write your own adventure game that matches
the modified schema described later in this assignment.
As in the previous assignment, you should avoid copy-pasting entire
JSON files into your code. You may hand-write small snippets of JSON
for testing purposes and store them in your tests. We have also
provided you with a helper method that can load in a file as a
String
.
We've modified the schema from last week with two major additions: items and enabled/disabled directions. It now looks something like this:
Direction := {
directionName : String
room : String // Name of the room this direction points to
enabled : Boolean // Whether this direction can be traveled to or not
validKeyNames : String[] // Names of items that can unlock the direction
}
Item := {
name : String
}
Room := {
name : String
description : String
directions : Direction[]
items : Item[]
}
Player := {
items : Item[] // Items the player is currently holding or starts out holding
}
Layout := {
startingRoom : String // The name of the start room for the game
endingRoom : String // The name of the end room for the game
rooms : Room[]
player : Player
}
The enabled
field of Direction says if the Direction can be used or
not; if the field is true
it can be used, and if it is false
it
cannot be used. To enable a Direction that is disabled the player must
use the command of the form “use Item with Direction”
(where Item
and Direction
are the names of the item and direction). The engine
should check to see if the Player has the Item and if that item name
matches a name in the validKeyNames
array of the Direction. If it
does, it should enable the Direction. If the player tries to go Direction
for a Direction that is not enabled, you should print out
an appropriate error message.
The items
field of Room is the Items that start in Rooms. They may
be picked up by players using the command of the form “pickup Item”
(where Item
is the name of the item). If the player tries to pickup Item
for an Item that is not in the current Room, you should print
out an appropriate error message.
You must extend your engine to print out the list of items currently in the room in addition to the room's description. For example:
You are in the west entry of Siebel Center. You can see the elevator, the ACM office, and hallways to the north and east.
You can see a sweatshirt, coin, and key here.
That means any time the description is printed, there should also be a printout of this list of items.
Our original siebel.json
file no longer matches the schema, so you
will need to make your own unique adventure game that matches this
schema (plus any custom extensions you add, detailed below).
Your game engine must be able to support loading JSON either from a
local file or from a URL on the Internet, and gracefully handle the
situations when an error occurs. This must be done using
command-line arguments (i.e, not with using a Scanner
to read
user's input). This
video might help with
working with command-line arguments.
Your custom JSON is not hosted on the Internet (unless you choose to find a way to do so), so it will likely be loaded as a local file, but your engine should still allow for loading either a URL or a local file.
Your game engine must support a few new commands (in addition to the
new use
and pickup
commands discussed earlier):
When a player types examine
, you should print out the description of
the Room they're currently in, and any Items present in the Room.
When a player types drop Item
(where Item
is the name of an item),
if the player has collected that item, it should be placed into the
current room and removed from their inventory. If the player does not
have the Item, you should print an appropriate error message.
You must also extend your game engine in a substantial and interesting way. You are allowed to modify the schema to make your extensions work, but you should not get rid of any features we've added (the Items or enabled/disabled Directions).
The extension must be of sufficient complexity and technical difficulty; if you are unsure whether your extension meets that criteria, make a private post on Piazza. Extensions that are trivial will receive a reduced grade.
Examples of reasonable extensions include:
Be creative!
At a minimum, your engine must support the following commands:
quit
or exit
to end the gamego
to move between roomspickup
to collect an Itemdrop
to drop an Itemexamine
to print the description of the current room and any available itemsuse
to use an Item on a Direction, potentially enabling itOther things we will take into consideration:
master
branch?You are still expected to write unit tests for this project. Some
parts of this project might be difficult to test; therefore, your
challenge is to figure out how to structure your code in such a way
that much of it can be tested. That said, some things (like reading
input from the user with a Scanner
) are too difficult to reasonably
test automatically; if in doubt, ask on Piazza whether something is
considered "testable" or not.
Try to make commits at regular intervals. You want to leave a clear trail of discrete pieces of progress that you've made as you work. Commits are cheap! Make lots of them. Once again, try to involve testing in your code development process; you don't have to write all of your tests before the code, but you should try to develop your code alongside your tests and vice versa.
Use your best judgement to write the cleanest code you can; make sure you can justify any design decisions you make in code review.
This is a test of your problem-solving skills: if you don't know how to do something (for example, setting command line arguments in IntelliJ,) you should try your favorite search engine. (Make sure you follow our policy on citing online code.) If you're still stuck, consider Piazza and office hours.