CS21 Lab 11: Classes and Objects
This lab is due Saturday, May 2, before midnight
Goals
-
gain experience writing classes
-
gain experience reading and using classes
This week’s lab is to write an in-terminal version of the Neko Atsumi (Kitty Collector) game. It’s just a simple, fun game (also free if you want to try it on your phone) where you buy items (toys and food) to put in your yard, and sometimes cats come visit your yard!
The game is silly and cute, but also an excellent example of classes and objects. In our version of the game we will have 4 different objects (Item, Cat, Store, Yard). We are giving you two of the classes (Store, Yard). Your job is to write the other two classes (Item, Cat), test code for the Store and Yard classes, and some of the functions in the game implementation.
For reference, game play is a simple menu of choices: see the yard, shop for items, see your cat album (where you keep a record of all cats that have visited your yard), and quit. You also start with a certain amount of money (fishes) to shop with. If you have toys and food in your yard, there’s a chance one or more cats will visit your yard. When cats visit and then leave your yard, they leave you a gift (more fishes).
1. the Item
class
There are a lot of files in this lab. Don’t worry about all of them now. We’ll edit some and just use the others. If you follow the lab writeup, we’ll guide you through which ones to edit and when. The writeup may seem long, but there are only a few files to edit and run.
Start by editing item.py
and writing the Item
class. You can write
and test this object on it’s own. Items can be either food or toys.
Here are the instance variables for an Item
object:
-
name: name of the item (ex: "Rubber Ball" or "Frisky Bitz")
-
cost: how much the item costs (ex: 20)
-
itype: the type of the item ("food" or "toy")
And here are the methods you need to write for the Item
class:
method | description |
---|---|
|
constructor for |
|
should return string representation of object |
|
getter for name of item |
|
getter for cost of item |
|
getter for type of item |
|
setter for cost of item (if we want to change cost) |
|
returns |
|
returns |
For reference, here is a short example of using the Item
class:
item = Item("Meow Mix",20,"food")
print(item)
item.setCost(25)
print(item)
print(item.isFood())
At the bottom of the given item.py file we have already provided
some test code. We suggest running python3 item.py after you implement
each method, even though some of the tests will fail (since you haven’t
written all of the methods yet).
|
For example, after writing the
__init__(…)
and
__str__(self)
methods, you should see something like this (depending on how your
str method formats the item data):
$ python3 item.py Rubber Ball: 60 fishes (toy) Pillow: 120 fishes (toy) Fish Bowl: 80 fishes (toy) Yarn: 120 fishes (toy) Frisky Bitz: 30 fishes (food) Two-tier Cat Tree: 200 fishes (toy) Deluxe Tuna Bitz: 12 fishes (food) Sashimi: 52 fishes (food) Fluffy Brown Bed: 160 fishes (toy) Bean Bag: 120 fishes (toy) Colorful Sock: 20 fishes (toy) White Sock: 22 fishes (toy) Toy Mouse: 75 fishes (toy) Green Box: 5 fishes (toy) Keyboard: 95 fishes (toy) Tape: 15 fishes (toy) Punch Cards: 64 fishes (toy) Cheese Bites: 15 fishes (food) Traceback (most recent call last): File "item.py", line 52, inmain() File "item.py", line 43, in main assert(fakeitem.getName()==name) AttributeError: 'Item' object has no attribute 'getName'
The AttributeError
at the end just means we tried to test the
getName()
method and it failed because you haven’t written it yet.
Once you write getName()
, that test should pass, and you won’t see
an attribute error for getName
. Just continue writing methods and
running the test code until you don’t see any more errors.
Also note: the utils.py
file provides a function called
loadItems(filename)
that reads in items from the items.txt
file.
We will use these for the game.
At this point you should have a working Item class. Do not
proceed unless your Item class is fully written and tested!
|
2. the Cat
class
Next edit cat.py
and write the Cat
class. You can write
and test this object on it’s own, too.
Here are the instance variables for a Cat
object:
-
name: name of the cat (ex: "Pumpkin")
-
description: description of the cat (ex: "Orange Tabby")
-
personality: personality of the cat (ex: "Shy")
-
visits: how many times the cat has visited your yard (initially 0 for all cats)
And here are the methods you need to write for the Cat
class:
method | description |
---|---|
|
constructor for |
|
should return string representation of object |
|
getter for name of cat |
|
getter for description of cat |
|
getter for personality of cat |
|
getter for visits by cat |
|
return random number of fishes (10-50) |
|
add 1 to number of visits by cat |
Notice that the self.visits
instance variable is not used when
creating new Cat
objects. All cats automatically start with zero
visits.
For reference, here is a short example of using the Cat
class:
>>> from cat import * >>> c = Cat("Pumpkin","Orange Tabby","Shy") >>> print(c) Name: Pumpkin Description: Orange Tabby Personality: Shy Visits: 0 >>> c.visited() >>> print(c.getVisits()) 1 >>> print(c) Name: Pumpkin Description: Orange Tabby Personality: Shy Visits: 1 >>> fishes = c.getFishes() >>> print(fishes) 13 >>> fishes = c.getFishes() >>> print(fishes) 29
You can see sample cat data in the cats.txt
file, and
utils.py
has a function to load all cat data and create Cat
objects.
We will use these in the game.
At the bottom of the given cat.py file we have already provided
some test code. We suggest running python3 cat.py after you implement
each method, even though some of the tests will fail (since you haven’t
written all of the methods yet).
Just continue writing methods and
running the test code until you don’t see any more errors.
|
3. the Store
class
We’ve already written this class for you, so you don’t have to change
anything in the class. Look through the class in the store.py
file
to understand a little of how it works. You don’t have to
understand all of the code in the file, but you should at least read the
comments to know what each method does and what it returns (if anything).
To get familiar with the Store objects and methods,
you do need to edit main() and add some test code.
See and follow the instructions in main() to add the test code.
Do not continue with the lab until you have written the test code in
main() of store.py !
|
For reference, here are the Store
class
methods. You will use them in the game.
method | description |
---|---|
|
constructor for |
|
should return string representation of object |
|
getter for how many unique items are in the store |
|
getter for how much an item costs (item specified by number) |
|
given item number, "sell" item (return item object) |
|
add given item to store |
4. the Yard
class
We’ve already written this class for you, too! Like the last class, you also have to write some test code for this one.
Look through the yard.py
file to familiarize yourself with
the available methods and what they each do. Additionally, read the
comment at the top of yard.py
to know how Yard
objects work
in this game. Specifically, you only have so much room in your yard for items,
and cats can’t come to your yard unless there is a free item (one not already
taken by another cat).
See and follow the instructions in main() to add the test code.
Do not continue with the lab until you have written the test code in
main() of yard.py !
|
For reference, here are the Yard
class
methods. You will use some of them in the game.
method | description |
---|---|
|
constructor for |
|
should return string representation of object |
|
add given cat to the yard, if there’s an available item |
|
add item to yard, if there’s space |
|
adds a slot to the yard (expands yard) |
|
return True if yard is empty (no items) |
|
return True if no empty slots in yard |
|
return list of all cats currently in the yard |
|
return True if an item is available for a cat to play with/eat |
|
return number of cats currently in the yard |
|
removes a specific cat from the yard, give the gift of fishes |
|
remove a specific item (i), and possibly a cat, from the yard |
|
check if food has been eaten, remove if yes (and cat), return fishes |
5. write the game functions
In nekoatsume.py
we have already written the main()
function which
includes loading various objects (cats, items, store, yard)
and the game loop. Your job is to complete the program
by writing the four functions called in the game loop.
You can see full examples of the game here:
Your game does not have to look exactly like our examples, but should be clean and easy to follow.
Here are the requirements for the functions you need to write:
5.1. see yard
Just show all items and cats currently in the yard. Hint: this one is easy…don’t overthink it! :)
5.2. shop
Show the items in the store and ask the user which item they want to buy. If the user enters a valid item number, check to see if they have enough money (fishes) to buy the item. If they do, buy the item and add it to the yard. If not, let the user know why they can’t buy that item. Either way, this function should return how many fishes the user now has.
In the example output above, if the user enters 0, they don’t want to buy anything at this time.
Here’s an example, and see the outputs above for others.
You've got 199 fishes... 1. see yard 2. shop 3. cat album 4. quit Your choice? 2 -------------------- Welcome to the cat store! -------------------- Store Inventory: 1. Rubber Ball ( toy) $ 60 fishes 2. Pillow ( toy) $120 fishes 3. Fish Bowl ( toy) $ 80 fishes 4. Yarn ( toy) $120 fishes 5. Frisky Bitz (food) $ 30 fishes 6. Two-tier Cat Tree ( toy) $200 fishes 7. Deluxe Tuna Bitz (food) $ 12 fishes 8. Sashimi (food) $ 52 fishes 9. Fluffy Brown Bed ( toy) $160 fishes 10. Bean Bag ( toy) $120 fishes 11. Colorful Sock ( toy) $ 20 fishes 12. White Sock ( toy) $ 22 fishes 13. Toy Mouse ( toy) $ 75 fishes 14. Green Box ( toy) $ 5 fishes 15. Keyboard ( toy) $ 95 fishes 16. Tape ( toy) $ 15 fishes 17. Punch Cards ( toy) $ 64 fishes 18. Cheese Bites (food) $ 15 fishes Which item do you want to buy? [0 to cancel] 6 You don't have enough fishes for that! :( ======================================== You've got 199 fishes... 1. see yard 2. shop 3. cat album 4. quit Your choice? 2 -------------------- Welcome to the cat store! -------------------- Store Inventory: 1. Rubber Ball ( toy) $ 60 fishes 2. Pillow ( toy) $120 fishes 3. Fish Bowl ( toy) $ 80 fishes 4. Yarn ( toy) $120 fishes 5. Frisky Bitz (food) $ 30 fishes 6. Two-tier Cat Tree ( toy) $200 fishes 7. Deluxe Tuna Bitz (food) $ 12 fishes 8. Sashimi (food) $ 52 fishes 9. Fluffy Brown Bed ( toy) $160 fishes 10. Bean Bag ( toy) $120 fishes 11. Colorful Sock ( toy) $ 20 fishes 12. White Sock ( toy) $ 22 fishes 13. Toy Mouse ( toy) $ 75 fishes 14. Green Box ( toy) $ 5 fishes 15. Keyboard ( toy) $ 95 fishes 16. Tape ( toy) $ 15 fishes 17. Punch Cards ( toy) $ 64 fishes 18. Cheese Bites (food) $ 15 fishes Which item do you want to buy? [0 to cancel] 15 You just bought a Keyboard!
5.3. show cat album
Just show all of the cats that have visited the yard. Here’s an example, and see the outputs above for others.
You've got 199 fishes... 1. see yard 2. shop 3. cat album 4. quit Your choice? 3 .................... Cat Album .................... 1. Sunny (Turkish Calico), visits: 1 2. Mittens (Black & White), visits: 3 3. Snowball (Solid White), visits: 1 4. Bolt (Brown Tabby), visits: 1 ...................................................
5.4. update the yard
This function will "decide" when cats come and go, updating the yard accordingly. We are trying to simulate cats being attracted into a yard by food and toys, so we will include these elements in the program:
-
if there are no items in the yard, no cats will come
-
if there is food in the yard and a cat eats it, the food is gone and that cat will leave (hopefully to go do his/her business in another yard!)
-
if there are items in the yard, cats don’t always come right away
-
if there are cats in the yard playing with toys, they might get bored and leave the yard
Here is one way to structure your update function:
-
if the yard is empty, nothing happens (nothing to update)
-
if there are cats paired with food items, calling the
updateFood()
yard method should remove the food item and the cat that ate the food (no point sticking around if the food is gone!). Note: this method will return fishes if a cat leaves, so make sure to update the user’s fishes -
if there are cats in the yard (see the yard methods for this), there should be a random chance one leaves the yard. If a cat does leave it will give the user fishes, so make sure to update the user’s fishes. Note: it doesn’t matter which cat leaves. Just pick one to leave from the list of cats currently in the yard
-
if there is an available item in the yard (ie, there’s an item, and no cats are already playing with it or eating it), there’s a random chance a cat comes into the yard. If a cat does come into the yard, add it to the cat album (if not already in the album) and update the cat’s visited instance variable
All of the above should be done with each update. You are welcome to break the update up into more functions if you want.
The updates require you to use Yard
and Cat
methods, as well as a
function from the
random
library. If you are stuck on how to implement
something, try looking through the Yard
and Cat
classes for a useful
method (or two).
For the "random chances", you are free to pick numbers that make the game interesting. Also, if a cat is coming into the yard, don’t worry about picking a cat that is not already in the yard. We can have magical cat clones in this game — just pick a random cat from the original list of cats and add it to the yard.
Here’s an example of a yard before and after the update function is called. In this example, the two cats eating food both leave, and Tabitha decides to stay and keep playing with the Fish Bowl. Also, no new cats come into the yard this time.
--------------------YARDYARDYARDYARDYARDYARD-------------------- Here's your yard: 1. Frisky Bitz, AdaLoveyarn 2. Fish Bowl, Tabitha 3. Frisky Bitz, Snowball 4. Cheese Bites 5. --------------------YARDYARDYARDYARDYARDYARD-------------------- <<<<< AdaLoveyarn left the yard and gave you 12 fishes! <<<<< Snowball left the yard and gave you 37 fishes! ======================================== You've got 82 fishes... 1. see yard 2. shop 3. cat album 4. quit Your choice? 1 --------------------YARDYARDYARDYARDYARDYARD-------------------- Here's your yard: 1. Fish Bowl, Tabitha 2. Cheese Bites 3. 4. 5.
6. enjoy the game! :)
Try running the game. Buy some items and see if any cats come to visit.
Test all of the user options and make sure they all work. If you want,
add your own cat to the cats.txt
file.
7. Extra Challenges
These will not affect your grade or gain you extra points. They are included just as extra challenges, if you are interested (and have already finished the entire game).
-
allow the user to have more items than the yard can hold, and sometimes change the items in the yard (so the cats don’t get bored with the same 5 items)
-
allow the user to expand the yard for a certain number of fishes (ie, add a special store item that increases the number of slots in the yard)
-
add an extra cat instance variable that determines how likely a cat is to enter the yard. For example, for low values the cat would be rare, and come to the yard less than others, but give more fishes to the user if they do come to the yard
-
allow the user to buy more than one of an item at a time:
Which item do you want to buy? [0 to cancel] 8 How many would you like? 2 You just bought 2 Sashimi!
-
save the yard data when the user quits and load it back up again (same items, yard) the next time the game is run
-
make the album it’s own object, instead of a python list
-
use Zelle graphics to visualize your cats and display the shop and album
8. Answer the Questionnaire
Please edit
the Questions-11.txt
file in your cs21/labs/11
directory
and answer the questions in that file.
Once you’re done with that, run handin21
again.
Turning in your labs….
Remember to run handin21
to turn in your lab files!
You may run handin21
as many times as you want. Each time it will
turn in any new work. We recommend running handin21
after
you complete each program or after you complete significant
work on any one program.