diff --git a/src/errors.rs b/src/errors.rs index b177e9e..27e9dbe 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -12,8 +12,8 @@ pub enum SyzygyError { /// Position has castling rights, but Syzygy tables do not contain /// positions with castling rights. Castling, - /// Position has too many pieces. Syzygy tables only support up to - /// 6 or 7 pieces. + /// Position has too many pieces, i.e., more pieces than any opened table. + /// Syzygy tables for standard chess support up to 7 pieces. TooManyPieces, /// Missing table. MissingTable { diff --git a/src/tablebase.rs b/src/tablebase.rs index 1b49280..a1ba53e 100644 --- a/src/tablebase.rs +++ b/src/tablebase.rs @@ -376,9 +376,14 @@ impl Tablebase { } fn probe<'a>(&'a self, pos: &'a S) -> SyzygyResult> { - if pos.board().occupied().count() > S::MAX_PIECES { + // Probing resolves captures, so sometimes we can obtain results + // for positions that have more pieces than the maximum amount of + // supported pieces. We artificially limit this to one additional + // level, to make sure search remains somewhat bounded. + if pos.board().occupied().count() > S::MAX_PIECES + 1 { return Err(SyzygyError::TooManyPieces); } + if pos.castles().any() { return Err(SyzygyError::Castling); } @@ -629,6 +634,11 @@ impl Tablebase { return Ok(Wdl::Draw); } + // More pieces than any opened table. + if pos.board().occupied().count() > self.max_pieces { + return Err(SyzygyError::TooManyPieces); + } + // Get raw WDL value from the appropriate table. let key = Material::from_board(pos.board()); self.wdl_table(&key)