Documentation ¶
Overview ¶
Package mj contains types and tools for working with the game of Mahjong.
It contains data types and structures that can represent tiles and collections of tiles. It also contains hand optimisers that finds the optimal grouping of tiles into sets.
All types have sensible zero values representing an empty hand, and the methods will behave accordingly. However, with the exception of Hand, the types are also immutable once declared and the (exported) methods will not mutate their receivers or cause aliasing.
Index ¶
- Constants
- type CountEntry
- type Counter
- func (c Counter) Copy() Counter
- func (c Counter) Entries() []CountEntry
- func (c Counter) ForEach(f func(t Tile, n int) bool)
- func (c Counter) Get(t Tile) int
- func (c Counter) Len() int
- func (c Counter) Map() map[Tile]int
- func (c Counter) Marshal() string
- func (c Counter) Remove(t Tile) Counter
- func (c Counter) String() string
- func (c Counter) ToHand(sorted bool) Hand
- func (c Counter) TryChi(t Tile) (Counter, bool)
- func (c Counter) TryPair(t Tile) (Counter, bool)
- func (c Counter) TryPeng(t Tile) (Counter, bool)
- func (c Counter) Valid() bool
- type Group
- type Hand
- func (h Hand) Append(t Tile) Hand
- func (h Hand) ForEach(f func(int, Tile) bool)
- func (h Hand) IsChi() bool
- func (h Hand) IsPair() bool
- func (h Hand) IsPeng() bool
- func (h Hand) Len() int
- func (h Hand) Less(i, j int) bool
- func (h Hand) Marshal() string
- func (h Hand) Remove(i int) Hand
- func (h Hand) Split(sorted bool) map[Suit]Hand
- func (h Hand) String() string
- func (h Hand) Swap(i, j int)
- func (h Hand) ToCount() Counter
- func (h Hand) TryChiAt(i int) (Hand, bool)
- func (h Hand) TryPairAt(i int) (Hand, bool)
- func (h Hand) TryPengAt(i int) (Hand, bool)
- func (h Hand) Valid() bool
- type HandRLE
- func (h HandRLE) Copy() HandRLE
- func (h HandRLE) Entries() []CountEntry
- func (h HandRLE) ForEach(f func(int, CountEntry) bool)
- func (h HandRLE) Get(t Tile) int
- func (h HandRLE) Len() int
- func (h HandRLE) Marshal() string
- func (h HandRLE) String() string
- func (h HandRLE) TryChiAt(i int) (HandRLE, bool)
- func (h HandRLE) TryPairAt(i int) (HandRLE, bool)
- func (h HandRLE) TryPengAt(i int) (HandRLE, bool)
- func (h HandRLE) Valid() bool
- type Suit
- type Tile
- type Value
Constants ¶
const NumTiles = 4*NumUniqueMeldingTiles + 8
const NumUniqueMeldingTiles = 3*9 + 7
The number of unique melding tiles in the game.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CountEntry ¶
CountEntry is a pair of a Tile and its count.
type Counter ¶
type Counter struct {
// contains filtered or unexported fields
}
Counter is a counter of tiles. It is an alternative unordered representation of Hand. It offers constant-time lookup of tile counts. However creating and modifying it is more expensive. The methods of Counter are guaranteed not to mutate the struct or cause memory aliasing.
You can bypass the methods of Counter by converting to a map[Tile]int with Counter.Map(), modifying the map, and passing it to NewCounter(), which will also verify your map.
func NewCounter ¶
NewCounter creates a new Counter from a map of tiles to their counts.
func NewCounterAtStart ¶
func NewCounterAtStart() Counter
func (Counter) Entries ¶
func (c Counter) Entries() []CountEntry
Entries returns all tile-count pairs in the Counter.
Warning: CountEntry.Count is int16, not int. This means the maximum count for a tile is 32767. If you really need to count more tiles than that, use Get() instead.
func (Counter) ForEach ¶
ForEach calls f(tile, count) for each tile-count pair. Unlike HandRLE.ForEach(), this doesn't seem to give us significant gains in efficiency.
func (Counter) Map ¶
Map returns a map of Tiles to their counts in the Counter. It is the inverse of NewCounter(). This map is a copy, so changes to the Counter won't be reflected in this map, or vice versa.
func (Counter) Marshal ¶
Marshal returns a space-efficient encoding of this Counter. It is suitable for comparison, because the output is always sorted in the same order.
func (Counter) Remove ¶
Remove deep-copies this Counter and removes a tile from it. It panics if the tile isn't in the counter.
func (Counter) String ¶
String returns the human-readable representation of this Counter. The caveats of Hand.String() apply here, with one additional: the order of tiles is undefined, but the same tiles will appear together.
func (Counter) ToHand ¶
ToHand converts this Counter to a Hand. If sorted is true, the hand is guaranteed to be in sorted order.
func (Counter) TryChi ¶
TryChi attempts to form a chi with the given tile as the first in the set. If it succeeds, it returns a new Counter with one of each of the given tile, the next tile, and the one after that, all removed. Otherwise, it returns (a zero Counter, false).
For example: (not the real syntax)
Counter{B1:1 B2:2 B3:1 B4:1}.TryChi(B1) -> Counter{B2:1 B4:1}
Note that one B1, one B2 and one B3 were removed.
It is possible to return (zero Counter, true) if the 3 tiles to be removed are the only tiles in the original Counter.
func (Counter) TryPair ¶
TryPair attempts to form a pair with the given tile. If it succeeds, it returns (a new Counter with the pair removed, true). Otherwise, it returns (a zero Counter, false).
It is possible to return (zero Counter, true) if the 2 tiles to be removed are the only tiles in the original Counter.
func (Counter) TryPeng ¶
TryPeng attempts to form a peng with the given tile. If it succeeds, it returns (a new Counter with the peng removed, true). Otherwise, it returns (a zero Counter, false).
It is possible to return (zero Counter, true) if the 3 tiles to be removed are the only tiles in the original Counter.
type Group ¶
type Group struct { // Each tile represents a meld of 3 identical tiles. Pengs Hand // Each tile is the first of 3 consecutive tiles. Chis Hand // Each tile represents a pair. Pairs Hand // All the leftover tiles. Free Hand }
Group is an allocation of tiles in a hand to melds.
func UnmarshalGroup ¶
UnmarshalGroup is the inverse of Group.Marshal().
func (Group) Marshal ¶
Marshal returns a space-efficient encoding of this Group, suitable for comparison and map keys. For a stable representation, sort each field first.
func (Group) Score ¶
Score is used to determine the optimality of groupings. A higher score is better. This only considers the hand and not the context of the surrounding game.
func (Group) String ¶
String returns the human-readable representation of this Group, in the order Pengs, Chis, Pairs and Free.
type Hand ¶
type Hand []Tile
Hand is an ordered sequence of tiles, representing a mahjong hand. Except for Swap, the methods of Hand are guaranteed to not mutate the sequence.
func MustParseHand ¶
MustParseHand is like ParseHand, but panics if the string cannot be parsed. Useful for testing code, setup, etc.
func ParseHand ¶
ParseHand turns a space-separated string of 2-character sequences into a Hand, in order. Each 2-character sequence is passed to ParseTile.
func UnmarshalHand ¶
UnmarshalHand is the inverse of Hand.Marshal().
func (Hand) IsChi ¶
IsChi returns true if the Hand contains exactly 3 tiles that are consecutive and all in one of the Bamboo, Coin or Wan suits.
func (Hand) Marshal ¶
Marshal returns a space-efficient encoding of this Hand. No sorting is performed before encoding. For an encoding that is suitable for comparison, use the sort.Sort() function on the Hand first.
func (Hand) Split ¶
Split splits a Hand into sub-Hands that each contain the tiles belonging to the same suit.
func (Hand) String ¶
String returns the unicode string representation of this Hand. It is always sorted and therefore suitable for comparison. Note: one tile requires up to 7 bytes in utf-8 encoding. See Marshal() for a more efficient representation.
func (Hand) ToCount ¶
ToCount converts this Hand to a Counter. The result is completely independent of this Hand (i.e. no aliasing).
func (Hand) TryChiAt ¶
TryChiAt attempts to form a chi starting with the tile at index i. If it succeeds, it returns (a new Hand with the chi tiles removed, true). Otherwise, it returns (nil, false). The hand should be sorted first.
It is possible to return (nil, true) if i == 0, len(h) == 3 and the 3 tiles in the hand form a chi by themselves.
func (Hand) TryPairAt ¶
TryPairAt attempts to form a pair with the tile at the given index. If it succeeds, it returns (a new Hand with those tiles removed, true). Otherwise, it returns (nil, false). The hand should be sorted first.
It is possible to return (nil, true) if i == 0, len(h) == 2 and h[0] == h[1].
func (Hand) TryPengAt ¶
TryPengAt attempts to form a peng with the tile at the given index. If it succeeds, it returns (a new Hand with those tiles removed, true). Otherwise, it returns (nil, false). The hand should be sorted first.
It is possible to return (nil, true) if i == 0, len(h) == 3 and h[0] == h[1] == h[2].
type HandRLE ¶
type HandRLE struct {
// contains filtered or unexported fields
}
HandRLE is a run-length encoded version of Hand. It combines the best of Hand and Counter: like Hand, it is compact, contiguous in memory and preserves order, but like Counter, it stores tiles and their counts.
Unfortunately, the public API is also a weird mix of Hand and Counter. Tile lookup now uses binary search, since the tile-count pairs are stored in order.
func NewHandRLE ¶
func NewHandRLE(entries ...CountEntry) (HandRLE, error)
NewHandRLE creates a new HandRLE from one or more CountEntry values.
func UnmarshalHandRLE ¶
func (HandRLE) Entries ¶
func (h HandRLE) Entries() []CountEntry
Entries returns all tile-count pairs in the HandRLE.
func (HandRLE) ForEach ¶
func (h HandRLE) ForEach(f func(int, CountEntry) bool)
ForEach allows iteration over the tile-count pairs without the extra copying of Entries. Using HandRLE.ForEach() instead of ranging over the result of HandRLE.Entries() can save a lot of time and memory. The passed-in function should accept an index and a CountEntry and return whether or not to continue the iteration.
func (HandRLE) Marshal ¶
Marshal returns a space-efficient encoding of this HandRLE. It is suitable for comparison, because the output is always sorted in the same order.
func (HandRLE) String ¶
String returns the unicode string representation of this HandRLE. It is always sorted and therefore suitable for comparison. Note: one tile requires up to 7 bytes in utf-8 encoding. See Marshal() for a more efficient representation.
func (HandRLE) TryChiAt ¶
TryChiAt attempts to form a chi starting with the tile at index i. If it succeeds, it returns (a new HandRLE with the chi tiles removed, true). Otherwise, it returns (zero HandRLE, false).
For example: (not the real syntax)
HandRLE{B1:1 B2:2 B3:1 B4:1}.TryChi(B1) -> HandRLE{B2:1 B4:1}
Note that one B1, one B2 and one B3 were removed.
It is possible to return (zero HandRLE, true) if the 3 tiles to be removed are the only tiles in the original HandRLE.
func (HandRLE) TryPairAt ¶
TryPairAt attempts to form a pair with the tile at the given index. If it succeeds, it returns (a new HandRLE with the pair removed, true). Otherwise, it returns (zero HandRLE, false).
It is possible to return (zero HandRLE, true) if the 2 tiles to be removed are the only tiles in the original HandRLE.
func (HandRLE) TryPengAt ¶
TryPengAt attempts to form a peng with the tile at the given index. If it succeeds, it returns (a new HandRLE with those tiles removed, true). Otherwise, it returns (zero HandRLE, false).
It is possible to return (zero HandRLE, true) if the 3 tiles to be removed are the only tiles in the original HandRLE.
type Suit ¶
type Suit byte
Suit is the suit of a Tile. The zero Suit is invalid. There are three basic suits, Bamboo, Coin and Wan, as well as the Honour and Flower suits.
type Tile ¶
Tile is a single tile played in mahjong, comprising a Suit and a Value.
func ParseTile ¶
ParseTile turns a 2-character string into a Tile. The first character is the Suit and may be one of the characters "bcwhf" (for Bamboo, Coin, Wan, Honour and Flower). The second character is the Value and its permissible range depends on the Suit:
- Bamboo, Coin and Wan: a digit between 1-9 inclusive.
- Honour: one of the characters "eswnzfb" (for East, South, West, North, Zhong, Fa and Ban).
- Flower: a digit between 1-8 inclusive.
Parsing errors are returned in err.
func UnmarshalTile ¶
UnmarshalTile is the inverse of Tile.Marshal().
func (Tile) IsTerminal ¶
IsTerminal returns true if the Tile is a basic tile and the value is 1 or 9.
type Value ¶
type Value byte
Value is the face value of a Tile, including honours and bonuses. The zero Value is invalid. Values 1-9 inclusive are used for the basic suits. East, South, West, North, Zhong, Fa and Ban are only valid for the Honour suit. Values 32-39 inclusive are only valid for the Flower suit. Value 32 is defined as FlowerBase. This defines the basic Hong Kong tileset.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
Package handcheck contains several hand optimisers.
|
Package handcheck contains several hand optimisers. |