Skip to main content

timecat/
constants.rs

1use super::*;
2
3pub mod description {
4    pub const ENGINE_NAME: &str = "Timecat";
5    pub const ENGINE_AUTHOR: &str = "Gourab Ghosh";
6    pub const ENGINE_VERSION: &str = env!("CARGO_PKG_VERSION");
7}
8
9pub mod types {
10    use super::*;
11
12    pub type Ply = usize;
13    pub type Depth = i8;
14    pub type Score = i16;
15    pub type MoveWeight = i32;
16    pub type NumMoves = u16;
17    pub type Spin = u128;
18    pub type Engine = CustomEngine<SearchController, Evaluator>;
19
20    #[cfg(feature = "colored")]
21    pub type ColoredStringFunction = fn(colored::ColoredString) -> colored::ColoredString;
22    #[cfg(not(feature = "colored"))]
23    pub type ColoredStringFunction = fn(String) -> String;
24
25    pub type Result<T> = std::result::Result<T, TimecatError>;
26}
27
28pub mod bitboard_and_square {
29    use super::*;
30    use File::*;
31
32    pub const NUM_SQUARES: usize = 64;
33
34    macro_rules! generate_bitboard_and_square_constants {
35        (@bb_squares $(($file:expr, $rank:expr)),+ $(,)?) => {
36            paste! {
37                $(
38                    pub const [<BB_$file$rank>]: BitBoard = BitBoard::new(1 << (8 * ($rank - 1) + $file as usize));
39                )*
40                pub static ALL_SQUARES: [Square; NUM_SQUARES] = [$( Square::[<$file$rank>] ), *];
41                pub static BB_SQUARES: [BitBoard; NUM_SQUARES] = [$( [<BB_$file$rank>] ), *];
42                pub static SQUARES_VERTICAL_MIRROR: [Square; NUM_SQUARES] = [$( [<$file$rank>].vertical_mirror() ), *];
43                pub static SQUARES_HORIZONTAL_MIRROR: [Square; NUM_SQUARES] = [$( [<$file$rank>].horizontal_mirror() ), *];
44                pub static SQUARES_ROTATED: [Square; NUM_SQUARES] = [$( [<$file$rank>].rotate() ), *];
45            }
46        };
47
48        (@bb_ranks_and_files $(($file:expr, $rank:expr)),+ $(,)?) => {
49            paste! {
50                $(
51                    pub const [<BB_RANK_$rank>]: BitBoard = unsafe { Rank::from_int($rank - 1) }.to_bitboard();
52                    pub const [<BB_FILE_$file>]: BitBoard = $file.to_bitboard();
53                )*
54                pub static BB_RANKS: [BitBoard; NUM_RANKS] = [$( [<BB_RANK_$rank>] ), *];
55                pub static BB_FILES: [BitBoard; NUM_FILES] = [$( [<BB_FILE_$file>] ), *];
56            }
57        };
58    }
59
60    #[rustfmt::skip]
61    generate_bitboard_and_square_constants!(
62        @bb_squares
63        (A, 1), (B, 1), (C, 1), (D, 1), (E, 1), (F, 1), (G, 1), (H, 1),
64        (A, 2), (B, 2), (C, 2), (D, 2), (E, 2), (F, 2), (G, 2), (H, 2),
65        (A, 3), (B, 3), (C, 3), (D, 3), (E, 3), (F, 3), (G, 3), (H, 3),
66        (A, 4), (B, 4), (C, 4), (D, 4), (E, 4), (F, 4), (G, 4), (H, 4),
67        (A, 5), (B, 5), (C, 5), (D, 5), (E, 5), (F, 5), (G, 5), (H, 5),
68        (A, 6), (B, 6), (C, 6), (D, 6), (E, 6), (F, 6), (G, 6), (H, 6),
69        (A, 7), (B, 7), (C, 7), (D, 7), (E, 7), (F, 7), (G, 7), (H, 7),
70        (A, 8), (B, 8), (C, 8), (D, 8), (E, 8), (F, 8), (G, 8), (H, 8),
71    );
72    generate_bitboard_and_square_constants!(
73        @bb_ranks_and_files
74        (A, 1), (B, 2), (C, 3), (D, 4), (E, 5), (F, 6), (G, 7), (H, 8),
75    );
76
77    pub static BB_ADJACENT_FILES: [BitBoard; 8] = [
78        BitBoard::new(144680345676153346),
79        BitBoard::new(361700864190383365),
80        BitBoard::new(723401728380766730),
81        BitBoard::new(1446803456761533460),
82        BitBoard::new(2893606913523066920),
83        BitBoard::new(5787213827046133840),
84        BitBoard::new(11574427654092267680),
85        BitBoard::new(4629771061636907072),
86    ];
87
88    pub const BB_CORNERS: BitBoard = BitBoard::new(
89        BB_A1.into_inner() ^ BB_H1.into_inner() ^ BB_A8.into_inner() ^ BB_H8.into_inner(),
90    );
91    pub const BB_CENTER: BitBoard = BitBoard::new(
92        BB_D4.into_inner() ^ BB_E4.into_inner() ^ BB_D5.into_inner() ^ BB_E5.into_inner(),
93    );
94    pub const BB_EDGES: BitBoard = BitBoard::new(
95        BB_RANK_1.into_inner()
96            | BB_RANK_8.into_inner()
97            | BB_FILE_A.into_inner()
98            | BB_FILE_H.into_inner(),
99    );
100
101    pub const BB_LIGHT_SQUARES: BitBoard = BitBoard::new(0x55aa_55aa_55aa_55aa);
102    pub const BB_DARK_SQUARES: BitBoard = BitBoard::new(0xaa55_aa55_aa55_aa55);
103
104    pub const BB_BACKRANKS: BitBoard =
105        BitBoard::new(BB_RANK_1.into_inner() ^ BB_RANK_8.into_inner());
106
107    pub const BB_UPPER_HALF_BOARD: BitBoard = BitBoard::new(0xFFFFFFFF00000000);
108    pub const BB_LOWER_HALF_BOARD: BitBoard = BitBoard::new(0x00000000FFFFFFFF);
109    pub const BB_LEFT_HALF_BOARD: BitBoard = BitBoard::new(0xF0F0F0F0F0F0F0F0);
110    pub const BB_RIGHT_HALF_BOARD: BitBoard = BitBoard::new(0x0F0F0F0F0F0F0F0F);
111
112    pub const CENTER_SQUARES_BB: BitBoard = BitBoard::new(0x0000001818000000);
113    pub const PSEUDO_CENTER_SQUARES_BB: BitBoard = BitBoard::new(0x00003C24243C0000);
114
115    pub static BOARD_QUARTER_MASKS: [BitBoard; 4] = [
116        BitBoard::new(0x0f0f_0f0f_0000_0000),
117        BitBoard::new(0xf0f0_f0f0_0000_0000),
118        BitBoard::new(0x0000_0000_0f0f_0f0f),
119        BitBoard::new(0x0000_0000_f0f0_f0f0),
120    ];
121
122    pub const DIAGONAL_RAY: BitBoard = BitBoard::new(0x8040201008040201);
123    pub const ANTI_DIAGONAL_RAY: BitBoard = DIAGONAL_RAY.flip_horizontal();
124
125    pub static UPPER_BOARD_MASK: [[BitBoard; 8]; 2] = [
126        [
127            BitBoard::new(0x0000_0000_0000_0000),
128            BitBoard::new(0x0000_0000_0000_00ff),
129            BitBoard::new(0x0000_0000_0000_ffff),
130            BitBoard::new(0x0000_0000_00ff_ffff),
131            BitBoard::new(0x0000_0000_ffff_ffff),
132            BitBoard::new(0x0000_00ff_ffff_ffff),
133            BitBoard::new(0x0000_ffff_ffff_ffff),
134            BitBoard::new(0x00ff_ffff_ffff_ffff),
135        ],
136        [
137            BitBoard::new(0xffff_ffff_ffff_ff00),
138            BitBoard::new(0xffff_ffff_ffff_0000),
139            BitBoard::new(0xffff_ffff_ff00_0000),
140            BitBoard::new(0xffff_ffff_0000_0000),
141            BitBoard::new(0xffff_ff00_0000_0000),
142            BitBoard::new(0xffff_0000_0000_0000),
143            BitBoard::new(0xff00_0000_0000_0000),
144            BitBoard::new(0x0000_0000_0000_0000),
145        ],
146    ];
147}
148
149pub mod board {
150    pub const EMPTY_SPACE_SYMBOL: &str = " ";
151    pub const EMPTY_SPACE_UNICODE_SYMBOL: &str = " ";
152    pub const WHITE_PIECE_UNICODE_SYMBOLS: [&str; 6] = ["♙", "♘", "♗", "♖", "♕", "♔"];
153    pub const BLACK_PIECE_UNICODE_SYMBOLS: [&str; 6] = ["♟", "♞", "♝", "♜", "♛", "♚"];
154    pub const MAX_MOVES_PER_POSITION: usize = 250;
155}
156
157pub mod fen {
158    pub const EMPTY_POSITION_FEN: &str = "8/8/8/8/8/8/8/8 w - - 0 1";
159    pub const STARTING_POSITION_FEN: &str =
160        "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
161}
162
163pub mod strings {
164    use super::*;
165
166    macro_rules! generate_constants {
167        ($constant_name:ident, [$( $func_name:ident ), *]) => {
168            #[cfg(feature = "colored")]
169            pub static $constant_name: &[ColoredStringFunction] = &[$( colored::Colorize::$func_name ), *];
170            #[cfg(not(feature = "colored"))]
171            pub static $constant_name: &[ColoredStringFunction] = &[];
172        };
173    }
174
175    generate_constants!(WHITE_PIECES_STYLE, [white, bold]);
176    generate_constants!(BLACK_PIECES_STYLE, [purple, bold]);
177    generate_constants!(BITBOARD_OCCUPIED_SQUARE_STYLE, [white, bold]);
178    generate_constants!(BOARD_SKELETON_STYLE, [green]);
179    generate_constants!(BOARD_LABEL_STYLE, [red, bold]);
180    generate_constants!(INFO_MESSAGE_STYLE, [bright_cyan, bold]);
181    generate_constants!(CHECK_STYLE, [on_bright_red]);
182    generate_constants!(CHECKERS_STYLE, [bright_red, bold]);
183    generate_constants!(CHECKMATE_SCORE_STYLE, [bright_red, bold]);
184    generate_constants!(PERFT_MOVE_STYLE, [green, bold]);
185    generate_constants!(PERFT_COUNT_STYLE, []);
186    generate_constants!(INPUT_MESSAGE_STYLE, [blue, bold]);
187    generate_constants!(SUCCESS_MESSAGE_STYLE, [green, bold]);
188    generate_constants!(ERROR_MESSAGE_STYLE, [red, bold]);
189    generate_constants!(LAST_MOVE_HIGHLIGHT_STYLE, [on_bright_black]);
190    generate_constants!(WARNING_MESSAGE_STYLE, [bright_yellow, bold]);
191
192    pub const STRINGIFY_NONE: &str = "UNKNOWN";
193}
194
195pub mod evaluate {
196    use super::*;
197
198    pub const ENDGAME_PIECE_THRESHOLD: u32 = 12;
199    pub const CACHE_TABLE_SIZE: CacheTableSize = CacheTableSize::Exact(16);
200    pub const DRAW_SCORE: Score = PAWN_VALUE / 2;
201    pub const CHECKMATE_SCORE: Score = 25_000;
202    pub const CHECKMATE_THRESHOLD: Score = CHECKMATE_SCORE - MAX_PLY as Score - 1;
203    pub const INFINITY: Score = CHECKMATE_SCORE + 4 * MAX_PLY as Score;
204    pub const PAWN_VALUE: Score = 100;
205    pub const MAX_PLY: usize = 255;
206    pub const INITIAL_MATERIAL_SCORE_ABS: Score = 16 * PAWN_VALUE
207        + 4 * (Knight.evaluate() + Bishop.evaluate() + Rook.evaluate())
208        + 2 * Queen.evaluate();
209    pub const MAX_MATERIAL_SCORE: Score = INITIAL_MATERIAL_SCORE_ABS / 2;
210    pub const WINNING_SCORE_THRESHOLD: Score = 15 * PAWN_VALUE;
211}
212
213pub mod cache_table {
214    use super::*;
215
216    pub const DEFAULT_HASH: NonZeroU64 = NonZeroU64::new(1).unwrap();
217}
218
219pub mod engine {
220    use super::*;
221
222    pub const NUM_KILLER_MOVES: usize = 3;
223
224    pub const DISABLE_ALL_PRUNINGS: bool = false;
225
226    pub const NULL_MOVE_MIN_DEPTH: Depth = 2;
227    pub const NULL_MOVE_MIN_REDUCTION: Depth = 2;
228    pub const NULL_MOVE_DEPTH_DIVIDER: Depth = 4;
229
230    pub const FULL_DEPTH_SEARCH_LMR: usize = 4;
231    pub const REDUCTION_LIMIT_LMR: Depth = 3;
232    pub const LMR_BASE_REDUCTION: f64 = 0.75;
233    pub const LMR_MOVE_DIVIDER: f64 = 2.25;
234
235    pub const ASPIRATION_WINDOW_CUTOFF: Score = PAWN_VALUE / 2;
236
237    pub const FOLLOW_PV: bool = true;
238    pub const PRINT_MOVE_INFO_DURATION_THRESHOLD: Duration = Duration::from_millis(1000);
239
240    pub const NUM_BEST_ROOT_MOVES_TO_SEARCH_FIRST: usize = 3;
241
242    #[rustfmt::skip]
243    pub static MVV_LVA: [[MoveWeight; 6]; 6] = [
244        [105, 205, 305, 405, 505, 605],
245        [104, 204, 304, 404, 504, 604],
246        [103, 203, 303, 403, 503, 603],
247        [102, 202, 302, 402, 502, 602],
248        [101, 201, 301, 401, 501, 601],
249        [100, 200, 300, 400, 500, 600],
250    ];
251}
252
253pub mod binary {
254    use super::*;
255
256    pub const DEFAULT_SELFPLAY_COMMAND: SearchConfig =
257        SearchConfig::from_go_command(GoCommand::from_millis(3000));
258}
259
260pub mod io {
261    use super::*;
262
263    pub const COMMUNICATION_CHECK_INTERVAL: Duration = Duration::from_millis(1);
264}
265
266pub mod atomic {
267    pub const MEMORY_ORDERING: std::sync::atomic::Ordering = std::sync::atomic::Ordering::Relaxed;
268}
269
270pub mod color {
271    use super::*;
272
273    pub const NUM_COLORS: usize = 2;
274    pub static ALL_COLORS: [Color; NUM_COLORS] = [Black, White];
275}
276
277pub mod piece {
278    use super::*;
279
280    pub const NUM_PIECE_TYPES: usize = 6;
281    pub static ALL_PIECE_TYPES: [PieceType; NUM_PIECE_TYPES] =
282        [Pawn, Knight, Bishop, Rook, Queen, King];
283    pub static ALL_PIECES: [Piece; NUM_PIECE_TYPES * NUM_COLORS] = [
284        WhitePawn,
285        WhiteKnight,
286        WhiteBishop,
287        WhiteRook,
288        WhiteQueen,
289        WhiteKing,
290        BlackPawn,
291        BlackKnight,
292        BlackBishop,
293        BlackRook,
294        BlackQueen,
295        BlackKing,
296    ];
297    pub const NUM_PROMOTION_PIECES: usize = 4;
298    pub static PROMOTION_PIECES: [PieceType; NUM_PROMOTION_PIECES] = [Queen, Knight, Rook, Bishop];
299}
300
301pub mod ranks {
302    use super::*;
303
304    pub const NUM_RANKS: usize = 8;
305    pub static ALL_RANKS: [Rank; NUM_RANKS] = [
306        Rank::First,
307        Rank::Second,
308        Rank::Third,
309        Rank::Fourth,
310        Rank::Fifth,
311        Rank::Sixth,
312        Rank::Seventh,
313        Rank::Eighth,
314    ];
315}
316
317pub mod files {
318    use super::*;
319
320    pub const NUM_FILES: usize = 8;
321    pub static ALL_FILES: [File; NUM_FILES] = [
322        File::A,
323        File::B,
324        File::C,
325        File::D,
326        File::E,
327        File::F,
328        File::G,
329        File::H,
330    ];
331}
332
333pub mod default_parameters {
334    use super::*;
335
336    pub const TIMECAT_DEFAULTS: TimecatDefaults = TimecatDefaults {
337        #[cfg(feature = "colored")]
338        colored: true,
339        console_mode: cfg!(feature = "debug"),
340        t_table_size: CacheTableSize::Exact(16),
341        long_algebraic_notation: false,
342        num_threads: NonZeroUsize::new(1).unwrap(),
343        move_overhead: Duration::from_millis(10),
344        use_own_book: false,
345        book_path: None,
346        inbuilt_book_bytes: None,
347        debug_mode: true,
348        chess960_mode: false,
349    };
350}