69
23. Inheritance — How to Think Like a Computer Scientist: Learning with Python 3
http://openbookproject.net/thinkcs/python/english3e/inheritance.html[1/4/2012 9:38:39 PM]
This is the first case we have seen where the initialization method performs a significant computation,
beyond initializing attributes.
To implement specific games, we can inherit from
CardGame and add features for the new game. As an
example, we’ll write a simulation of Old Maid.
The object of Old Maid is to get rid of cards in your hand. You do this by matching cards by rank and
color. For example, the 4 of Clubs matches the 4 of Spades since both suits are black. The Jack of
Hearts matches the Jack of Diamonds since both are red.
To begin the game, the Queen of Clubs is removed from the deck so that the Queen of Spades has no
match. The fifty-one remaining cards are dealt to the players in a round robin. After the deal, all
players match and discard as many cards as possible.
When no more matches can be made, play begins. In turn, each player picks a card (without looking)
from the closest neighbor to the left who still has cards. If the chosen card matches a card in the
player’s hand, the pair is removed. Otherwise, the card is added to the player’s hand. Eventually all
possible matches are made, leaving only the Queen of Spades in the loser’s hand.
In our computer simulation of the game, the computer plays all hands. Unfortunately, some nuances
of the real game are lost. In a real game, the player with the Old Maid goes to some effort to get their
neighbor to pick that card, by displaying it a little more prominently, or perhaps failing to display it
more prominently, or even failing to fail to display that card more prominently. The computer simply
picks a neighbor’s card at random.
23.6.
OldMaidHand class
A hand for playing Old Maid requires some abilities beyond the general abilities of a
Hand. We will
define a new class,
OldMaidHand, that inherits from
Hand and provides an additional method called
remove_matches:
We start by making a copy of the list of cards, so that we can traverse the copy while removing cards
from the original. Since
self.cards is modified in the loop, we don’t want to use it to control the
traversal. Python can get quite confused if it is traversing a list that is changing!
1
2
3
4
class CardGame:
:
def __init__(self):
self.deck = Deck()
self.deck.shuffle()
1
2
3
4
5
6
7
8
9
10
11
12
13
class OldMaidHand(Hand):
def remove_matches(self):
count = 0
original_cards = self.cards[:]
for card in original_cards:
match = Card(3 - card.suit, card.rank)
if match in self.cards:
self.cards.remove(card)
self.cards.remove(match)
print("Hand {0}: {1} matches {2}"
.format(self.name, card, match))
count = count + 1
return count