mahjong_core/
tile.rs

1use crate::{DragonTile, FlowerTile, SeasonTile, SuitTile, WindTile};
2use serde::{Deserialize, Serialize};
3use ts_rs::TS;
4
5pub type TileId = usize;
6
7#[derive(Clone, Debug, Serialize, Deserialize, TS)]
8#[ts(export)]
9pub enum Tile {
10    Dragon(DragonTile),
11    Suit(SuitTile),
12    Wind(WindTile),
13    Flower(FlowerTile),
14    Season(SeasonTile),
15}
16
17impl Tile {
18    pub fn get_id(&self) -> TileId {
19        match self {
20            Self::Suit(tile) => tile.id,
21            Self::Dragon(tile) => tile.id,
22            Self::Wind(tile) => tile.id,
23            Self::Season(tile) => tile.id,
24            Self::Flower(tile) => tile.id,
25        }
26    }
27
28    pub fn is_same_type(&self, tile_b: &Self) -> bool {
29        match self {
30            Self::Suit(_) => matches!(tile_b, Self::Suit(_)),
31            Self::Dragon(_) => matches!(tile_b, Self::Dragon(_)),
32            Self::Wind(_) => matches!(tile_b, Self::Wind(_)),
33            Self::Season(_) => matches!(tile_b, Self::Season(_)),
34            Self::Flower(_) => matches!(tile_b, Self::Flower(_)),
35        }
36    }
37
38    pub fn is_same_content(&self, tile_b: &Self) -> bool {
39        match self {
40            Self::Suit(tile_a) => match tile_b {
41                Self::Suit(tile_b) => tile_a.suit == tile_b.suit && tile_a.value == tile_b.value,
42                _ => false,
43            },
44            Self::Dragon(tile_a) => match tile_b {
45                Self::Dragon(tile_b) => tile_a.value == tile_b.value,
46                _ => false,
47            },
48            Self::Wind(tile_a) => match tile_b {
49                Self::Wind(tile_b) => tile_a.value == tile_b.value,
50                _ => false,
51            },
52            Self::Season(tile_a) => match tile_b {
53                Self::Season(tile_b) => tile_a.value == tile_b.value,
54                _ => false,
55            },
56            Self::Flower(tile_a) => match tile_b {
57                Self::Flower(tile_b) => tile_a.value == tile_b.value,
58                _ => false,
59            },
60        }
61    }
62
63    fn cmp_custom_order(tile: &Self) -> u32 {
64        match tile {
65            Self::Suit(_) => 0,
66            Self::Dragon(_) => 1,
67            Self::Wind(_) => 2,
68            Self::Season(_) => 3,
69            Self::Flower(_) => 4,
70        }
71    }
72
73    pub fn cmp_custom(&self, other: &Self) -> std::cmp::Ordering {
74        match self {
75            Self::Suit(tile_a) => {
76                if let Self::Suit(tile_b) = other {
77                    if tile_a.suit != tile_b.suit {
78                        return tile_a.suit.cmp(&tile_b.suit);
79                    }
80
81                    return tile_a.value.cmp(&tile_b.value);
82                }
83            }
84            Self::Dragon(tile_a) => {
85                if let Self::Dragon(tile_b) = other {
86                    return tile_a.value.cmp(&tile_b.value);
87                }
88            }
89            Self::Wind(tile_a) => {
90                if let Self::Wind(tile_b) = other {
91                    return tile_a.value.cmp(&tile_b.value);
92                }
93            }
94            Self::Season(tile_a) => {
95                if let Self::Season(tile_b) = other {
96                    return tile_a.value.cmp(&tile_b.value);
97                }
98            }
99            Self::Flower(tile_a) => {
100                if let Self::Flower(tile_b) = other {
101                    return tile_a.value.cmp(&tile_b.value);
102                }
103            }
104        };
105
106        Self::cmp_custom_order(self).cmp(&Self::cmp_custom_order(other))
107    }
108
109    pub fn is_bonus(&self) -> bool {
110        matches!(self, Self::Flower(_) | Self::Season(_))
111    }
112}
113
114impl Tile {
115    pub fn set_id(&mut self, id: TileId) {
116        match self {
117            Self::Suit(tile) => tile.id = id,
118            Self::Dragon(tile) => tile.id = id,
119            Self::Wind(tile) => tile.id = id,
120            Self::Season(tile) => tile.id = id,
121            Self::Flower(tile) => tile.id = id,
122        }
123    }
124}