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/games/play/5zyoqrsugeopel3ffhz_vq
http://textadventures.co.uk/games/play/3cbedqimquselmanehhzxg
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.(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.(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).
3. (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.(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.(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.
- 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
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.(1) Add two fields to the Exit class: key, of type Thing, and message, of type Str. Update the class’s doc string appropriately. When an Exit is constructed, set its key field to None and its message field to the empty string.
2.(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.(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:
4.exit #27 #28 north
5.key exit #28 #113 north
6.#219 You don’t have a ticket!
7.exit #28 #27 south
Modify your load function to recognize key exits and add their information to the World. 5
(4) Modify the save method in the World class so that key exits 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.
版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。