diff --git a/src/board.rs b/src/board.rs index ff5031227..4d4f1e7ad 100644 --- a/src/board.rs +++ b/src/board.rs @@ -155,16 +155,14 @@ impl Board { /// ``` #[inline] pub fn status(&self) -> BoardStatus { - let moves = MoveGen::new_legal(&self).len(); - match moves { - 0 => { - if self.checkers == EMPTY { - BoardStatus::Stalemate - } else { - BoardStatus::Checkmate - } + if MoveGen::has_legal_moves(&self) { + BoardStatus::Ongoing + } else { + if self.checkers == EMPTY { + BoardStatus::Stalemate + } else { + BoardStatus::Checkmate } - _ => BoardStatus::Ongoing, } } diff --git a/src/movegen/movegen.rs b/src/movegen/movegen.rs index 8706bc38f..6c05aa57c 100644 --- a/src/movegen/movegen.rs +++ b/src/movegen/movegen.rs @@ -118,6 +118,45 @@ impl MoveGen { movelist } + /// Check whether the board has any legal moves or not + #[inline(always)] + pub fn has_legal_moves(board: &Board) -> bool { + let checkers = *board.checkers(); + let mask = !board.color_combined(board.side_to_move()); + let mut movelist = NoDrop::new(ArrayVec::<[SquareAndBitBoard; 18]>::new()); + + let legal_fns = if checkers == EMPTY { + [ + PawnType::legals:: , + KnightType::legals::, + BishopType::legals::, + RookType::legals:: , + QueenType::legals:: , + KingType::legals:: , + ] + } else if checkers.popcnt() == 1 { + [ + PawnType::legals:: , + KnightType::legals::, + BishopType::legals::, + RookType::legals:: , + QueenType::legals:: , + KingType::legals:: , + ] + } else { + KingType::legals::(&mut movelist, &board, mask); + return movelist.len() != 0 + }; + + for f in legal_fns { + f(&mut movelist, &board, mask); + if movelist.len() != 0 { return true } + movelist.clear(); + } + + return false + } + /// Create a new `MoveGen` structure, only generating legal moves #[inline(always)] pub fn new_legal(board: &Board) -> MoveGen {