Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Napoleon - movedatabase.cpp

movedatabase.cpp

Caricato da: Crybot
Scarica il programma completo

  1. #include "movedatabase.h"
  2. #include "compassrose.h"
  3. #include "knight.h"
  4. #include "king.h"
  5. #include <cmath>
  6. #include <stdlib.h>
  7.  
  8. namespace Napoleon
  9. {
  10.     BitBoard MoveDatabase::PawnAttacks[2][64]; // color, square
  11.     BitBoard MoveDatabase::KingAttacks[64]; // square
  12.     BitBoard MoveDatabase::KnightAttacks[64]; // square
  13.  
  14.     BitBoard MoveDatabase::RankAttacks[64][64]; // square, occupancy
  15.     BitBoard MoveDatabase::FileAttacks[64][64]; // square, occupancy
  16.     BitBoard MoveDatabase::A1H8DiagonalAttacks[64][64]; // square , occupancy
  17.     BitBoard MoveDatabase::H1A8DiagonalAttacks[64][64]; // square , occupancy
  18.     BitBoard MoveDatabase::PseudoRookAttacks[64]; // square
  19.     BitBoard MoveDatabase::PseudoBishopAttacks[64]; // square
  20.  
  21.     BitBoard MoveDatabase::ObstructedTable[64][64];
  22.  
  23.  
  24.     /* all this operation will be executed before the engine gets active, so it is not needed optimization */
  25.  
  26.     void MoveDatabase::InitAttacks()
  27.     {
  28.         initPawnAttacks();
  29.         initKnightAttacks();
  30.         initKingAttacks();
  31.         initRankAttacks();
  32.         initFileAttacks();
  33.         initDiagonalAttacks();
  34.         initAntiDiagonalAttacks();
  35.         initPseudoAttacks();
  36.         initObstructedTable();
  37.     }
  38.  
  39.     void MoveDatabase::initPawnAttacks()
  40.     {
  41.         for (int sq = 0; sq < 64; sq++)
  42.         {
  43.             PawnAttacks[PieceColor::White][sq] = CompassRose::OneStepNorthEast(Constants::Masks::SquareMask[sq]) | CompassRose::OneStepNorthWest(Constants::Masks::SquareMask[sq]);
  44.             PawnAttacks[PieceColor::Black][sq] = CompassRose::OneStepSouthEast(Constants::Masks::SquareMask[sq]) | CompassRose::OneStepSouthWest(Constants::Masks::SquareMask[sq]);
  45.         }
  46.     }
  47.  
  48.     void MoveDatabase::initKnightAttacks()
  49.     {
  50.         // inizializza l'array di mosse precalcolate
  51.         for (int sq = 0; sq < 64; sq++)
  52.         {
  53.             KnightAttacks[sq] = Knight::GetKnightAttacks(Constants::Masks::SquareMask[sq]);
  54.         }
  55.     }
  56.     void MoveDatabase::initKingAttacks()
  57.     {
  58.         for (int sq = 0; sq < 64; sq++)
  59.         {
  60.             // inizializza l'array di mosse precalcolate
  61.             KingAttacks[sq] = King::GetKingAttacks(Constants::Masks::SquareMask[sq]);
  62.         }
  63.     }
  64.  
  65.     void MoveDatabase::initRankAttacks()
  66.     {
  67.         for (int sq = 0; sq < 64; sq++)
  68.         {
  69.             for (int occ = 0; occ < 64; occ++)
  70.             {
  71.                 int rank = Utils::Square::GetRankIndex(sq);
  72.                 int file = Utils::Square::GetFileIndex(sq);
  73.  
  74.                 BitBoard occupancy = (BitBoard)(occ << 1);
  75.                 BitBoard targets = Constants::Empty;
  76.  
  77.                 int blocker = file + 1;
  78.                 while (blocker <= 7)
  79.                 {
  80.                     targets |= Constants::Masks::SquareMask[blocker];
  81.                     if (Utils::BitBoard::IsBitSet(occupancy, blocker)) break;
  82.  
  83.                     blocker++;
  84.                 }
  85.  
  86.                 blocker = file - 1;
  87.                 while (blocker >= 0)
  88.                 {
  89.                     targets |= Constants::Masks::SquareMask[blocker];
  90.                     if (Utils::BitBoard::IsBitSet(occupancy, blocker)) break;
  91.  
  92.                     blocker--;
  93.                 }
  94.  
  95.                 RankAttacks[sq][occ] = targets << (8 * rank);
  96.             }
  97.         }
  98.     }
  99.     void MoveDatabase::initFileAttacks()
  100.     {
  101.         for (int sq = 0; sq < 64; sq++)
  102.         {
  103.             for (int occ = 0; occ < 64; occ++)
  104.             {
  105.                 BitBoard targets = Constants::Empty;
  106.                 BitBoard rankTargets = RankAttacks[7 - (sq / 8)][occ]; // converte la posizione reale in quella scalare RANK
  107.  
  108.                 for (int bit = 0; bit < 8; bit++) // accede ai singoli bit della traversa (RANK)
  109.                 {
  110.                     int rank = 7 - bit;
  111.                     int file = Utils::Square::GetFileIndex(sq);
  112.  
  113.                     if (Utils::BitBoard::IsBitSet(rankTargets, bit))
  114.                     {
  115.                         targets |= Constants::Masks::SquareMask[Utils::Square::GetSquareIndex(file, rank)];
  116.                     }
  117.                 }
  118.                 FileAttacks[sq][occ] = targets;
  119.             }
  120.         }
  121.     }
  122.  
  123.     void MoveDatabase::initDiagonalAttacks()
  124.     {
  125.  
  126.         for (int sq = 0; sq < 64; sq++)
  127.         {
  128.             for (int occ = 0; occ < 64; occ++)
  129.             {
  130.                 int diag = Utils::Square::GetRankIndex(sq) - Utils::Square::GetFileIndex(sq);
  131.                 BitBoard targets = Constants::Empty;
  132.                 BitBoard rankTargets = diag > 0 ? RankAttacks[sq % 8][occ] : RankAttacks[sq / 8][occ];
  133.                 // converte la posizione reale in quella scalare RANK //
  134.  
  135.                 for (int bit = 0; bit < 8; bit++) // accede ai singoli bit della traversa (RANK)
  136.                 {
  137.                     int rank;
  138.                     int file;
  139.  
  140.                     if (Utils::BitBoard::IsBitSet(rankTargets, bit))
  141.                     {
  142.                         if (diag >= 0)
  143.                         {
  144.                             rank = diag + bit;
  145.                             file = bit;
  146.                         }
  147.                         else
  148.                         {
  149.                             file = bit - diag;
  150.                             rank = bit;
  151.                         }
  152.                         if ((file >= 0) && (file <= 7) && (rank >= 0) && (rank <= 7))
  153.                         {
  154.                             targets |= Constants::Masks::SquareMask[Utils::Square::GetSquareIndex(file, rank)];
  155.                         }
  156.                     }
  157.                 }
  158.  
  159.                 A1H8DiagonalAttacks[sq][occ] = targets;
  160.             }
  161.         }
  162.     }
  163.  
  164.     void MoveDatabase::initAntiDiagonalAttacks()
  165.     {
  166.         for (int sq = 0; sq < 64; sq++)
  167.         {
  168.             for (int occ = 0; occ < 64; occ++)
  169.             {
  170.                 int diag = Utils::Square::GetH1A8AntiDiagonalIndex(sq);
  171.  
  172.                 BitBoard targets = Constants::Empty;
  173.                 BitBoard rankTargets = diag > 7 ? RankAttacks[7 - sq / 8][occ] : RankAttacks[sq % 8][occ];
  174.                 // converte la posizione reale in quella scalare RANK //
  175.  
  176.                 for (int bit = 0; bit < 8; bit++) // accede ai singoli bit della traversa (RANK)
  177.                 {
  178.                     int rank;
  179.                     int file;
  180.  
  181.                     if (Utils::BitBoard::IsBitSet(rankTargets, bit))
  182.                     {
  183.                         if (diag >= 7)
  184.                         {
  185.                             rank = 7 - bit;
  186.                             file = (diag - 7) + bit;
  187.                         }
  188.                         else
  189.                         {
  190.                             rank = diag - bit;
  191.                             file = bit;
  192.                         }
  193.                         if ((file >= 0) && (file <= 7) && (rank >= 0) && (rank <= 7))
  194.                         {
  195.                             targets |= Constants::Masks::SquareMask[Utils::Square::GetSquareIndex(file, rank)];
  196.                         }
  197.                     }
  198.                 }
  199.  
  200.                 H1A8DiagonalAttacks[sq][occ] = targets;
  201.             }
  202.         }
  203.     }
  204.  
  205.     void MoveDatabase::initPseudoAttacks()
  206.     {
  207.         for (int i = 0; i < 64; i++)
  208.         {
  209.             PseudoRookAttacks[i] = RankAttacks[i][0] | FileAttacks[i][0];
  210.             PseudoBishopAttacks[i] = A1H8DiagonalAttacks[i][0] | H1A8DiagonalAttacks[i][0];
  211.         }
  212.     }
  213.  
  214.     // thanks stockfish for this
  215.     void MoveDatabase::initObstructedTable()
  216.     {
  217.         using namespace Utils::Square;
  218.  
  219.         for (int s1 = 0; s1 < 64; s1++)
  220.         {
  221.             for (int s2 = 0; s2 < 64; s2++)
  222.             {
  223.                 ObstructedTable[s1][s2] = 0;
  224.                 if ((PseudoRookAttacks[s1] | PseudoBishopAttacks[s1]) & Constants::Masks::SquareMask[s2])
  225.                 {
  226.                     int delta = (s2 - s1) / std::max(  abs(GetFileIndex(s1) - GetFileIndex(s2)), abs(GetRankIndex(s1) - GetRankIndex(s2))  );
  227.  
  228.                     for (int s = s1 + delta; s != s2; s += delta)
  229.                         ObstructedTable[s1][s2] |= Constants::Masks::SquareMask[s];
  230.                 }
  231.             }
  232.         }
  233.     }
  234.  
  235. }