Skip to main content

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}