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.