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}