Answers.Body: <p>Pinned pieces only exist when attackers are sliding pieces (bishop, rook, queen). Also pinned pieces can move along the attack ray to the king, you cannot exclude them from legal moves directly. For example, the rook can move d4 and d6 in the board image below and the pawn can do enpassant in the 2nd example. You can check all 8 directions N, W, E, S, NW, NE, SW, SE to get all pinned pieces.</p>
  <p>A piece is pinned if it suits the rules below.</p>
  <ul>
  <li>It is a friend piece</li>
  <li>It is the closest piece to the friend king placed on the path from king to the end of the board on specific direction (NORTH, SOUTH-EAST etc.)</li>
  <li>The second closest piece after the friend is the enemy and can attack along the direction to the king. Rook and queen for the N-S-W-E. Bishop and queen for NW-NE-SW-SE.</li>
  <li><code>UnpinnedMoves</code> = <code>Pseudolegalmoves(pinned_piece)</code> &amp; <code>PathFromKingToTheEnemy</code></li>
  </ul>
  <p>For example I have shared my code to find the pinned piece on the NORTH. A8 is LSB and H1 is MSB in my bitboard. You can change <code>BitScanReverse()</code> into <code>BitScanForward()</code> according to your bitboard design and direction that is checking for pinned piece. (for south it must be <code>BitScanForward()</code> in my code)</p>
  <p><a href="https://i.sstatic.net/5eWgr.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/5eWgr.png" alt="enter image description here" /></a></p>
  <p><a href="https://i.sstatic.net/65UnK.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/65UnK.png" alt="enter image description here" /></a></p>
  <pre><code>public static ulong Pinned_NORTH(ulong king_loc, ulong friendPieces, ulong allPieces, ulong rookEnemies, ulong queenEnemies)
  {
      //Gets all vertical sliding enemies
      ulong straightSlidingEnemies = rookEnemies | queenEnemies;
  
      //if no rook or queen enemies exist, there is no pinned piece
      if(straightSlidingEnemies == 0)
         return 0;
  
      //get all squares on the North side of the king
      ulong northSquares= CrossLookup.NORTH[king_loc];
  
      //get intersected pieces at the north side of the king, rook and queen in the example
      ulong intersectedPieces = northSquares&amp; allPieces;
  
      //get closest piece to the king in intersectedPieces, rook in the example
      ulong closestPiece = intersectedPieces.BitScanReverse();
  
      //check if the closest piece is our friend
      ulong friend = closestPiece &amp; friendPieces;
  
      //if it is ENEMY, there cannot be a pinned piece in the NORTH
      if (friend == 0)
          return 0;
  
      //Get second closest piece and check if it is an enemy that is a rook or a queen who can attack from the NORTH
      ulong slidingEnemy = (intersectedPieces &amp; ~closestPiece ).BitScanReverse() &amp; straightSlidingEnemies ;
  
      //if it is NOT A SLIDING ENEMY, there cannot be a pinned piece in the NORTH
      if (slidingEnemy == 0)
          return 0;
      
      //Otherwise closest piece is a pinned piece and can only move along the ray from king to the enemy
      return friend;
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-11-27T21:26:48.143Z
Answers.LastActivityDate: 2021-11-27T22:44:16.307Z
Answers.LastEditDate: 2021-11-27T22:44:16.307Z
Answers.UserDisplayName: Ali Tor
Answers.Body: <p>This task is nontrivial and cannot be obtained easily or setwise from the available bitboards.</p>
  
  <p>The following solution is an example for how such a task might be done for a generic slider - only obvious substitutions are necessary to convert this code to be usable for bishops, rooks and queens.</p>
  
  <p>First, identify the set of possible pinn<strong>ing</strong> pieces by calculating sliding attacks <em>from the king square</em>, using the opposite side as the set of occupied squares.</p>
  
  <pre><code>BitBoard bb_pinners = slider_moves(king_square, bb_other_side) &amp; bb_other_side;
  </code></pre>
  
  <p>All bitboard engines should have some function similar to <code>bishop_moves</code> or <code>rook_moves</code>, which uses magic bitboards, PEXT or Koch-Stone to generate sliding moves from a square, given a bitboard of occupied squares as blockers to the slider. </p>
  
  <p>To determine the set of pinned pieces from the set of pinners, it is necessary to iterate through the set of possible pinners (this is why pinned pieces cannot be calculated setwise).</p>
  
  <p>For each pinner, we consider the set of bits between the pinner square and the king square (using the utility function <code>between</code>), determine if there is only one bit set, and if so, add that bit to the set of pinned pieces.</p>
  
  <pre><code>BitBoard bb_pinned = 0;
  while(bb_pinners) {
      Square sq = pop_bit(bb_pinners);
      BitBoard bb_possible_pinned = between(sq, king_square) &amp; bb_own_side;
      if(only_one_bit(bb_possible_pinned)) {
          bb_pinned |= bb_possible_pinned;
      }
  }
  </code></pre>
  
  <p>Here, <code>pop_bit</code> finds the index of and removes the least significant bit of bb_pinners.</p>
  
  <p>Stockfish implements a similar strategy in <a href="https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp#L486-L509" rel="noreferrer"><code>slider_blockers</code></a> to determine possibly pinned pieces.</p>
  
  <p>It is also worth mentioning that even with a set of these blockers, this does not mean that they may be excluded from legal move generation because if the pinned piece is a slider itself of the correct type, it may still have legal moves despite being pinned, under the above algorithm's definition.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-16T17:44:32.950Z
Answers.LastActivityDate: 2019-08-16T17:44:32.950Z
Answers.UserDisplayName: konsolas
Body: <p>I'm currently working on a chess engine and have a pseudo-legal move generator working. I'm looking for a way to efficiently generate a bitboard of pinned pieces, so I could skip them when generating legal moves. How would one go about doing this, given 12 bitboards for each piece, and a bitboard called UNSAFE with all the squares the opponent is threatening?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-11-27T21:56:44.543Z
Comments.Text: All the answers below are probably correct but I can tell you that if you want a strong engine, you are looking in the wrong place.
  
  I am one of the authors of Koivisto (depending on the rating list, somewhere in between the top 4-10 engines in the world). We still use pseudo legal move generation and check if they are legal. move generation, compared to evaluation, move ordering etc. is almost insignificant.
Comments.UserDisplayName: Finn Eggers
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-11-29T21:18:56.267Z
Comments.Text: Hi Finn! It's great hearing from you - I've been a fan ever since your neural networks tutorial on youtube :) Koivisto is really doing great recently - what was the change that brought you up from 3407 to 3445 (CCRL 40/15)? Thank you for the information - I ended up doing something similar to that, but I'm only testing certain moves for legality (when in check, en passant, moving a pinned piece, and when the king moves)
Comments.UserDisplayName: Ori Yonay
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-11-30T06:05:11.973Z
Comments.Text: That makes me happy to hear.  I assume you mean the difference between 6.0 and 7.0. most of it comes from slight search adjustments. We also retrained a new network with more data and a different architecture. You can also add me on Discord if you have more questions :) (Luecx#0540)
Comments.UserDisplayName: Finn Eggers
Tags: <engines><programming><pins><bitboard>
Title: Chess Engine: Generate a Bitboard of Pinned Pieces
ThreadText: # Chess Engine: Generate a Bitboard of Pinned Pieces
  
  (Asked by: username_0 on 2019-08-15)
  
  I'm currently working on a chess engine and have a pseudo-legal move generator working. I'm looking for a way to efficiently generate a bitboard of pinned pieces, so I could skip them when generating legal moves. How would one go about doing this, given 12 bitboards for each piece, and a bitboard called UNSAFE with all the squares the opponent is threatening?
  
  **Tags:** engines, programming, pins, bitboard
  
  > **Comments:**
  > **username_1**: All the answers below are probably correct but I can tell you that if you want a strong engine, you are looking in the wrong place.  I am one of the authors of Koivisto (depending on the rating list, somewhere in between the top 4-10 engines in the world). We still use pseudo legal move generation and check if they are legal. move generation, compared to evaluation, move ordering etc. is almost insignificant.  
  > **username_0**: Hi username_1! It's great hearing from you - I've been a fan ever since your neural networks tutorial on youtube :) Koivisto is really doing great recently - what was the change that brought you up from 3407 to 3445 (CCRL 40/15)? Thank you for the information - I ended up doing something similar to that, but I'm only testing certain moves for legality (when in check, en passant, moving a pinned piece, and when the king moves)  
  > **username_1**: That makes me happy to hear.  I assume you mean the difference between 6.0 and 7.0. most of it comes from slight search adjustments. We also retrained a new network with more data and a different architecture. You can also add me on Discord if you have more questions :) (Luecx#0540)  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_3 on 2019-08-16. Score: 6 | Accepted answer
  
  This task is nontrivial and cannot be obtained easily or setwise from the available bitboards.
  
  The following solution is an example for how such a task might be done for a generic slider - only obvious substitutions are necessary to convert this code to be usable for bishops, rooks and queens.
  
  First, identify the set of possible pinn**ing** pieces by calculating sliding attacks *from the king square*, using the opposite side as the set of occupied squares.
  
  ```
  BitBoard bb_pinners = slider_moves(king_square, bb_other_side) & bb_other_side;
  
  ```
  
  All bitboard engines should have some function similar to `bishop_moves` or `rook_moves`, which uses magic bitboards, PEXT or Koch-Stone to generate sliding moves from a square, given a bitboard of occupied squares as blockers to the slider.
  
  To determine the set of pinned pieces from the set of pinners, it is necessary to iterate through the set of possible pinners (this is why pinned pieces cannot be calculated setwise).
  
  For each pinner, we consider the set of bits between the pinner square and the king square (using the utility function `between`), determine if there is only one bit set, and if so, add that bit to the set of pinned pieces.
  
  ```
  BitBoard bb_pinned = 0;
  while(bb_pinners) {
      Square sq = pop_bit(bb_pinners);
      BitBoard bb_possible_pinned = between(sq, king_square) & bb_own_side;
      if(only_one_bit(bb_possible_pinned)) {
          bb_pinned |= bb_possible_pinned;
      }
  }
  
  ```
  
  Here, `pop_bit` finds the index of and removes the least significant bit of bb\_pinners.
  
  Stockfish implements a similar strategy in [`slider_blockers`](https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp#L486-L509) to determine possibly pinned pieces.
  
  It is also worth mentioning that even with a set of these blockers, this does not mean that they may be excluded from legal move generation because if the pinned piece is a slider itself of the correct type, it may still have legal moves despite being pinned, under the above algorithm's definition.
  
  
  ---
  
  ### Answer by username_2 on 2021-11-27. Score: 2
  
  Pinned pieces only exist when attackers are sliding pieces (bishop, rook, queen). Also pinned pieces can move along the attack ray to the king, you cannot exclude them from legal moves directly. For example, the rook can move d4 and d6 in the board image below and the pawn can do enpassant in the 2nd example. You can check all 8 directions N, W, E, S, NW, NE, SW, SE to get all pinned pieces.
  
  A piece is pinned if it suits the rules below.
  
  * It is a friend piece
  * It is the closest piece to the friend king placed on the path from king to the end of the board on specific direction (NORTH, SOUTH-EAST etc.)
  * The second closest piece after the friend is the enemy and can attack along the direction to the king. Rook and queen for the N-S-W-E. Bishop and queen for NW-NE-SW-SE.
  * `UnpinnedMoves` = `Pseudolegalmoves(pinned_piece)` & `PathFromKingToTheEnemy`
  
  For example I have shared my code to find the pinned piece on the NORTH. A8 is LSB and H1 is MSB in my bitboard. You can change `BitScanReverse()` into `BitScanForward()` according to your bitboard design and direction that is checking for pinned piece. (for south it must be `BitScanForward()` in my code)
  
  [![enter image description here](https://i.sstatic.net/5eWgr.png)](https://i.sstatic.net/5eWgr.png)
  
  [![enter image description here](https://i.sstatic.net/65UnK.png)](https://i.sstatic.net/65UnK.png)
  
  ```
  public static ulong Pinned_NORTH(ulong king_loc, ulong friendPieces, ulong allPieces, ulong rookEnemies, ulong queenEnemies)
  {
      //Gets all vertical sliding enemies
      ulong straightSlidingEnemies = rookEnemies | queenEnemies;
  
      //if no rook or queen enemies exist, there is no pinned piece
      if(straightSlidingEnemies == 0)
         return 0;
  
      //get all squares on the North side of the king
      ulong northSquares= CrossLookup.NORTH[king_loc];
  
      //get intersected pieces at the north side of the king, rook and queen in the example
      ulong intersectedPieces = northSquares& allPieces;
  
      //get closest piece to the king in intersectedPieces, rook in the example
      ulong closestPiece = intersectedPieces.BitScanReverse();
  
      //check if the closest piece is our friend
      ulong friend = closestPiece & friendPieces;
  
      //if it is ENEMY, there cannot be a pinned piece in the NORTH
      if (friend == 0)
          return 0;
  
      //Get second closest piece and check if it is an enemy that is a rook or a queen who can attack from the NORTH
      ulong slidingEnemy = (intersectedPieces & ~closestPiece ).BitScanReverse() & straightSlidingEnemies ;
  
      //if it is NOT A SLIDING ENEMY, there cannot be a pinned piece in the NORTH
      if (slidingEnemy == 0)
          return 0;
      
      //Otherwise closest piece is a pinned piece and can only move along the ray from king to the enemy
      return friend;
  }
  
  ```
  
  
  ---
  
  