On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions

## Set Class Hierarchy

A winning Mah Jongg hand has five scoring sets exactly one of which is a pair. There are four varieties of set: pair, three of a kind, three in a row of the same suit, and four of a kind. The most common winning hands have 14 tiles: 4 sets of three and a pair. Each four of a kind extends the hand by one tile to accomodate the larger set.

A Mah Jongg `Hand` object, then, is a list of `Tile`s. This class needs a method, `mahjongg` that returns `True` is the hand is a winning hand. The evaluation is rather complex, because a tile can participate in a number of sets, and several alternative interpretations may be necessary to determine the appropriate use for a given tile.

Consider a hand with 2, 2, 2, 3, 4 of bamboo. This is either a set of three 2's and a non-scoring 3 and 4, or it is a pair of 2's and a sequence of 2, 3, 4.

The `mahjongg` method, then must create five `Set` objects, assigning individual `Tile`s to the `Set`s until all of the `Tile`s find a home. The hand is a winning hand if all sets are full, there are five sets, and one set is a pair.

We'll cover the design of the `Set` classes in this section, and return to the design of the `Hand` class in the next section.

We can create a class hierarchy around the four varieties of `Set`: pairs, threes, fours and straights. A `PairSet` holds two of a kind: both of the tiles have the same name or the same suit and rank. A `ThreeSet` and `FourSet` are similar, but have a different expectation for being full. A `SequenceSet` holds three suit tiles of the same suit with adjacent ranks. Since we will sort the tiles into ascending order, this set will be built in ascending order, making the comparison rules slightly simpler.

We'll define a `Set` superclass to hold a sequence of `Tile`s. We will be able to add new tiles to a `Set`, as well as check to see if a tile could possibly belong to a `Set`. Finally, we can check to see if the `Set` is full. The superclass, `Set`, is abstract and returns `NotImplemented` for the `full`. The sublasses will override this methods with specific rules appropriate to the kind of set.

```class
Set
:
`  def __init__(self):`

`  def __str__(self):`

```  def canContain(self,
aTile
):```

```  def add(self,
aTile
):```

`  def full(self):`

```  def fallback(self,
tileStack
):```

`  def pair(self):`
```
• The `Set` `__init__` function should create an internal list to store the tiles.

• The `add` method appends the new tile to the internal list. A pop function can remove the last tile appended to the list.

• The superclass `canContain` method returns `True` if the list is empty; it returns `False` if the list is full. Otherwise it compares the new tile against the last tile in the list to see if they are equal. Since most of the subclasses must match exactly, this rule is what is used. The straight subclass must override this to compare suit and rank correctly.

• The superclass `fallback` pushes all of the tiles from the `Set` back onto the given stack. The superclass version pushes the tiles and then returns `None`. Each subclass must override this to return a different fallback Set instance.

• The superclass `pair` returns `False`. The `PairSet` subclass must override this to return `True`.

An important note about the `fallback` is that the stack that will be given as an argument in `tileStack` is part of the `Hand`, and is using is maintainted by doing `tileStack.pop(0)` to get the first tile, and `tileStack.insert( 0, aTile )` to push a tile back onto the front of the hand of tiles.

We'll need the following four subclasses of `Set`.

• `FourSet`Specializes `Set` for sets of four matching tiles. The `full` method returns `True` when there are four elements in the list. The `fallback` method pushes the set's tiles onto the given `tileStack`; it returns a new `ThreeSet` with the first tile from the `tileStack`.

• `ThreeSet`Specializes `Set` for sets of three matching tiles. The `full` method returns `True` when there are three elements in the list. The `fallback` method pushes the set's tiles onto the given `tileStack`; it returns a new `SequenceSet` with the first tile from the `tileStack`.

• `SequenceSet`Specializes `Set` for sets of three tiles of the same suit and ascending rank. The `belongs` returns `True` for an empty list of tiles, `False` for a full list of tiles, otherwise it compares the suit and rank of the last tile in the list with the new tile to see if the suits match and the new tile's rank is one more than the last tile in the list. The `full` method returns `True` when there are three elements in the list. The `fallback` method pushes the set's tiles onto the given `tileStack`; it returns a new `PairSet` with the first tile from the `tileStack`.

• `PairSet`The `full` method returns `True` when there are two elements in the list. The `fallback` method is inherited from the superclass method in `Set`; this method returns None, since there is no fallback from a pair. This subclass also returns `True` for the `pair` method.

The idea is to attempt to use a `FourSet` to collect a group of tiles. If this doesn't work out, we put the tiles back into the hand, and try a `ThreeSet`. If this doesn't work out, we put the tiles back and try a `SequenceSet`. The last resort is to try a `PairSet`. There is no fallback after a pair set, and the hand cannot be a winner.

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