Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ members = [
"tuner",
"uci",
]
resolver = "2"
resolver = "3"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Fatalii supports both standard chess and Chess960 (a.k.a. Fischer Random Chess).
- Mobility
- Bishop pair
- Tempo
- King tropism
- Piece positions relative to both kings
- Tapered evaluation for all parameters
- Tuned with training positions from the
[Zurichess dataset quiet-labeled.v7](https://bitbucket.org/zurichess/tuner/downloads/quiet-labeled.v7.epd.gz)
Expand Down
4 changes: 2 additions & 2 deletions engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
name = "engine"
version = "0.1.0"
authors = ["Patrick Heck <49785565+FitzOReilly@users.noreply.github.com>"]
edition = "2021"
edition = "2024"

[dependencies]
crossbeam-channel = "0.5"
thiserror = "2.0.11"
thiserror = "2.0.18"
movegen = { path = "../movegen" }
search = { path = "../search" }

Expand Down
63 changes: 34 additions & 29 deletions engine/src/best_move_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::engine_out::EngineOut;
use crossbeam_channel::Receiver;
use movegen::r#move::Move;
use movegen::side::Side;
use search::search::SearchResult;
use search::SearchOptions;
use search::search::SearchResult;
use std::sync::{Arc, Mutex};
use std::thread;

Expand All @@ -20,40 +20,45 @@ impl BestMoveHandler {
let mut side_to_move = None;
let mut best_move = None;

let thread = thread::spawn(move || loop {
let message = receiver.recv().expect("Error receiving BestMoveCommand");
match message {
BestMoveCommand::SetOptions(new_options) => match options.lock() {
Ok(mut opt) => *opt = *new_options,
Err(e) => panic!("{}", e),
},
BestMoveCommand::SetSideToMove(s) => side_to_move = s,
BestMoveCommand::DepthFinished(res) => engine_out
.info_depth_finished(Self::search_result_to_relative(Some(res), side_to_move))
.expect("Error writing search info"),
BestMoveCommand::Stop(StopReason::Command) => {
match options.lock() {
Ok(mut opt) => opt.infinite = false,
let thread = thread::spawn(move || {
loop {
let message = receiver.recv().expect("Error receiving BestMoveCommand");
match message {
BestMoveCommand::SetOptions(new_options) => match options.lock() {
Ok(mut opt) => *opt = *new_options,
Err(e) => panic!("{}", e),
},
BestMoveCommand::SetSideToMove(s) => side_to_move = s,
BestMoveCommand::DepthFinished(res) => engine_out
.info_depth_finished(Self::search_result_to_relative(
Some(res),
side_to_move,
))
.expect("Error writing search info"),
BestMoveCommand::Stop(StopReason::Command) => {
match options.lock() {
Ok(mut opt) => opt.infinite = false,
Err(e) => panic!("{}", e),
}
engine_out
.best_move(best_move.take())
.expect("Error writing best move");
}
engine_out
.best_move(best_move.take())
.expect("Error writing best move");
}
BestMoveCommand::Stop(StopReason::Finished(new_best_move)) => {
best_move = Some(new_best_move);
match options.lock() {
Ok(opt) => {
if !opt.infinite {
engine_out
.best_move(best_move.take())
.expect("Error writing best move");
BestMoveCommand::Stop(StopReason::Finished(new_best_move)) => {
best_move = Some(new_best_move);
match options.lock() {
Ok(opt) => {
if !opt.infinite {
engine_out
.best_move(best_move.take())
.expect("Error writing best move");
}
}
Err(e) => panic!("{}", e),
}
Err(e) => panic!("{}", e),
}
BestMoveCommand::Terminate => break,
}
BestMoveCommand::Terminate => break,
}
});

Expand Down
4 changes: 2 additions & 2 deletions engine/src/engine.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::best_move_handler::{BestMoveCommand, BestMoveHandler, StopReason};
use crate::engine_out::EngineOut;
use crate::{EngineOptions, Variant};
use crossbeam_channel::{unbounded, Sender};
use crossbeam_channel::{Sender, unbounded};
use movegen::position::Position;
use movegen::position_history::PositionHistory;
use movegen::side::Side;
use search::SearchOptions;
use search::search::{Search, SearchInfo};
use search::search_params::SearchParamsOptions;
use search::searcher::Searcher;
use search::SearchOptions;
use std::sync::{Arc, Mutex};
use std::time::Duration;

Expand Down
2 changes: 1 addition & 1 deletion engine/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use crate::engine::{Engine, EngineError};
pub use crate::engine_options::{
EngineOptions, Variant, DEFAULT_HASH_BYTES, DEFAULT_HASH_MB, DEFAULT_MOVE_OVERHEAD_MILLIS,
DEFAULT_HASH_BYTES, DEFAULT_HASH_MB, DEFAULT_MOVE_OVERHEAD_MILLIS, EngineOptions, Variant,
};
pub use crate::engine_out::EngineOut;

Expand Down
30 changes: 17 additions & 13 deletions engine/tests/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use mock_engine_out::MockEngineOut;
use more_asserts::assert_le;
use movegen::position::Position;
use movegen::position_history::PositionHistory;
use search::alpha_beta::AlphaBeta;
use search::SearchOptions;
use search::alpha_beta::AlphaBeta;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
Expand Down Expand Up @@ -38,12 +38,14 @@ fn search_timeout() {
let tol = 80;

let start = Instant::now();
assert!(engine
.search(SearchOptions {
movetime: Some(movetime),
..Default::default()
})
.is_ok());
assert!(
engine
.search(SearchOptions {
movetime: Some(movetime),
..Default::default()
})
.is_ok()
);
assert!(receiver.recv_timeout(waittime).is_ok());
let stop = Instant::now();
assert_le!(
Expand Down Expand Up @@ -75,12 +77,14 @@ fn search_timeout_aborted() {
let tol = 80;

let start = Instant::now();
assert!(engine
.search(SearchOptions {
movetime: Some(movetime),
..Default::default()
})
.is_ok());
assert!(
engine
.search(SearchOptions {
movetime: Some(movetime),
..Default::default()
})
.is_ok()
);
thread::sleep(sleeptime);
engine.stop();
assert!(receiver.recv_timeout(waittime).is_ok());
Expand Down
4 changes: 2 additions & 2 deletions eval/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "eval"
version = "0.1.0"
authors = ["Patrick Heck <49785565+FitzOReilly@users.noreply.github.com>"]
edition = "2021"
edition = "2024"

[dependencies]
movegen = { path = "../movegen" }
Expand All @@ -11,4 +11,4 @@ movegen = { path = "../movegen" }
trace = []

[dev-dependencies]
rand = "0.9.2"
rand = "0.10.0"
8 changes: 4 additions & 4 deletions eval/src/hand_crafted_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::hand_crafted_eval_coeffs::{Coeff, HandCraftedEvalCoeffs};
use crate::params;
use crate::piece_table_refs::PIECE_TABLE_REFS;
use crate::score_pair::ScorePair;
use crate::{Eval, Score, EQ_POSITION};
use crate::{EQ_POSITION, Eval, Score};
use movegen::bishop::Bishop;
use movegen::bitboard::Bitboard;
use movegen::file::File;
Expand Down Expand Up @@ -557,12 +557,12 @@ impl HandCraftedEval {
#[cfg(test)]
mod tests {
use movegen::{
fen::Fen, move_generator::MoveGenerator, position::Position,
position_history::PositionHistory, r#move::MoveList,
fen::Fen, r#move::MoveList, move_generator::MoveGenerator, position::Position,
position_history::PositionHistory,
};
use rand::seq::{IndexedMutRandom, SliceRandom};

use crate::{Eval, EQ_POSITION};
use crate::{EQ_POSITION, Eval};

use super::HandCraftedEval;

Expand Down
2 changes: 1 addition & 1 deletion eval/src/hand_crafted_eval_coeffs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use movegen::{
square::Square,
};

use crate::{params, Score};
use crate::{Score, params};

#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub struct Coeff(pub i8);
Expand Down
2 changes: 1 addition & 1 deletion eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub use crate::game_phase::GamePhase;
pub use crate::hand_crafted_eval::HandCraftedEval;
#[cfg(feature = "trace")]
pub use crate::hand_crafted_eval_coeffs::HandCraftedEvalCoeffs;
pub use crate::score::{Score, ScoreVariant, BLACK_WIN, EQ_POSITION, NEG_INF, POS_INF, WHITE_WIN};
pub use crate::score::{BLACK_WIN, EQ_POSITION, NEG_INF, POS_INF, Score, ScoreVariant, WHITE_WIN};

pub mod eval;
pub mod hand_crafted_eval;
Expand Down
2 changes: 1 addition & 1 deletion eval/src/material_mobility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ impl MaterialMobility {
#[cfg(test)]
mod tests {
use super::*;
use movegen::position_history::PositionHistory;
use movegen::r#move::{Move, MoveType};
use movegen::position_history::PositionHistory;
use movegen::square::Square;

#[test]
Expand Down
2 changes: 1 addition & 1 deletion eval/src/params.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use movegen::{file::File, rank::Rank, square::Square};

use crate::{score_pair::ScorePair, Score};
use crate::{Score, score_pair::ScorePair};

// Piece square tables:
// We use symmetrical PSTs, so we only define values for half the board. Squares
Expand Down
6 changes: 3 additions & 3 deletions fatalii/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "fatalii"
version = "0.10.0-alpha"
edition = "2021"
version = "0.10.0"
edition = "2024"

[dependencies]
engine = { path = "../engine" }
Expand All @@ -11,4 +11,4 @@ uci = { path = "../uci" }

[dev-dependencies]
assert_matches = "1.5.0"
rexpect = "0.6.0"
rexpect = "0.6.3"
4 changes: 2 additions & 2 deletions fatalii/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use engine::{Engine, EngineOptions, DEFAULT_HASH_BYTES};
use engine::{DEFAULT_HASH_BYTES, Engine, EngineOptions};
use eval::HandCraftedEval;
use search::alpha_beta::AlphaBeta;
use std::error::Error;
use std::io;
use std::sync::{Arc, Mutex};
use uci::UciOut;
use uci::uci_in::{
debug, go, is_ready, position, quit, set_option, stop, uci as cmd_uci, ucinewgame,
};
use uci::UciOut;
use uci::{Parser, ParserMessage};

pub fn run() -> Result<(), Box<dyn Error>> {
Expand Down
12 changes: 6 additions & 6 deletions movegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
name = "movegen"
version = "0.1.0"
authors = ["Patrick Heck <49785565+FitzOReilly@users.noreply.github.com>"]
edition = "2021"
edition = "2024"

[dependencies]
bitflags = "2.8.0"
smallvec = "1.13.2"
thiserror = "2.0.11"
bitflags = "2.11.0"
smallvec = "1.15.1"
thiserror = "2.0.18"

[dev-dependencies]
criterion = "0.5.1"
rand = "0.9"
criterion = "0.8.2"
rand = "0.10"

[[bench]]
name = "bench_movegen"
Expand Down
2 changes: 1 addition & 1 deletion movegen/benches/bench_movegen.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput};
use criterion::{BatchSize, BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use movegen::fen::Fen;
use movegen::performance_tester::PerformanceTester;
use movegen::position::Position;
Expand Down
8 changes: 4 additions & 4 deletions movegen/src/fen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,10 @@ impl Fen {
for cur in fen.bytes() {
let cur_castling_right = match cur {
b'K' | b'Q' | b'k' | b'q' if cur == prev => {
return Err(FenError::DuplicateCastlingRights)
return Err(FenError::DuplicateCastlingRights);
}
b'K' | b'Q' | b'k' | b'q' if cur < prev => {
return Err(FenError::WrongCastlingRightOrder)
return Err(FenError::WrongCastlingRightOrder);
}
b'K' => CastlingRights::WHITE_KINGSIDE,
b'Q' => CastlingRights::WHITE_QUEENSIDE,
Expand Down Expand Up @@ -386,7 +386,7 @@ impl Fen {
match king_file.idx().cmp(&castling_file.idx()) {
Ordering::Less => match kingside {
Some(f) if f != castling_file => {
return Err(FenError::InvalidCastlingRights)
return Err(FenError::InvalidCastlingRights);
}
_ => {
kingside = Some(castling_file);
Expand All @@ -400,7 +400,7 @@ impl Fen {
Ordering::Equal => return Err(FenError::InvalidCastlingRights),
Ordering::Greater => match queenside {
Some(f) if f != castling_file => {
return Err(FenError::InvalidCastlingRights)
return Err(FenError::InvalidCastlingRights);
}
_ => {
queenside = Some(castling_file);
Expand Down
4 changes: 2 additions & 2 deletions movegen/src/move_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use crate::move_generator::move_generator_template::MoveGeneratorTemplate;

use crate::attacks_to::AttacksTo;
use crate::bitboard::Bitboard;
use crate::r#move::{Move, MoveList};
use crate::piece;
use crate::position::Position;
use crate::r#move::{Move, MoveList};
use crate::square::Square;

pub struct MoveGenerator;
Expand Down Expand Up @@ -128,9 +128,9 @@ mod tests {

use super::*;
use crate::fen::Fen;
use crate::r#move::{Move, MoveType};
use crate::position::Position;
use crate::position_history::PositionHistory;
use crate::r#move::{Move, MoveType};
use crate::square::Square;
use rand::seq::IndexedMutRandom;

Expand Down
2 changes: 1 addition & 1 deletion movegen/src/move_generator/king_in_check_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::move_generator::move_generator_template::MoveGeneratorTemplate;

use crate::attacks_to::AttacksTo;
use crate::bitboard::Bitboard;
use crate::pawn::Pawn;
use crate::r#move::MoveList;
use crate::pawn::Pawn;
use crate::square::Square;

// In check, the only legal moves are:
Expand Down
Loading