Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




Chapter 41. Mah Jongg Hands

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.

The three suits are bamboo, “characters” (wan, simplified or traditional), and dots. The ranks are the numbers one to nine.

The winds and dragons are collectively called “honors”. There are four winds: East ( ), South ( ), West ( 西 ), and North ( ). There are three dragons: White ( ), Red ( ), and Green ( ). These tiles don't have ranks, merely names.

In some variations of the game there are also jokers, seasons and flowers. We'll leave these out of our analysis for the moment.

Tile Class Hierarchy

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.


  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.

  Published under the terms of the Open Publication License Design by Interspire