chess_lab/core/variant.rs
1use crate::{
2 core::{Move, Piece},
3 errors::{FenError, MoveError, PGNError},
4 logic::Game,
5};
6
7use super::{Color, GameStatus, Position};
8
9/// A trait for a chess variant.
10///
11/// A chess variant is a game that is derived from chess, but has different rules.
12///
13pub trait Variant {
14 /// Moves a piece on the board.
15 ///
16 /// # Arguments
17 /// * `move_str` - A move string in algebraic notation.
18 ///
19 /// # Returns
20 /// A `Result<GameStatus, MoveError>` object
21 /// * `Ok(GameStatus)` - The status of the game after the move.
22 /// * `Err(MoveError)` - An error occurred while moving the piece.
23 ///
24 fn move_piece(&mut self, move_str: &str) -> Result<GameStatus, MoveError>;
25
26 /// Undoes the last move.
27 ///
28 fn undo(&mut self);
29
30 /// Redoes the last undone move.
31 ///
32 fn redo(&mut self);
33
34 /// Returns the PGN string of the game.
35 ///
36 /// # Returns
37 /// The PGN string of the game.
38 ///
39 fn pgn(&self) -> String;
40
41 /// Returns the FEN string of the game.
42 ///
43 /// # Returns
44 /// The FEN string of the game.
45 ///
46 fn fen(&self) -> String;
47
48 /// Returns the piece at a given position.
49 ///
50 /// # Arguments
51 /// * `pos` - The position to get the piece from.
52 ///
53 /// # Returns
54 /// The piece at the given position, if there is one.
55 ///
56 fn get_piece_at(&self, pos: Position) -> Option<Piece>;
57
58 /// Returns the legal moves for a given position.
59 ///
60 /// # Arguments
61 /// * `pos` - The position to get the legal moves for.
62 ///
63 /// # Returns
64 /// A vector of legal moves for the given position.
65 ///
66 fn get_legal_moves(&self, pos: Position) -> Vec<Move>;
67
68 /// Saves the game to a file.
69 ///
70 /// # Arguments
71 /// * `path` - The path to the file.
72 /// * `overwrite` - Whether to overwrite the file if it already exists.
73 ///
74 /// # Returns
75 /// A `Result<(), std::io::Error>` object
76 /// * `Ok(())` - The game was saved successfully.
77 /// * `Err(std::io::Error)` - An error occurred while saving the game.
78 ///
79 fn save(&self, path: &str, overwrite: bool) -> Result<(), std::io::Error>;
80
81 /// Resigns the game for a player.
82 ///
83 /// # Arguments
84 /// * `color` - The color of the player that is resigning.
85 ///
86 fn resign(&mut self, color: Color);
87
88 /// Sets the game as a draw by agreement.
89 ///
90 fn draw(&mut self);
91
92 /// Sets the game as lost in time for a player.
93 ///
94 /// # Arguments
95 /// * `color` - The color of the player that lost in time.
96 ///
97 fn lost_on_time(&mut self, color: Color);
98
99 /// Gets the minified fen of the game.
100 ///
101 /// # Returns
102 /// The minified fen of the game.
103 ///
104 fn get_minified_fen(&self) -> String;
105
106 /// Gets the last move of the game.
107 ///
108 /// # Returns
109 /// The last move of the game, if there is one.
110 ///
111 fn get_last_move(&self) -> Option<Move>;
112
113 /// Returns whether it is white's turn to move.
114 ///
115 /// # Returns
116 /// Whether it is white's turn to move.
117 ///
118 fn is_white_turn(&self) -> bool;
119
120 /// Returns the halfmove clock of the game.
121 ///
122 /// # Returns
123 /// The halfmove clock of the game.
124 ///
125 fn get_halfmove_clock(&self) -> u32;
126
127 /// Returns the fullmove number of the game.
128 ///
129 /// # Returns
130 /// The fullmove number of the game.
131 ///
132 fn get_fullmove_number(&self) -> u32;
133
134 /// Returns the castling rights of the game.
135 ///
136 /// # Returns
137 /// The castling rights of the game.
138 ///
139 fn get_castling_rights(&self) -> String;
140
141 /// Returns the en passant square of the game.
142 ///
143 /// # Returns
144 /// The en passant square of the game.
145 ///
146 fn get_en_passant(&self) -> Option<Position>;
147
148 /// Returns the starting FEN of the game.
149 ///
150 /// # Returns
151 /// The starting FEN of the game.
152 ///
153 fn get_starting_fen(&self) -> String;
154
155 /// Returns the status of the game.
156 ///
157 /// # Returns
158 /// The status of the game.
159 ///
160 fn get_status(&self) -> GameStatus;
161}
162
163/// Construction helpers for variant types.
164pub trait VariantBuilder: Sized + Default {
165 /// The name of the variant.
166 ///
167 /// # Returns
168 /// The name of the variant.
169 ///
170 fn name() -> &'static str;
171
172 /// Creates a new instance of the variant.
173 ///
174 /// # Returns
175 /// A new instance of the variant.
176 ///
177 fn new(game: Game) -> Self;
178
179 /// Creates a new instance of the variant from a FEN string.
180 ///
181 /// # Arguments
182 /// * `fen` - A FEN string.
183 ///
184 /// # Returns
185 /// A `Result<Self, FenError>` object
186 /// * `Ok(Self)` - A new instance of the variant.
187 /// * `Err(FenError)` - An error occurred while parsing the FEN string.
188 ///
189 fn from_fen(fen: &str) -> Result<Self, FenError>;
190
191 /// Creates a new instance of the variant from a PGN string.
192 ///
193 /// # Arguments
194 /// * `pgn` - A PGN string.
195 ///
196 /// # Returns
197 /// A `Result<Self, PgnError>` object
198 /// * `Ok(Self)` - A new instance of the variant.
199 /// * `Err(PgnError)` - An error occurred while parsing the PGN string.
200 ///
201 fn from_pgn(pgn: &str) -> Result<Self, PGNError>;
202
203 /// Loads the game from a file.
204 ///
205 /// # Arguments
206 /// * `path` - The path to the file.
207 ///
208 /// # Returns
209 /// A `Result<Self, PgnError>` object
210 /// * `Ok(Self)` - The game was loaded successfully.
211 /// * `Err(PgnError)` - An error occurred while loading the game.
212 ///
213 fn load(path: &str) -> Result<Self, PGNError>;
214
215 /// Loads multiple games from a file.
216 ///
217 /// # Arguments
218 /// * `path` - The path to the file.
219 ///
220 /// # Returns
221 /// A `Result<Vec<Self>, PgnError>` object
222 /// * `Ok(Vec<Self>)` - The games were loaded successfully.
223 /// * `Err(PgnError)` - An error occurred while loading the games.
224 ///
225 fn load_all(path: &str) -> Result<Vec<Self>, PGNError>;
226}