rusty2048_shared/
lib.rs

1//! Shared components for Rusty2048
2//!
3//! This module contains shared utilities, themes, and components
4//! that can be used across different platforms.
5
6use serde::{Deserialize, Serialize};
7
8pub mod i18n;
9pub use i18n::{I18n, Language, TranslationKey};
10
11/// Color theme for the game
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Theme {
14    pub name: String,
15    pub background: String,
16    pub grid_background: String,
17    pub tile_colors: Vec<String>,
18    pub text_color: String,
19    pub title_color: String,
20    pub score_color: String,
21    pub best_score_color: String,
22    pub moves_color: String,
23    pub time_color: String,
24}
25
26impl Default for Theme {
27    fn default() -> Self {
28        Self {
29            name: "Classic".to_string(),
30            background: "#faf8ef".to_string(),
31            grid_background: "#bbada0".to_string(),
32            tile_colors: vec![
33                "#cdc1b4".to_string(), // 0
34                "#eee4da".to_string(), // 2
35                "#ede0c8".to_string(), // 4
36                "#f2b179".to_string(), // 8
37                "#f59563".to_string(), // 16
38                "#f67c5f".to_string(), // 32
39                "#f65e3b".to_string(), // 64
40                "#edcf72".to_string(), // 128
41                "#edcc61".to_string(), // 256
42                "#edc850".to_string(), // 512
43                "#edc53f".to_string(), // 1024
44                "#edc22e".to_string(), // 2048
45            ],
46            text_color: "#776e65".to_string(),
47            title_color: "#776e65".to_string(),
48            score_color: "#776e65".to_string(),
49            best_score_color: "#776e65".to_string(),
50            moves_color: "#776e65".to_string(),
51            time_color: "#776e65".to_string(),
52        }
53    }
54}
55
56impl Theme {
57    /// Create a dark theme
58    pub fn dark() -> Self {
59        Self {
60            name: "Dark".to_string(),
61            background: "#1a1a1a".to_string(),
62            grid_background: "#2d2d2d".to_string(),
63            tile_colors: vec![
64                "#3c3c3c".to_string(), // 0
65                "#4a4a4a".to_string(), // 2
66                "#5a5a5a".to_string(), // 4
67                "#6a6a6a".to_string(), // 8
68                "#7a7a7a".to_string(), // 16
69                "#8a8a8a".to_string(), // 32
70                "#9a9a9a".to_string(), // 64
71                "#aaaaaa".to_string(), // 128
72                "#bbbbbb".to_string(), // 256
73                "#cccccc".to_string(), // 512
74                "#dddddd".to_string(), // 1024
75                "#eeeeee".to_string(), // 2048
76            ],
77            text_color: "#ffffff".to_string(),
78            title_color: "#ffffff".to_string(),
79            score_color: "#4ade80".to_string(),
80            best_score_color: "#fbbf24".to_string(),
81            moves_color: "#60a5fa".to_string(),
82            time_color: "#a78bfa".to_string(),
83        }
84    }
85
86    /// Create a neon theme
87    pub fn neon() -> Self {
88        Self {
89            name: "Neon".to_string(),
90            background: "#000000".to_string(),
91            grid_background: "#1a0033".to_string(),
92            tile_colors: vec![
93                "#330033".to_string(), // 0
94                "#ff00ff".to_string(), // 2
95                "#00ffff".to_string(), // 4
96                "#ffff00".to_string(), // 8
97                "#ff0080".to_string(), // 16
98                "#80ff00".to_string(), // 32
99                "#0080ff".to_string(), // 64
100                "#ff8000".to_string(), // 128
101                "#8000ff".to_string(), // 256
102                "#00ff80".to_string(), // 512
103                "#ff0080".to_string(), // 1024
104                "#ffff00".to_string(), // 2048
105            ],
106            text_color: "#ffffff".to_string(),
107            title_color: "#ff00ff".to_string(),
108            score_color: "#00ffff".to_string(),
109            best_score_color: "#ffff00".to_string(),
110            moves_color: "#ff0080".to_string(),
111            time_color: "#80ff00".to_string(),
112        }
113    }
114
115    /// Create a retro theme
116    pub fn retro() -> Self {
117        Self {
118            name: "Retro".to_string(),
119            background: "#2b2b2b".to_string(),
120            grid_background: "#404040".to_string(),
121            tile_colors: vec![
122                "#555555".to_string(), // 0
123                "#00ff00".to_string(), // 2
124                "#00dd00".to_string(), // 4
125                "#00bb00".to_string(), // 8
126                "#009900".to_string(), // 16
127                "#007700".to_string(), // 32
128                "#005500".to_string(), // 64
129                "#003300".to_string(), // 128
130                "#001100".to_string(), // 256
131                "#00ff00".to_string(), // 512
132                "#00dd00".to_string(), // 1024
133                "#00bb00".to_string(), // 2048
134            ],
135            text_color: "#00ff00".to_string(),
136            title_color: "#00ff00".to_string(),
137            score_color: "#00ff00".to_string(),
138            best_score_color: "#00ff00".to_string(),
139            moves_color: "#00ff00".to_string(),
140            time_color: "#00ff00".to_string(),
141        }
142    }
143
144    /// Create a pastel theme
145    pub fn pastel() -> Self {
146        Self {
147            name: "Pastel".to_string(),
148            background: "#f8f9fa".to_string(),
149            grid_background: "#e9ecef".to_string(),
150            tile_colors: vec![
151                "#dee2e6".to_string(), // 0
152                "#ffb3ba".to_string(), // 2
153                "#baffc9".to_string(), // 4
154                "#bae1ff".to_string(), // 8
155                "#ffffba".to_string(), // 16
156                "#ffb3d9".to_string(), // 32
157                "#d9b3ff".to_string(), // 64
158                "#b3d9ff".to_string(), // 128
159                "#b3ffd9".to_string(), // 256
160                "#ffd9b3".to_string(), // 512
161                "#d9ffb3".to_string(), // 1024
162                "#ffb3b3".to_string(), // 2048
163            ],
164            text_color: "#495057".to_string(),
165            title_color: "#6c757d".to_string(),
166            score_color: "#28a745".to_string(),
167            best_score_color: "#ffc107".to_string(),
168            moves_color: "#17a2b8".to_string(),
169            time_color: "#6f42c1".to_string(),
170        }
171    }
172
173    /// Get all available themes
174    pub fn all_themes() -> Vec<Self> {
175        vec![
176            Self::default(),
177            Self::dark(),
178            Self::neon(),
179            Self::retro(),
180            Self::pastel(),
181        ]
182    }
183
184    /// Get theme by name
185    pub fn by_name(name: &str) -> Option<Self> {
186        Self::all_themes().into_iter().find(|t| t.name == name)
187    }
188}
189
190/// Game configuration that can be shared across platforms
191#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct SharedConfig {
193    pub theme: Theme,
194    pub board_size: usize,
195    pub target_score: u32,
196    pub enable_animations: bool,
197    pub enable_sound: bool,
198}
199
200impl Default for SharedConfig {
201    fn default() -> Self {
202        Self {
203            theme: Theme::default(),
204            board_size: 4,
205            target_score: 2048,
206            enable_animations: true,
207            enable_sound: false,
208        }
209    }
210}
211
212/// Animation settings
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct AnimationConfig {
215    pub duration_ms: u32,
216    pub easing: String,
217    pub enable_slide: bool,
218    pub enable_merge: bool,
219    pub enable_spawn: bool,
220}
221
222impl Default for AnimationConfig {
223    fn default() -> Self {
224        Self {
225            duration_ms: 150,
226            easing: "ease-out".to_string(),
227            enable_slide: true,
228            enable_merge: true,
229            enable_spawn: true,
230        }
231    }
232}