The game of Mah Jongg is played with a deck of tiles with three
suits with ranks from one to nine. There are four sets of these 27 tiles.
Additionally there are four copies of the four winds and three dragons.
This gives a deck of 136 tiles.
In some variations of the game there are also jokers, seasons and
flowers. We'll leave these out of our analysis for the moment.
We can define a parent class of Tile, and
two subclasses: SuitTile and
HonorTile. These have slightly different
attributes. The SuitTile has suit and rank
information. The HonorTile merely has a unique
name. The comparison function, __cmp__, must
compare self.getName to
other.getName to see if the other tile has the same
name. Additionally, SuitTile objects should
return a suit and rank information. Honors tiles should return None for
these methods.
We'll define Tile as an abstract
superclass. Some of the methods in the superclass will
either raise NotImplementedError or
return NotImplemented. The superclass can provide any
common functions that are shared by all of the subclasses. Each subclass
will provide overriding method definitions that actually do useful work
and are specialized for that particular family of tiles.
class
Tile
:
def __init__(self,
name
):
def __str__(self):
def __cmp__(self,
other
):
def getSuit(self):
def getRank(self):
def getName(self):
For HonorsTile,
getSuit and getRank must
return None. However, for
getSuit, it should return the tile's name. The
__cmp__ is inherited from the superclass.
For SuitTile, getSuit
and getRank return the proper suit and rank values.
However, for getName, it should return
None. The function __cmp__
function must compare self.getSuit to
other.getSuit; if those are equal, it must compare
self.getRank to other.getRank.
In the case of matching suit, it can compare the ranks, which will tend
to put the suit tiles into order properly.
Note that we defined the Tile superclass
with a name attribute. We can use this to keep the
suit information for SuitTile. We must be sure,
however, that getName returns
None, not the suit.
Also, if we use the names "Bamboo",
"Character" and "Dots", this makes
the suits occur alphabetically in front of the honors without any
further special processing. If, on the other hand, we want to use
Unicode characters for the suits, we should add an additional sort key
to the Tile that can be overridden by
SuitTile and HonorsTile to
force a particular sort order.
Note that the ranks of one and nine have special status among the
suit tiles. These are called terminals, ranks two through eight are
called simples. Currently, we don't have a need for this
distinction.
Build The Tile Class Hierarchy. First, build the tile class hierarchy. This includes the
Tile, SuitTile,
HonorTile classes. Write a short test that will
be sure that the equality tests work correctly among tiles.