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#[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#[derive(Clone, Debug, Default)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize))]
43pub struct WaitSet {
44 pub waiting_tiles: TileMask34,
46
47 pub regular: Vec<RegularWait>,
49
50 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}