Sfoglia il codice sorgente

got queen move generator working

Nicolas Winkler 6 anni fa
parent
commit
34b7e1699f
3 ha cambiato i file con 50 aggiunte e 3 eliminazioni
  1. 1 0
      src/engine.rs
  2. 42 3
      src/movegen.rs
  3. 7 0
      src/search.rs

+ 1 - 0
src/engine.rs

@@ -31,6 +31,7 @@ pub fn run_engine(r: Receiver<EngineMsg>, s: Sender<InterfaceMsg>) {
     let mut game = Game::default();
     for msg in r {
         game.pieces[0] = 0x00ff_0000_0000_0100;
+        game.pieces[QUEEN as usize] = 0x0000_0000_0000_0080;
         game.pieces[10] = 0x4000_0000_0000_0000;
         let moves = generate_moves(&game, WHITE);
         for mov in moves {

+ 42 - 3
src/movegen.rs

@@ -34,7 +34,7 @@ pub enum Move {
 /**
  * \brief Iterator to serialize bitboard bit for bit
  *
- * Extracts each bit out of the bitboard and returns each one as a separate bitboard.
+ * Extracts every bit out of the bitboard and returns each one as a separate bitboard.
  */
 pub struct BitboardIterator { pub board: Bitboard }
 
@@ -58,7 +58,7 @@ pub fn generate_moves(game: &Game, side: Side) -> Vec<Move> {
     let mut moves: Vec<Move> = Vec::new();
     generate_pawn_pushes(game, side, &mut moves);
     generate_pawn_captures(game, side, &mut moves);
-    generate_bishop_moves(game, side, &mut moves);
+    generate_queen_moves(game, side, &mut moves);
     return moves;
 }
 
@@ -112,7 +112,7 @@ fn generate_pawn_captures(game: &Game, side: Side, move_list: &mut Vec<Move>) {
 
         for cap in [left_cap, right_cap].iter() {
             if cap & others != 0 {
-                let simple_move = SimpleMove { from: pawn.trailing_zeros() as u8, to: cap.trailing_zeros() as u8 };
+                let simple_move = SimpleMove { from: square(pawn), to: square(*cap) };
                 if cap & promotion_mask != 0 {
                     move_list.push(Move::Promotion { mov: simple_move, promote_to: QUEEN });
                     move_list.push(Move::Promotion { mov: simple_move, promote_to: ROOK });
@@ -127,6 +127,45 @@ fn generate_pawn_captures(game: &Game, side: Side, move_list: &mut Vec<Move>) {
 }
 
 
+fn generate_queen_moves(game: &Game, side: Side, move_list: &mut Vec<Move>) {
+    let friends = game.get_all_side(side);
+    let others = game.get_all_side(!side);
+    
+    let queens = BitboardIterator { board: game.queens(side) };
+
+    for queen in queens {
+        let destinations = generate_queen_destinations(friends, others, queen);
+        let dest_iter = BitboardIterator { board: destinations };
+        for dest in dest_iter {
+            let smove = SimpleMove{ from: square(queen), to: square(dest) };
+            move_list.push(Move::Default { mov: smove, piece_type: QUEEN });
+        }
+    }
+}
+
+fn generate_queen_destinations(friends: Bitboard, others: Bitboard,
+                               queen: Bitboard) -> Bitboard {
+    let occupied = friends | others;
+
+    let directions = [north_one, south_one, east_one, west_one,
+                      northeast_one, southeast_one, northwest_one, southwest_one];
+
+    let mut result = 0;
+    for direction in directions.into_iter() {
+        let mut q = queen;
+        loop {
+            q = direction(q);
+            result |= q;
+            if q & (occupied) != 0 || q == 0 {
+                break;
+            }
+        }
+    }
+
+    return result & !friends;
+}
+
+
 #[cfg(test)]
 mod tests {
     use search::Game;

+ 7 - 0
src/search.rs

@@ -25,6 +25,13 @@ impl Game {
         }
     }
 
+    /**
+     * \return bitboard containig all occupied squares
+     */
+    pub fn occupied(&self) -> Bitboard {
+        self.pieces.into_iter().fold(0, |a, b| { a | b } )
+    }
+
     pub fn pawns(&self, side: Side) -> Bitboard {
         match side {
             WHITE => self.pieces[0],