Pārlūkot izejas kodu

reducing mov struct size

Nicolas Winkler 2 gadi atpakaļ
vecāks
revīzija
646d1dd3ca
3 mainītis faili ar 86 papildinājumiem un 41 dzēšanām
  1. 1 1
      src/evaluate.rs
  2. 15 7
      src/game.rs
  3. 70 33
      src/movegen.rs

+ 1 - 1
src/evaluate.rs

@@ -217,7 +217,7 @@ pub fn evaluate(game: &Game) -> PosValue {
 
 pub fn game_lateness(game: &Game) -> i32 {
     let all_pieces = game.get_all_side(WHITE) | game.get_all_side(BLACK);
-    let n_pieces = all_pieces.count_ones();
+    let n_pieces = all_pieces.count_ones() as i32;
     let captured_pieces = 32 - n_pieces;
 
     if captured_pieces > 15 {

+ 15 - 7
src/game.rs

@@ -217,7 +217,7 @@ impl Game {
                     if piece_type != PAWN {
                         return Err(());
                     }
-                    Ok(Move::Promotion{ mov: SimpleMove{ from, to }, promote_to, captured })
+                    Ok(Move::Promotion{ mov: SimpleMove{ from, to }, pc: PieceCaptureType::new(promote_to, captured) })
                 }
                 else {
                     if piece_type == KING && (from as i32 - to as i32).abs() == 2 {
@@ -238,7 +238,7 @@ impl Game {
                     }
 
                     //println!("pt: {}", piece_type);
-                    Ok(Move::Default{ mov: SimpleMove{ from, to }, piece_type, captured })
+                    Ok(Move::Default{ mov: SimpleMove{ from, to }, pc: PieceCaptureType::new(piece_type, captured) })
                 }
             }
             else {
@@ -578,7 +578,6 @@ impl Game {
     }
 
     pub fn apply(&mut self, mov: Move) -> MoveUndo {
-
         /*if !self.is_zobrist_correct() {
             println!("{}", self.beautiful_print());
             println!("incorrect zobrist before apply {} {:?}", mov.to_string(), mov);
@@ -601,7 +600,8 @@ impl Game {
         let others = self.get_all_side(!side);
 
         match mov {
-            Move::Default{ mov, piece_type: pt, captured: _ } => {
+            Move::Default{ mov, pc } => {
+                let pt = pc.piece_type();
 
                 if pt == KING {
                     // invalidate castling rights
@@ -704,7 +704,9 @@ impl Game {
                     panic!("internal en passant error");
                 }
             },
-            Move::Promotion { mov, promote_to, captured } => {
+            Move::Promotion { mov, pc } => {
+                let promote_to = pc.piece_type();
+                let captured = pc.capture_type();
                 //if from_square(mov.to) & others != 0 {
                 if let Some(pt) = captured {
                     *self.get_piece_mut(pt, !side) &= !from_square(mov.to);
@@ -795,7 +797,10 @@ impl Game {
         // the side that played the turn that is to be reverted
         let side = !self.turn;
         match mov {
-            Move::Default{ mov, piece_type, captured } => {
+            Move::Default{ mov, pc } => {
+                let piece_type = pc.piece_type();
+                let captured = pc.capture_type();
+
                 let moved_piece_bb = self.get_piece_mut(piece_type, side);
                 *moved_piece_bb &= !from_square(mov.to);
                 *moved_piece_bb |= from_square(mov.from);
@@ -851,7 +856,10 @@ impl Game {
                 // should already be reverted
                 //self.en_passant = Some(indices_from_square(beaten).0);
             },
-            Move::Promotion { mov, promote_to, captured } => {
+            Move::Promotion { mov, pc } => {
+                let promote_to = pc.piece_type();
+                let captured = pc.capture_type();
+
                 match promote_to {
                     QUEEN => { *self.queens_mut(side) &= !from_square(mov.to); }
                     ROOK => { *self.rooks_mut(side) &= !from_square(mov.to); }

+ 70 - 33
src/movegen.rs

@@ -3,6 +3,7 @@ use bitboard::Square;
 use bitboard::*;
 use game::Game;
 use hash::{Cache, EntryType};
+use std::f32::consts::PI;
 use std::iter::Iterator;
 
 use crate::evaluate::evaluate;
@@ -30,11 +31,14 @@ pub struct SimpleMove {
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct PieceCaptureType(u8);
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum Move {
-    Default { mov: SimpleMove, piece_type: PieceType, captured: Option<PieceType> },
+    Default { mov: SimpleMove, pc: PieceCaptureType },
     Castling { side: Side, left: bool },
     EnPassant { mov: SimpleMove, beaten: Square },
-    Promotion { mov: SimpleMove, promote_to: PieceType, captured: Option<PieceType> },
+    Promotion { mov: SimpleMove, pc: PieceCaptureType },
     Nullmove
 }
 
@@ -47,6 +51,38 @@ pub struct MoveUndo {
     pub mov: Move
 }
 
+impl PieceCaptureType {
+
+    pub fn new(piece_type: PieceType, capture_type: Option<PieceType>) -> Self {
+        if piece_type > KING {
+            panic!("ILLEGAL PIECE");
+        }
+        let upper = piece_type << 4;
+        let lower = capture_type.unwrap_or(0xF);
+        PieceCaptureType(upper | lower)
+    }
+
+    pub fn piece_type(&self) -> PieceType {
+        (self.0 >> 4) as PieceType
+    }
+
+    pub fn capture_type(&self) -> Option<PieceType> {
+        let ct = (self.0 & 0xF) as PieceType;
+        
+        if ct == 0xF {
+            None
+        }
+        else {
+            Some(ct)
+        }
+    }
+
+    pub fn has_capture(&self) -> bool {
+        let ct = (self.0 >> 4) as PieceType;
+        ct != 0xF
+    }
+}
+
 impl Default for Move {
     fn default() -> Move {
         Move::Nullmove
@@ -81,7 +117,7 @@ impl Move {
 
     pub fn to_string(&self) -> String {
         match self {
-            Move::Default{ mov, piece_type: _pt, captured: _c } => {
+            Move::Default{ mov, pc: _} => {
                 Self::square_to_string(mov.from) + &Self::square_to_string(mov.to)
             },
             Move::Castling{ side, left } => {
@@ -103,12 +139,13 @@ impl Move {
             Move::EnPassant{ mov, beaten: _ } => {
                 Self::square_to_string(mov.from) + &Self::square_to_string(mov.to)
             },
-            Move::Promotion{ mov, promote_to, captured: _c } => {
+            Move::Promotion{ mov, pc } => {
+                let promote_to = pc.piece_type();
                 Self::square_to_string(mov.from) + &Self::square_to_string(mov.to) + 
-                if *promote_to == QUEEN { "q" }
-                else if *promote_to == ROOK { "r" }
-                else if *promote_to == KNIGHT { "n" }
-                else if *promote_to == BISHOP { "b" }
+                if promote_to == QUEEN { "q" }
+                else if promote_to == ROOK { "r" }
+                else if promote_to == KNIGHT { "n" }
+                else if promote_to == BISHOP { "b" }
                 else { "" }
             },
             Move::Nullmove => {
@@ -119,8 +156,8 @@ impl Move {
 
     pub fn is_capture(&self) -> bool {
         match self {
-            Move::Default{ mov: _, piece_type: _, captured: c } => c.is_some(),
-            Move::Promotion{ mov: _, promote_to: _, captured: c } => c.is_some(),
+            Move::Default{ mov: _, pc } => pc.capture_type().is_some(),
+            Move::Promotion{ mov: _, pc } => pc.capture_type().is_some(),
             Move::EnPassant{ mov: _, beaten: _ } => true,
             Move::Castling{ side: _, left: _ } => false,
             Move::Nullmove => false
@@ -366,8 +403,8 @@ pub fn generate_legal_moves(game: &mut Game, side: Side, captures_only: bool) ->
     let check_legality = |m: &Move| {
         if !check {
             match m {
-                Move::Default { mov, piece_type: _, captured: _ } |
-                Move::Promotion { mov, promote_to: _, captured: _ } => {
+                Move::Default { mov, pc: _ } |
+                Move::Promotion { mov, pc: _ } => {
                     let from = from_square(mov.from);
                     if from & possible_pins == 0 && from != king {
                         return true;
@@ -476,13 +513,13 @@ fn mvv_lva_score(mov: &Move) -> i32 {
     ];
 
     match mov {
-        Move::Default { mov: _, piece_type, captured } => {
-            let attack = PIECE_VALUES[*piece_type as usize];
-            let victim = captured.map(|ct| PIECE_VALUES[ct as usize]).unwrap_or(0);
+        Move::Default { mov: _, pc } => {
+            let attack = PIECE_VALUES[pc.piece_type() as usize];
+            let victim = pc.capture_type().map(|ct| PIECE_VALUES[ct as usize]).unwrap_or(0);
             attack - victim * 5
         },
-        Move::Promotion { mov: _, promote_to: _, captured } => {
-            let victim = captured.map(|ct| PIECE_VALUES[ct as usize]).unwrap_or(0);
+        Move::Promotion { mov: _, pc } => {
+            let victim = pc.capture_type().map(|ct| PIECE_VALUES[ct as usize]).unwrap_or(0);
             PIECE_VALUES[PAWN as usize] - victim * 5
         },
         _ => 0
@@ -521,7 +558,7 @@ fn generate_pawn_pushes(game: &Game, side: Side, move_list: &mut Vec<Move>) {
             WHITE => south_one(p),
             BLACK => north_one(p)
         };
-        move_list.push(Move::Default { mov: SimpleMove { from: square(origin), to: square(p) }, piece_type: PAWN, captured: None });
+        move_list.push(Move::Default { mov: SimpleMove { from: square(origin), to: square(p) }, pc: PieceCaptureType::new(PAWN, None) });
     }
 }
 
@@ -544,7 +581,7 @@ fn generate_pawn_doublepushes(game: &Game, side: Side, move_list: &mut Vec<Move>
             WHITE => south_one(south_one(p)),
             BLACK => north_one(north_one(p))
         };
-        move_list.push(Move::Default { mov: SimpleMove { from: square(origin), to: square(p) }, piece_type: PAWN, captured: None });
+        move_list.push(Move::Default { mov: SimpleMove { from: square(origin), to: square(p) }, pc: PieceCaptureType::new(PAWN, None) });
     }
 }
 
@@ -570,12 +607,12 @@ fn generate_pawn_captures(game: &Game, side: Side, move_list: &mut Vec<Move>) {
                 let captured = game.find_piece(*cap);
                 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, captured: captured });
-                    move_list.push(Move::Promotion { mov: simple_move, promote_to: ROOK, captured: captured });
-                    move_list.push(Move::Promotion { mov: simple_move, promote_to: BISHOP, captured: captured });
-                    move_list.push(Move::Promotion { mov: simple_move, promote_to: KNIGHT, captured: captured });
+                    move_list.push(Move::Promotion { mov: simple_move, pc: PieceCaptureType::new(QUEEN, captured) });
+                    move_list.push(Move::Promotion { mov: simple_move, pc: PieceCaptureType::new(KNIGHT, captured) });
+                    move_list.push(Move::Promotion { mov: simple_move, pc: PieceCaptureType::new(ROOK, captured) });
+                    move_list.push(Move::Promotion { mov: simple_move, pc: PieceCaptureType::new(BISHOP, captured) });
                 } else {
-                    move_list.push(Move::Default { mov: simple_move, piece_type: PAWN, captured: captured });
+                    move_list.push(Move::Default { mov: simple_move, pc: PieceCaptureType::new(PAWN, captured) });
                 }
             }
         }
@@ -601,10 +638,10 @@ fn generate_promotions(game: &Game, side: Side, move_list: &mut Vec<Move>) {
         };
         let movement = SimpleMove { from: square(origin), to: square(p) };
         //move_list.push(Move::Default { mov: SimpleMove { from: square(origin), to: square(p) }, piece_type: PAWN });
-        move_list.push(Move::Promotion { mov: movement, promote_to: QUEEN, captured: None });
-        move_list.push(Move::Promotion { mov: movement, promote_to: ROOK, captured: None });
-        move_list.push(Move::Promotion { mov: movement, promote_to: BISHOP, captured: None });
-        move_list.push(Move::Promotion { mov: movement, promote_to: KNIGHT, captured: None });
+        move_list.push(Move::Promotion { mov: movement, pc: PieceCaptureType::new(QUEEN, None) });
+        move_list.push(Move::Promotion { mov: movement, pc: PieceCaptureType::new(KNIGHT, None) });
+        move_list.push(Move::Promotion { mov: movement, pc: PieceCaptureType::new(ROOK, None) });
+        move_list.push(Move::Promotion { mov: movement, pc: PieceCaptureType::new(BISHOP, None) });
     }
 }
 
@@ -657,12 +694,12 @@ fn generate_knight_moves(game: &Game, side: Side, move_list: &mut Vec<Move>, cap
         for target in cap_targets {
             let simple_move = SimpleMove { from: square(k), to: square(target) };
             let captured = game.find_piece(target);
-            move_list.push(Move::Default{ mov: simple_move, piece_type: KNIGHT, captured });
+            move_list.push(Move::Default{ mov: simple_move, pc: PieceCaptureType::new(KNIGHT, captured) });
         }
         if !captures_only {
             for target in nocap_targets {
                 let simple_move = SimpleMove { from: square(k), to: square(target) };
-                move_list.push(Move::Default{ mov: simple_move, piece_type: KNIGHT, captured: None });
+                move_list.push(Move::Default{ mov: simple_move, pc: PieceCaptureType::new(KNIGHT, None) });
             }
         }
     }
@@ -740,10 +777,10 @@ fn generate_sliding_moves(game: &Game, friends: Bitboard, others: Bitboard, piec
         for dest in dest_iter {
             let smove = SimpleMove{ from: square(piece), to: square(dest) };
             if dest & others != 0 {
-                move_list.push(Move::Default { mov: smove, piece_type: piece_type, captured: game.find_piece(dest) });
+                move_list.push(Move::Default { mov: smove, pc: PieceCaptureType::new(piece_type, game.find_piece(dest)) });
             }
             else {
-                move_list.push(Move::Default { mov: smove, piece_type: piece_type, captured: None });
+                move_list.push(Move::Default { mov: smove, pc: PieceCaptureType::new(piece_type, None) });
             }
         }
     }
@@ -818,7 +855,7 @@ fn generate_king_moves(game: &Game, side: Side, move_list: &mut Vec<Move>, captu
     for destination in area_iter {
         let simple_move = SimpleMove{ from: square(king), to: square(destination) };
         let captured = game.find_piece(destination);
-        move_list.push(Move::Default { mov: simple_move, piece_type: KING, captured });
+        move_list.push(Move::Default { mov: simple_move, pc: PieceCaptureType::new(KING, captured) });
     }
 }