CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions)
Assignment Guidelines:
This assignment covers material up to (and including) Module 10.
Do not use recursion. All repetition must be performed using iteration (while and for loops only)
and abstract list functions (map and filter).
Submission details:
– Solutions to all four questions must be placed in a single file, a09.py, and must be completed
using Python 3.
– Download the interface file from the course Web page to ensure that all class and function
names are spelled correctly and each function and method has the correct number and order
of parameters.
– All solutions must be submitted to MarkUs. No solutions will be accepted through email, even
if you are having issues with MarkUs.
– Verify using MarkUs and your basic test results that your files were properly submitted and are
readable on MarkUs.
– For full style marks, your program must follow the Python section of the CS116 Style Guide.
– Be sure to review the Academic Integrity policy on the Assignments page
– Helper functions need design recipe elements but not examples and tests.
This assignment includes special instructions regarding the Design Recipe. Please see the note on
the last page for more information.
If you wish to test your code, download the testing module from the course web page and include
import check in your solution file.
– Test data for all questions will always meet the stated assumptions for consumed values.
Restrictions:
– Do not import any modules other than math and check.
– Do not use any other Python functions not discussed in class or explicitly allowed elsewhere.
See the allowable functions post on Piazza. You are always allowed to define your own helper
functions, as long as they meet the assignment restrictions.
– While you may use global constants in your solutions, do not use global variables for anything
other than testing.
– Read each question carefully for additional restrictions.
– The solutions you submit must be entirely your own work. Do not look up either full
or partial solutions on the Internet or in printed sources.
1
CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions)
Text Adventures
Before computers were powerful enough for fancy graphics, some of the best computer games were Text
Adventures. The game would describe the world to you in words, and you would move through that world
and interact with it by issuing commands in words. (If you’ve ever played Dungeons & Dragons, your
relationship to the game is a bit like your relationship to your Dungeon Master.) Infocom was probably the
most famous maker of these games; you can play the classic games Zork I (1980) and The Hitchhiker’s
Guide to the Galaxy (1984) here:
http://textadventures.co.uk/g…
http://textadventures.co.uk/g…
In this assignment, you will implement a small subset of a text adventure game. A World consists of a set
of interconnected Rooms containing Things. As the Player, you can use Exits to walk from room to room,
looking at, picking up, and dropping Things. You can load a game from a text file, play it for a while, and
save the resulting game state to another text file.
To begin, download (and study!) the interface file from the course website. It contains a large amount
of starter code to help you complete your game.
Question 1: Playing the game
The game environment is stored in a class called World, and you will find a small test world defined as
global constant testworld. World includes a play method that acts a bit like Python itself: it allows
you to type in commands and shows you their effects. Have a look at that method (which is written for
you). It understands a few simple“verbs”: quit, look, inventory, take, drop, and go. Apart from quit, these
commands all call other methods in the World class. In this question you will make games playable by
implementing these methods.
(1) Implement the look method. It accepts a noun argument, giving the name of the thing the user
wants to look at, and doesn’t return anything. It prints the name and description of of the passed-in
noun. The player is able to look at a number of things; use the following order to decide what they
want to look at:
If the noun is the special word me, look at the player.
If the noun is the special word here, look at the player’s current room.
Next check the names of the things in the player’s inventory. If any thing’s name matches the
noun, look at that.
Finally, check the names of the things in the player’s room. If any thing’s name matches the
noun, look at that.
If none of the possibilities above provides a match, print the message “You don’t see that
here.”. This message is defined for you as a field in World class, so just print the contents of the
field; do the same with all the other messages given below.
In this and the other commands you can assume that when there is a match, the match is unique.
That is, although a world might contain two things of the same name, those things will never be in
the player’s inventory at the same time, or in the same room together.
Note that the Player, Thing, and Room classes already include look methods that print the
appropriate text for each kind of thing you can look at. Your job is simply to find the right object
and ask it to look.
(2) Implement the inventory method. It accepts no arguments (other than self) and doesn’t return
anything. It prints a formatted list of the names of the things that the player is currently carrying.
In particular, if the player is carrying anything, the method should print text like this:
Inventory : wallet , phone , keys
That is, on a single line you should print “Inventory: “, followed by a list of the names of the
things in the player’s inventory, separated by “, “. If the player’s inventory is empty, you should
print the message “You aren’t carrying anything.” (as defined in a constant).
2
CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions)
(3) Implement the go method. It accepts a noun argument, giving the name of the exit to go through,
and doesn’t return anything. If the noun corresponds to the name of one of the exits in the player’s
current room, mutate the contents of the World so that the player moves to the room at the other
end of that exit (the destination). In that case, the method should conclude by looking at their
new room, so the user can see where they ended up. If no exit with that name exists, the method
should print the message “You can’t go that way.” You can assume that no room contains two
exits of the same name.
(Note that the rooms and exits in a world behave a bit like the vertices and edges in a directed
graph, though you don’t need that information to complete the assignment.)
(4) Implement the take method. It accepts a noun argument, giving the name of the thing to pick
up, and doesn’t return anything. If the noun corresponds to a thing in the player’s current room,
mutate the World so that the thing is removed from the room’s contents and appended to the
player’s inventory. In that case, the method prints “Taken.”. If no such thing can be found in the
player’s room, the method prints “You can’t take that.”.
(5) Implement the drop method. It accepts a noun argument, giving the name of the thing to put
down, and doesn’t return anything. If the noun corresponds to a thing in the player’s inventory,
mutate the World so that the thing is removed from their inventory and appended to the contents
of the player’s current room. In that case, the method prints “Dropped.”. If no such thing can be
found in the player’s inventory, the method prints “You aren’t carrying that.”.
Once all of these methods are implemented, you should be able to play the test game, producing a
transcript like this one:
testworld.play()
Hallway
You are in the hallway of a university building. Students are coming and
going every which way.
Exits: shop, west.
- look me
Stu Dent
Stu Dent is an undergraduate Math student at the University of Waterloo,
who is excelling at this studies despite the fact that their name is a
terrible pun.
Carrying: wallet, keys, phone. - go shop
Coffee Shop
You are in the student-run coffee shop. Your mouth waters as you scan the
room, seeing many fine foodstuffs available for purchase.
Contents: cup of coffee.
Exits: hall. - take cup of coffee
Taken. - drop phone
Dropped. - inventory
Inventory: wallet, keys, cup of coffee - go trapdoor
You can’t go that way. - go hall
Hallway
You are in the hallway of a university building. Students are coming and
going every which way.
Exits: shop, west.
3
CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions) - take salmon
You can’t take that. - go west
Classroom
You are in a nondescript university classroom. Students sit in rows at
tables, pointedly ignoring the professor, who’s shouting and waving their
arms about at the front of the room.
Exits: hall. - drop cup of coffee
Dropped. -
quit
Goodbye.Question 2: Loading games
Write a global function called load. It consumes a single string argument, giving the name of a text file
to read from, and returns a World constructed from the information in the text file.
In order to describe a complete world, the information in the text file must be stored in a specific way.
Here is a description of the file format:
First we list all the things in the world, which can be in rooms or in the player’s inventory. Each
thing is represented in two lines in the text file. The first line contains the word thing, followed
by a numeric code preceded by a number sign, such as #3 or #784, followed by the name of thing
(which may consist of multiple words). The second line is a text description. The description can
be as long as you want (i.e., don’t worry about running over 80 characters). For example:
thing #17 lava lamp
A conical lava lamp, giving off an eerie red glow as its contents roil.
Next, we list all the rooms in the world. Every room is represented in three lines of text. The first
line contains the word room, followed by a numeric code (as above) and a room name (as above).
The second line is the description. The third line contains the word contents followed by the
numeric codes of the things currently in that room. For example:
room #237 Burj Khalifa
You are standing in Dubai, at the base of the world’s tallest building.
contents #8 #13 #1128
Next, we describe the game’s one and only player, using four lines of text. The first line contains
the word player, followed by a numeric code, followed by the player’s name. The second line is the
description. The third line is the player’s inventory, which works like a room’s contents. The
fourth line contains the word location followed by the numeric code of the room where the player
currently is. For example:
player #4 Feridun Hamdullahpur
The president of the University of Waterloo, wearing a suit and tie.
inventory #2 #61
location #92
Finally, we give all the exits that lead from one room to another. Every exit is described in one line
of text: the word exit, followed by the numeric code of the room that has this exit, followed by
the numeric code of the room that the exit leads to, followed by the exit’s name. For example:
exit #1 #3 green door
4
CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions)
Your job is to consume all of this information and use it to build the Python objects that make up a
World. When you do this, you must resolve every reference to a numeric code (e.g., in the list of contents of
a room, or in an exit) into the actual Thing or Room to which that code corresponds. You should also keep
these numeric codes around by passing them as IDs to the constructors of the Thing, Room, and Person
classes.
You can assume that the file uses the format above (you don’t have to check for errors). In particular,
you can assume that all numeric codes correspond to legal objects that have already been defined, and that
all numeric codes are unique. Every world must have exactly one player and at least one room (so that the
player can have a location).
We provide several example worlds in text files on the course web page. The file testworld.txt contains
the same world as the one described by the provided global variable testworld. One of these text files
contains additional keyexits; these are for Question 4 and can be ignored here.
Question 3: Saving games
If you can load a game from a text file, it makes sense that you should also be able to save a game to a
file. That way, you can load a game, play it for a while (mutating the World), and then save the new state
of the game to be resumed later. In the World class add a method called save, which takes a single file
name (i.e., a string) as input (in addition to self) and writes the complete state of the game to that file.
The format used should exactly match the format described above for loading. That is, if w is a World,
then the following code should work:
w . save (‘world . txt ‘)
w2 = load (‘world . txt ‘)w and w2 are now copies of the same game !
Question 4: Locks and keys
Finally, let’s add one new feature to the game mechanic, and see how it affects all the previous steps.
It would be interesting to have doors that lock, which in our game will take the form of exits that let
you pass only if the player has a certain thing (the exit’s“key”) in their inventory. Exits can have different
keys, and an exit that doesn’t have a key will always let you pass. Use the following steps to add keys to
the world:
(1) Add two fields to the Exit class: key, of type Thing, and message, of type Str. Update the class’s
docstring appropriately. When an Exit is constructed, set its key field to None and its message
field to the empty string.
(2) Change your go method to take the key into account. If an exit doesn’t have a key, the player can
always follow that exit to its destination. If the exit has a key, then the player can use the exit if the
key is in their inventory (in which case they keep the key). If they don’t have the key then the go
command prints the contents of the Exit’s message field, and the player’s location doesn’t change.
(3) We need to modify the text file format for games described in Question 2, to take keys into account.
In addition to the exit lines already described, we allow an additional keyexit, which occupies two
lines in the file. The first line is analogous to ordinary exits: the source and destination rooms of
the exit, and the exit’s name. The second line gives the numeric code of the key that unlocks the
exit, and the text of the message that appears if the player isn’t holding the key. Both types of exits
are legal in a game file. For example:
exit #27 #28 north
keyexit #28 #113 north219 You don’t have a ticket!
exit #28 #27 south
Modify your load function to recognize keyexits and add their information to the World.
5
CS 116 Winter 2019 Assignment 09
Due Friday, April 5 at 6:00 pm (no late submissions)
(4) Modify the save method in the World class so that keyexits are also stored in the saved text file,
in the same format described above.
A second global constant called testworld key is defined for you, which you can use to make sure you’re
using keys correctly.
Note that you do not need to implement this feature in order to receive full marks for the first three
questions on the assignment. We will test your solution to the first three questions on worlds that don’t
have keys.
A note on the design recipe
When you put all of the pieces of this assignment together, you get a large system that is best experienced
interactively. That also affects testing. It’s not very practical to write a large number of small tests for
the methods and functions here; it’s much more natural to test the system by loading, playing, and saving
games. Therefore, for the purposes of this assignment, you are not required to include examples or tests
in your source code. You should experiment extensively with your implementation to make sure it behaves
correctly. You should still include purposes and contracts for any functions you write.
These same restrictions affect the automated testing performed on your submitted assignment. Please
note that the Basic Tests performed when you submit will be especially minimal, and definitely not enough
to ensure that your implementation performs correctly in all situations. It is your responsibility to test your
code until you are confident that it is correct.
As always, you must not share your solution code with other students. However, you are welcome (and
indeed, encouraged) to share your worlds with other students, in the form of the text files defined in
Question 2. You can use other students’worlds for further testing, or just to explore.
WX:codehelp