Lab 08: OOP
Due at 11:59pm on 07/16/2015.
Starter Files
Download lab08.zip. Inside the archive, you will find starter files for the questions in this lab, along with a copy of the OK autograder.
Submission
By the end of this lab, you should have submitted the lab with
python3 ok --submit
. You may submit more than once before the
deadline; only the final submission will be graded.
To receive credit for this lab, you must complete the following:
- Unlock Question 1 (What would Python print?)
- Complete Questions 2 in
data.py
- Complete Questions 3, 4, and 5 in
classses.py
In this lab, you will use Object-oriented programming (OOP) — a style of programming that allows you to think of code in terms of "objects" — to build a text-based adventure game!
Prologue
It's the day of the CS 61A potluck, and Robert needs to buy food for the potluck. It would be really convenient if he could drive a car; after all, there's a lot of food to carry!
In car.py
, you'll find a class called Car
. Remember that a class is a
blueprint for how to create objects of that type; in this case, the Car
class
tells us how to to create create Car
objects.
Let's build Robert a car. Don't worry, you won't need to do any physical work,
the constructor will do it for you. A class's constructor is a function
that builds an instance of the class. In Python, the constructor is called the
__init__
. There must be two underscores on each side of init
. The Car
class's constructor looks like this:
def __init__(self, model_type):
self.wheels = Car.num_wheels
self.color = "No color yet. You need to paint me."
self.model = model_type
Let's make our car. First, open up the Python interpreter and load car.py
:
python3 -i car.py
Robert would like to drive a Tesla. Try constructing an instance of the Car
class with the following::
roberts_car = Car("Tesla")
An object is an instance of a class. In this case,roberts_car
is an
instance of the Car
class.
That's cool and all, but what color is my car?
We'll use an attribute of the class. An attribute is a quality of the
object: cars have wheels and color, so we have given our Car
class
self.wheels
and self.color
attributes. We can access attributes using dot
notation. What does the following print in the interpreter?
roberts_car.color
Look's like we need to paint it.
Let's use the paint
method. Methods are functions that are bound to an
object. Think of methods as "verbs" of the class. Cars can drive so we have
given our Car
class the method drive
. Try out the following in the
interpreter:
roberts_car.paint("Black")
roberts_car.color
Awesome! But why don't I need to input two arguments? The car constructor should
take in self
and model
, but I only passed in model
, and it worked. Why?
In Python, the dot notation implicitly passes in roberts_car
as self
.
When a method is called, self
is bound to an instance of the class.
Question 1: What would Python print?
Use OK to test your knowledge with the following What would Python print questions:
python3 ok -q car -u
>>> roberts_car = Car("Tesla")
>>> roberts_car.model
______'Tesla'
>>> Car.headlights
______2
>>> roberts_car.headlights
______2
>>> Car.headlights = 3
>>> roberts_car.headlights
______3
>>> roberts_car.headlights = 2
>>> Car.headlights
______3
>>> roberts_car.wheels = 2
>>> roberts_car.wheels
______2
>>> Car.num_wheels
______4
>>> roberts_car.drive()
______'Tesla cannot drive!'
Variables
Before you enter Soda! You must take this chart with you...
With OOP be aware of three types of variables:
Notice: Local variables has two examples
Instance Attributes | Class Attributes | Local Variable | |
---|---|---|---|
Traits | - Will be accessible after method calls. - Each instance of a class keeps its own version of the instance attribute |
- Will be accessible after method calls. - All instances of a class will share the same class attributes. |
- Will not be accessible after method or function calls. - Just like the variables in normal functions. |
Examples |
|
|
|
Explanations |
We construct two Car instances. Each has its own
self.color instance attribute/variable. One is
'red' , and the other is 'blue' .
|
num_wheels is a class attribute of the Car class.
|
model_type is a local variable. It is not accessible
outside of the __init__ method. In contrast,
self.model is an instance variable that is accessible
everywhere. x is also a local variable.
|
Note: Access class attributes by <class name>.<attribute>
, such as
Car.num_wheels
, or by <instance>.<attribute>
, such as car1.num_wheels
.
Adventure Game!
In this lab, you will implement a text adventure game. To start the game, type
python3 adventure.py
The ZIP archive provided at the start of lab contains all the starter code. All
of your changes will be made to classes.py
, although you have to create
yourself as a player in data.py
before implementing anything else.
classes.py
: Implementation for classes used in the gamedata.py
: All of the objects used in the gameadventure.py
: Interpreter of the game
Question 2: Who am I?
It is time for you to enter a world of adventure! First, you need to create
yourself as a Player
object in data.py
. Take a look at the Player
class in
classes.py
and create a Player
object at the bottom of data.py
.
The Player
constructor takes two arguments:
name
should be your preferred name (as a string)- the starting
place
Your Player
should start at sather_gate
.
# Player:
# The Player should start at sather_gate.
me = None
me = Player('Sally', sather_gate)
Question 3: Where do I go?
Once you've created your player, you can start the adventure game:
python3 adventure.py
You will see the following output:
Welcome to the adventure game!
It's a bright sunny day.
You are a cute little squirrel named [your name],
wandering around Berkeley campus looking for food.
Let's go to FSM (Free Speech Movement Cafe)
and see what we can find there!
There are 6 possible commands:
talk to [character]
help
take [thing]
go to [direction]
look
check backpack
adventure>
First, we need to be able to go to places. If you try the go
command, you'll
notice it doesn't do anything.
In classes.py
, implement the go_to
method in the Player
class. go_to
takes in
a direction
that you want to go to.
Hint: The
exit_to
method inPlace
will return the correspondingPlace
object ifdirection
is among your available exits. Otherwise,exit_to
will return the currentPlace
. Take a look at the doctest for more details.
def go_to(self, direction):
"""Go to direction if it's among the exits of player's current place.
>>> sather_gate = Place('Sather Gate', 'You are at Sather Gate', [], [])
>>> gbc = Place('GBC', 'You are at Golden Bear Cafe', [], [])
>>> sather_gate.add_exits([gbc])
>>> gbc.add_exits([sather_gate])
>>> me = Player('player', sather_gate)
>>> me.go_to('GBC')
You are at Golden Bear Cafe
>>> me.place.name
'GBC'
>>> me.go_to('GBC')
Can't go to GBC from GBC.
Try looking around to see where to go.
>>> me.go_to('Sather Gate')
You are at Sather Gate
"""
"*** YOUR CODE HERE ***"
self.place = self.place.exit_to(direction)
Use OK to test your code:
python3 ok -q go_to
Question 4: How do I talk?
Now you can go wherever you want! Try going to Wheeler Hall. There, you'll find
Derrick. Try talking to him with the talk to
command. This also doesn't work
:(
Next, implement the talk_to
method in Player
. talk_to
takes in the name of
a Character
object, and prints out the Character
's response. Take a look at
the doctest for more details.
Hint:
talk_to
takes in an argumentperson
, which is a string. Thecharacters
instance attribute inself.place
is a dictionary mappingCharacter
names (strings) toCharacter
objects.Once you've got the
Character
object, what method in theCharacter
class will make them talk?
def go_to(self, direction):
"""Go to direction if it's among the exits of player's current place.
>>> sather_gate = Place('Sather Gate', 'You are at Sather Gate', [], [])
>>> gbc = Place('GBC', 'You are at Golden Bear Cafe', [], [])
>>> sather_gate.add_exits([gbc])
>>> gbc.add_exits([sather_gate])
>>> me = Player('player', sather_gate)
>>> me.go_to('GBC')
You are at Golden Bear Cafe
>>> me.place.name
'GBC'
>>> me.go_to('GBC')
Can't go to GBC from GBC.
Try looking around to see where to go.
>>> me.go_to('Sather Gate')
You are at Sather Gate
"""
"*** YOUR CODE HERE ***"
self.place = self.place.exit_to(direction)
Use OK to test your code:
python3 ok -q talk_to
Question 5: How do I take items?
Now you can talk to people in adventure world! To make it even better, let's
implement the take
method in the Player
class. take
takes in a Thing
object and puts it into your backpack
. Currently, you don't have a backpack,
so let's create an instance variable backpack
and initialize it to an empty
list.
After you've done initialized your empty backpack
, take a look at the doctests
for take
and implement the method.
Hint: the
things
instance attribute in thePlace
class is a dictionary that mapsThing
names (strings) toThing
objects.The
take
method in thePlace
class will also come in handy.
def take(self, thing):
"""Take a thing if thing is at player's current place
>>> hotdog = Thing('Hotdog', 'A hot looking hotdog')
>>> gbc = Place('GBC', 'You are at Golden Bear Cafe', [], [hotdog])
>>> me = Player('Player', gbc)
>>> me.backpack
[]
>>> me.take(hotdog)
Thing should be a string.
>>> me.take('dog')
dog is not here.
>>> me.take('Hotdog')
Player takes the Hotdog
>>> me.take('Hotdog')
Hotdog is not here.
>>> type(me.backpack[0])
<class '__main__.Thing'>
"""
if type(thing) != str:
print('Thing should be a string.')
return None # Replace this line
elif thing not in self.place.things:
print(thing, 'is not here.')
else:
taken = self.place.take(thing)
print(self.name, 'takes the', taken.name)
self.backpack.append(taken)
Use OK to test your code:
python3 ok -q take
Question 6: Win the game!
Good job! Now you can explore around campus and try to win the game. Talk to the people at different places in order to get hints. Can you save the day and make it to the 61A potluck in time?
Enjoy!