ritchie/hand/decompose

Tile decomposer. Takes a hand, and finds waiting patterns. Importantly, it finds all possible patterns, which is important, because we want the most valuable potential winning hand, scoring-wise. Waits break down into the following categories:

The algorithm for decomposition works roughly like this:

Types

pub type Block {
  Block(kind: BlockKind, t: List(tile.Tile))
}

Constructors

pub type BlockKind {
  Sequence
  Triplet
  MeldedSequence
  MeldedTriplet
  MeldedKan
  MeldedAnkan
}

Constructors

  • Sequence
  • Triplet
  • MeldedSequence
  • MeldedTriplet
  • MeldedKan
  • MeldedAnkan
pub type DecompNode {
  DecompNode(
    kind: DecompNodeKind,
    tiles: List(tile.Tile),
    children: List(DecompNode),
  )
}

Constructors

pub type DecompNodeKind {
  DTriplet
  DSequence
  DPair
  DWait(WaitingKind)
}

Constructors

pub type DecomposedHand {
  RegularHand(
    blocks: List(Block),
    pair: option.Option(List(tile.Tile)),
    wkind: WaitingKind,
    wtiles: List(tile.Tile),
  )
  SevenPairs(
    pairs: List(List(tile.Tile)),
    wkind: WaitingKind,
    wtiles: List(tile.Tile),
  )
  ThirteenOrphans(
    tiles: List(tile.Tile),
    pair: option.Option(List(tile.Tile)),
    wkind: WaitingKind,
    wtiles: List(tile.Tile),
  )
}

Constructors

pub type FlattenedDecompNode {
  FlattenedDecompNode(
    kind: DecompNodeKind,
    tiles: List(tile.Tile),
  )
}

Constructors

pub type Shape {
  ShapeBlock(block: Block)
  ShapePair(tiles: List(tile.Tile))
  ShapeWait(kind: WaitingKind)
}

Constructors

pub type WaitingKind {
  Pattern(pattern: WaitingPattern, tiles: List(tile.Tile))
  Tanki(tile: tile.Tile)
  Single(tile: tile.Tile)
  AllOrphans(tiles: List(tile.Tile))
}

Constructors

pub type WaitingPattern {
  Penchan
  Kanchan
  Ryanmen
  Shanpon
}

Constructors

  • Penchan
  • Kanchan
  • Ryanmen
  • Shanpon

Values

pub fn decomp_to_thing(decomp: FlattenedDecompNode) -> Shape
pub fn decompose(
  hand: tile_set37.TileSet37,
  melds: List(meld.Meld),
) -> List(DecomposedHand)

Enumerates every way the hand can be decomposed into waiting shapes.

hand must hold expected_hand_size(melds) concealed tiles (i.e. be a tenpai-sized hand); any other size yields [] rather than a partial or incorrect decomposition.

Waiting tiles (wtiles) are always reported as normal tiles: red fives collapse to their normal counterpart, so a wait on 0m is reported as 5m.

pub fn decompose_regular(
  hand: tile_set34.TileSet34,
  melds: List(Block),
) -> List(DecomposedHand)
pub fn decompose_seven_pairs(
  hand: tile_set34.TileSet34,
) -> List(DecomposedHand)
pub fn decompose_suit(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(DecompNode)
pub fn expected_hand_size(melds: List(meld.Meld)) -> Int

The number of concealed tiles a tenpai hand holds, given its melds. Each meld (including kans) occupies one of the four block slots.

pub fn flatten_decomposition(
  nodes: List(DecompNode),
) -> List(List(FlattenedDecompNode))
pub fn pop_pairs(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(#(tile_set34.TileSet34, List(tile.Tile)))

Removes pairs from a TileSet34. Returns the updated tileset and the extracted tiles for each pair.

pub fn pop_sequences(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(#(tile_set34.TileSet34, List(tile.Tile)))

Removes sequences from a TileSet34. Returns the updated tileset and the extracted tiles for each sequence.

pub fn pop_tanki(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(#(tile_set34.TileSet34, tile.Tile))

Removes pair waits (tanki) from a TileSet34. Returns the updated tileset and removed tiles for all pair waits.

pub fn pop_triplets(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(#(tile_set34.TileSet34, List(tile.Tile)))

Removes triplets from a TileSet34. Returns the updated tileset and the extracted tiles for each triplet.

pub fn pop_waiting_sets(
  hand: tile_set34.TileSet34,
  suit: Int,
) -> List(
  #(WaitingPattern, tile_set34.TileSet34, List(tile.Tile)),
)

Removes sequence waits (penchan/ryanmen/kanchan) from a TileSet34. Returns the updated tileset and the extracted tiles for each pair.

pub fn wtiles(decomp: DecomposedHand) -> List(tile.Tile)

Returns the tiles that would complete the decomposed hand.

✨ Search Document