示例#1
0
 private function FindTilesAttackedByPawn($nRank, $nFile)
 {
     $this->nCalls++;
     $nTile = $nRank * 8 + $nFile;
     $n64AttackedTiles = 0;
     $n64Occupied = 0;
     // Need to use different bitmap arrays for the players.
     if ($this->PlayerTurn == 0) {
         // Get the tile(s) that can be theoretically moved to.
         $n64AttackedTiles = $this->WPawnAttacks[$nTile]->duplicate();
         // If this is the starting rank for pawn then see if the two tiles above are free.
         if ($nRank == 1) {
             // Check that the tile in rank 3 is free. If not then rank 4 cannot be reached.
             $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile + 8]);
             if ($n64Occupied->is_zero()) {
                 // Check if rank 4 is free. If not then exclusive or to remove that tile from
                 // the bitmap.
                 $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile + 16]);
                 if (!$n64Occupied->is_zero()) {
                     $n64AttackedTiles->_XOR($n64Occupied);
                 }
             } else {
                 $n64AttackedTiles->set_value('0x0');
             }
             // Set to 0 since neither tile can be reached.
         } else {
             if ($nRank < 7) {
                 // Check that the rank above can be moved to by masking the ALL pieces bitmap
                 // with the tile above the current position, to see if the tile is occupied.
                 // If it is then remove this tile from the attack bitmap.
                 $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile + 8]);
                 if (!$n64Occupied->is_zero()) {
                     $remove = new BitBoard();
                     $remove->set_value('FFFFFFFFFFFFFFFF');
                     $remove->_XOR($this->Tiles[$nTile + 8]);
                     $n64AttackedTiles->_AND($remove);
                 }
             }
         }
         // Now check if capturing a piece is possible by ANDing the captures bitmap
         // with the all black pieces bitmap and combining this with the AttackedTiles bitmap.
         $n64AttackedTiles->_OR(BitBoard::_AND_($this->WPawnCaptures[$nTile], $this->n64BAll));
         // Check if en passant is possible, by ANDing the en passant bitmap with the pawn capture
         // bitmap for this tile. Then OR this with the attackedtiles bitmap.
         $n64AttackedTiles->_OR(BitBoard::_AND_($this->n64Enpassant, $this->WPawnCaptures[$nTile]));
     } else {
         $n64AttackedTiles = $this->BPawnAttacks[$nTile]->duplicate();
         if ($nRank == 6) {
             $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile - 8]);
             if ($n64Occupied->is_zero()) {
                 $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile - 16]);
                 if (!$n64Occupied->is_zero()) {
                     $n64AttackedTiles->_XOR($n64Occupied);
                 }
             } else {
                 $n64AttackedTiles->set_value('0x0');
             }
             // Set to 0 since neither tile can be reached.
         } else {
             if ($nRank > 0) {
                 $n64Occupied = BitBoard::_AND_($this->n64All, $this->Tiles[$nTile - 8]);
                 if (!$n64Occupied->is_zero()) {
                     $remove = new BitBoard();
                     $remove->set_value('FFFFFFFFFFFFFFFF');
                     $remove->_XOR($this->Tiles[$nTile - 8]);
                     $n64AttackedTiles->_AND($remove);
                 }
             }
         }
         $n64AttackedTiles->_OR(BitBoard::_AND_($this->BPawnCaptures[$nTile], $this->n64WAll));
         $n64AttackedTiles->_OR(BitBoard::_AND_($this->n64Enpassant, $this->BPawnCaptures[$nTile]));
     }
     return $n64AttackedTiles;
 }