Browse Source

improved legality check

Nicolas Winkler 2 years ago
parent
commit
9cdad1e5d7
1 changed files with 34 additions and 19 deletions
  1. 34 19
      src/movegen.rs

+ 34 - 19
src/movegen.rs

@@ -310,24 +310,34 @@ pub fn generate_legal_moves_old(game: &mut Game, side: Side) -> Vec<Move> {
     moves.into_iter().filter(check_legality).collect::<Vec<Move>>()
 }
 
-fn generate_all_slides(origin: Bitboard) -> Bitboard {
-    let mut result = populate_files(origin) | populate_rows(origin);
-
-    let mut ne = origin;
-    let mut se = origin;
-    let mut nw = origin;
-    let mut sw = origin;
-    for _ in 1..7 {
-        result |= ne;
-        result |= se;
-        result |= nw;
-        result |= sw;
-        ne = northeast_one(ne);
-        se = southeast_one(se);
-        nw = northwest_one(nw);
-        sw = southwest_one(sw);
-    }
-    return result;
+fn possibly_pinned_pieces(king: Bitboard, friends: Bitboard, enemies: Bitboard) -> Bitboard {
+    let check_ray = |ray_func: fn(Bitboard) -> Bitboard| -> Bitboard {
+        let mut pos = king;
+        let mut ray = king;
+        let mut one_friend = false;
+        for _ in 0..7 {
+            pos = ray_func(pos);
+            if pos & friends != 0 && !one_friend {
+                one_friend = true;
+            } else if pos & friends != 0 && one_friend {
+                return 0;
+            } else if pos & enemies != 0 && one_friend {
+                return ray;
+            }
+            ray |= pos;
+        }
+        return 0;
+    };
+
+    return
+          check_ray(north_one)
+          | check_ray(south_one)
+          | check_ray(east_one)
+          | check_ray(west_one)
+          | check_ray(northeast_one)
+          | check_ray(northwest_one)
+          | check_ray(southeast_one)
+          | check_ray(southwest_one);
 }
 
 
@@ -341,7 +351,7 @@ pub fn generate_legal_moves(game: &mut Game, side: Side, captures_only: bool) ->
 
     let check = is_check(game, side);
     let king = game.kings(side);
-    let possible_pins = generate_all_slides(king);
+    let possible_pins = possibly_pinned_pieces(king, game.get_all_side(side), game.get_all_side(!side));
 
     let check_legality = |m: &Move| {
         if !check {
@@ -352,6 +362,11 @@ pub fn generate_legal_moves(game: &mut Game, side: Side, captures_only: bool) ->
                         return true;
                     }
                 },
+                Move::Promotion { mov, promote_to: _, captured: _ } => {
+                    if from_square(mov.from) & possible_pins == 0 {
+                        return true;
+                    }
+                },
                 _ => {}
             }
         }