riichi_decomp/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod decomposer;
4pub mod irregular;
5pub mod regular;
6
7use std::fmt::{Display, Formatter};
8
9use itertools::Itertools;
10
11use riichi_elements::prelude::*;
12
13pub use riichi_decomp_table::WaitingKind;
14pub use self::{
15    decomposer::Decomposer,
16    regular::RegularWait,
17    irregular::{IrregularWait, detect_irregular_wait},
18};
19
20/// One waiting pattern, either [`RegularWait`] or [`IrregularWait`].
21///
22/// ## Optional `serde` support
23///
24/// Serialization only. `{type, wait}` (adjacently tagged).
25///
26#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize))]
28#[cfg_attr(feature = "serde", serde(tag = "type", content = "wait"))]
29pub enum Wait {
30    Regular(RegularWait),
31    Irregular(IrregularWait),
32}
33
34/// All the ways a player's closed hand can be considered waiting, regular and/or irregular.
35///
36/// ## Optional `serde` support
37///
38/// Serialization only.
39/// Straightforward struct mapping of fields.
40///
41#[derive(Clone, Debug, Default)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize))]
43pub struct WaitSet {
44    /// The set of all waiting tiles in all different ways of waiting.
45    pub waiting_tiles: TileMask34,
46
47    /// Regular waiting patterns (groups and a pair).
48    pub regular: Vec<RegularWait>,
49
50    /// Irregular waiting pattern (seven pairs, thirteen orphans).
51    pub irregular: Option<IrregularWait>,
52}
53
54impl WaitSet {
55    pub fn from_keys(decomposer: &mut Decomposer, keys: &[u32; 4]) -> Self {
56        let mut waiting_tiles = TileMask34::default();
57        let regular = decomposer.with_keys(*keys).iter().collect_vec();
58        for wait in regular.iter() {
59            waiting_tiles.0 |= 1 << wait.waiting_tile.encoding() as u64;
60        }
61        let irregular = detect_irregular_wait(*keys);
62        if let Some(irregular) = irregular {
63            waiting_tiles |= irregular.to_waiting_set();
64        }
65        Self { waiting_tiles, regular, irregular }
66    }
67
68    pub fn from_tile_set(decomposer: &mut Decomposer, tile_set: &TileSet34) -> Self {
69        Self::from_keys(decomposer, &tile_set.packed_34())
70    }
71}
72
73impl Display for WaitSet {
74    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75        write!(f, "{{waiting_tiles={}", self.waiting_tiles)?;
76        if let Some(irregular) = self.irregular {
77            write!(f, " irregular={}", irregular)?;
78        }
79        write!(f, " regular=[")?;
80        for w in &self.regular {
81            write!(f, "({}),", w)?;
82        }
83        write!(f, "]}}")
84    }
85}