- Design due Oct 21
- Partially Working version Oct 26
- Complete Version Nov 4
Goals
- To learn how to process XML by creating a text adventure game like Zork.
- To design a object oriented system with UML
- To design build a system with many interacting class.
- Working with a large, somewhat complex, code base.
- To have fun creating your own text adventure.
Class Design using UML
You should design your classes using UML – Unified Modeling Language. You start by reviewing your system, looking for things in the game (e.g. nouns) and for actions in the game (e.g. verbs). Generally the nouns will become classes (rooms, items, creatures), and the verbs will become methods on the classes (move, attach, look, read).
We specify graphically the design of a class with a box with three parts. At the top of a class box is a descriptive name. In the middle box is a list of all class attributes (variables, arrays, etc) with their types. In the lower box are all the methods on the class (including their parameters). The + or – before means public (+) or private (-). (# is protected, which only some languages like Java have).

You should show all parameters for each method:

And classes are connected with lines showing relationships between the classes. These lines should be named with descriptions.
- Association – a simple line means two classes are associated. For example a room is associated with the items it contains.
- Aggregation – a line with a filled diamond on one end means one class contains other things. For example a room contains one or more creatures. The filled diamond is on the container side (the room in this case).
- Composition – a line with a hollow diamond on one end means a object is made of other things. The hollow diamond is on the side of the class that is made of the other objects. For example, a room is made of borders (among other things). The difference between aggregation and composition is that in composition the contained items depend on the container class. If a room disappears, so does the borders (composition), but not the items in the room (aggregation). Another example is a car – it is made of 4 tires (composition) and may have several people in it (aggregation). It ‘s not a car without the wheels, but is a car with or without the people.
- Inheritance – an arrow with a pointer means the pointed at class is the super class. If you have had Data Structures you know what this is. Otherwise I don’t expect you to use it (unless you learned it elsewhere)

Notes:
- A player blocks another player. This is simple association.
- A play throws a ball. This is also an association, one class using another.
- A player has a list or array of game stats. This is composition. The stats are part of the player.
- A game is made of many players. This is aggregation. The players don’t need to game to exist.
Class methods
As mentioned above, generally classes are noun, and actions are verbs. Thus I would expect to see a class for every noun in the game world, and a method in a class for every verb or action.
Introduction to Zork
For this assignment you will create a program for a game like Zork. Zork was one of the first interactive role-playing, text based adventure computer games. You can play it here: https://classicreload.com/zork-i.html
You will your own text game engine which will be able to read as input a game XML file with complete information of a specific adventure and create the set of objects to interact with the player in that environment.
This specification is purposely given “as it is”. If anything is incomplete, inconsistent, or incorrect, please explain your interpretation or improvement of the specification in a document that you turn in with your assignment.
One of the goals of this assignment is to provide you with an opportunity to learn how to handle an imperfect specification, as all specifications are eventually found to be.
Aou may ask the course instructor about what things mean, and you may discuss any part of this assignment with your classmates or others, including tools, algorithms, what a pain it is, and so forth. You must write your own code however — code sharing is strictly forbidden.
You can find a simple start of the game in Python here: http://jimskon.com/class/softdev/skon/zork/zork.html
I have created 3 versions of this starting code:
- C++: https://github.com/jimskon/ZorkCppStart
- Python: https://github.com/jimskon/ZorkPyStart
- Javascript (Web based): https://github.com/jimskon/ZorkJSStart
The C++ and Python version can be run on the console, or from a web page. It uses a background server when running from the web since the game is “stateful”, e.g. it must remember where you are between moves.
I did all the hard work of getting the web and client/server running for the Python and C++ version. You can mostly focus on the game. One issue you do have to deal with is multiple players at the same time. This is not a problem for the Javascript version (since the state is on he browser).
This includes starting XML. TheXML
Basic Commands in the game (you may add more):
- go (dir) – movement commands to put the player in a different room. Directions can be anything, typically north, south, east, west, up, down. If a room is bordered in the direction indicated, the description of the new room is to be printed to the screen. Otherwise print “Can’t go that way.”
- i – short for “inventory”, lists all items in the player’s inventory separated by commas (if more than one). If there are no items in the inventory, print “Inventory: empty”.
- take (item) – changes item ownership from room or container to inventory. If successful print “Item (item) added to inventory”. (Hint: this can be written as shortcut for put command)
- open (container) – prints contents of container in format “(container) contains (item), (item), …” and makes those items available to pick up. If empty, should output “(container) is empty.”
- read (item) – prints writing on object if any available, else prints “Nothing written.” if command is executed on an existing item in the player’s inventory that does not contain writing.
- drop (item) – changes item ownership from inventory to present room and prints “(item) dropped.”
- put (item) in (container) – changes item ownership from inventory to declared container if container is open and prints “Item (item) added to (container).”
- turn on (item) – activates item if in inventory printing “You activate the (item).” and executing commands in “turnon” element.
- attack (creature) with (item) – prints “You assault the (creature) with the (item).” and executes “attack” elements if item matches creature’s “vulnerability” and existing conditions are met.
Behind the Scenes operation
You should write code to support these. Remember – keep things simple, make this functionally cohesive!
- Add (object) to (room/container) – creates instance of object with specific owner (does not work oninventory)
- Delete (object) – removes object references from game, but item can still be brought back into the game through the ‘Add’ command. Rooms will have references to them as ‘borders’ removed, butthere is no means at present for adding a room back in.
- Update (object) to (status) – creates new status for object to be checked by triggers
- Game Over – ends game with a declaration of “Victory!”
Order of Operations
When the user enters a command:
- Check if command is overwritten by any triggers.
- Execute command if not overwritten.
- Check if effects of command activate a trigger.
- If so, continue to check if new status effects activate additional triggers ad infinitum.
Objects
If element is followed by [ ] there may be multiple objects.
- Room – may contain the following elements: name, status, type, description, border[ ], container[ ], item[ ], creature[ ], trigger[ ]. Type is assumed ‘regular’ unless specified.
- Item – may contain name, status, description, writing, status, turn on, and trigger[ ]. If item has turn on element and “turn on” command is issued by user, action elements in ‘turn on’ are to be executed if any given conditions are met.
- Container – may contain name, status, description, accept[ ], item[ ], trigger[ ]. If an ‘accept’ element is added, only specific items may be put into the container and the container need not be opened to insert them (cannot be opened until one of those items is inserted, in fact).
- Creature – may contain name, status, description, vulnerability[ ], attack, trigger[ ]. If “attack” command is issued by user with creature’s vulnerability, action elements in ‘attack’ are to be executed if any given conditions are met.
Special “Objects”
- Triggers – contains one or more condition including special conditions of type command (all of which need to be satisfied for the corresponding actions to take place), type, one or more print, and one or more action. Type is assumed to be ‘single’ (only used once) unless specified as ‘permanent’ (unlimited use). Order of execution is to output any ‘print’ action first, then other ‘action’ commands in the order given in the file.
- Possible conditions: owner, status
- Possible commands are any user command, recognized for the entire string (i.e. take sword). The trigger will pass the ‘command’ portion of of it’s condition if there is no command element or if any one of the command element’s contents are matched.
- Owner – will have object, has, and owner elements. Status – will have object and status elements.
- Also, context is very important. Only triggers in the present context of the game should be checked. This includes the inventory, the present room, and any items, containers, creatures, and items in containers in the present room. The actions those triggers perform, however, can act on any object in the game.
Multiplayer support (Python and C++) for students with Data Structures.
I have added a variable to he Python and C++ for “gameId”. This is to allow you to host several separate sessions at once. This will require the server to create multiple session (e.g. have multiple “game” objects. The Javascript code should present a unique (random?) gameID at start of game, and pass it in for everymove. If you have only had Intro you don’t need to add this feature.
Scoring (for students with Data Structures)
If you are doing the Javascript version, you will need to add the a accumulating game score. Each tme the play does something right, it increases, and if they do something wrong, it decreases. The goal for players is the get the highest score. (This is added for
XML Formatting
Root element:
Each type of object will have elements associated with their given descriptions above with the addition of a ‘name’ element.
Triggers will have the additional complexity of containing a condition and action elements, with the condition having three additional elements to create an ‘if’ statement of the form “if (object) is/isn’t in (owner)” with the is/isn’t being determined by the element.
Grading for Part One (Design)
Give a complete Object Oriented Design, using Lucidchart. Include all data structures for storing game data.
| Requirement | Intro Points | DS Points | Comments | Score |
| Class diagrams for each class | 20 | 20 | ||
| Specification of variables in each class | 20 | 20 | ||
| Specification of each method in each class (name, funciton, parameters) | 20 | 15 | ||
| Diagram showing and explaining relationships amoung classes (composition, interaction, inheritance) | 20 | 15 | ||
| Explainations of any data structures to be used | 20 | 15 | ||
| Multiplayer support design (C++ or Python), or game scoring design (JavaScript) | 15 | |||
| Total | 100 | 100 |
Grading for Part 2 – Partial Functionality
An working implementation of the Object Oriented Design
The system must fully support at least 5 of the 10 basic game commands:
- go
- i
- take (item)
- open (container)
- open exit
- read (item)
- drop (item)
- put (item) in (container)
- turn on (item)
- attack (creature) with (item)
The game should have support for all 4 object types:
- Room, Item, Container, CreatureYou should have XML to support at least 3 rooms, and three of each kind of object.
Grading On complete Game (total 200 points)
Final Function (100 points)
I will ask you do demo these actions on your program during the time you set up to do this.
| Requirement | Intro Points | DS Points | Comments | Score |
| rooms – movement between entrance, regular room(s), and exit | 24 | 20 | ||
| items – take/drop, read, turn on, and add/remove | 24 | 20 | ||
| containers – take, put in, open, restrictions (accepts element) | 16 | 14 | ||
| creatures – attack and add/remove | 8 | 8 | ||
| triggers – permanence and activation with each other object type | 28 | 23 | ||
| Multiplayer support (C++ or Python), or game scoring (JavaScript) | 15 | |||
| Total | 100 |
Final Design (100)
| Requirement | Points | Comments | Score |
| Complete class implementation – should completely impliment you class design | 25 | ||
| Functionally modular. Functions should be concise with a single cohesive operation. | 25 | ||
| Commenting: Headers on all functions, commenting in code as useful. | 10 | ||
| Good Variable Names/Function names | 10 | ||
| Complete. Must have 10 rooms, 12 items, 5 containers, 5 creatures, 8 triggers. | 30 | ||
| Total | 100 |
NOTES
Commands should not be case sensitive.
Triggers always take precedence over default actions, and are only relevant in their given contexts (ie trigger associated with a room should not be tested if player is not in that room). When testing for triggers, test only triggers of objects in your present context (present room, objects in present room, objects in containers in present room, inventory), however, they can affect any object in the map.
Initial room will always be named “Entrance”.
If an error message is not specified, the general error message is “Error”.
