Exemplo n.º 1
0
 /**
  * Add castling moves if available
  *
  * @return array the squares where the king can go
  **/
 protected function addCastlingSquares(King $king, array $squares)
 {
     $player = $king->getPlayer();
     $rooks = PieceFilter::filterNotMoved(PieceFilter::filterClass(PieceFilter::filterAlive($player->getPieces()), 'Rook'));
     if (empty($rooks)) {
         return $squares;
     }
     $opponentControlledKeys = $this->getPlayerControlledKeys($player->getOpponent(), true);
     foreach ($rooks as $rook) {
         $kingX = $king->getX();
         $kingY = $king->getY();
         $rookX = $rook->getX();
         $dx = $kingX > $rookX ? -1 : 1;
         $newKingX = 1 === $dx ? 7 : 3;
         $newRookX = 1 === $dx ? 6 : 4;
         $possible = true;
         // Unattacked
         $rangeMin = min($kingX, $newKingX);
         $rangeMax = min(8, max($kingX, $newKingX) + 1);
         for ($_x = $rangeMin; $_x !== $rangeMax; $_x++) {
             if (in_array(Board::posToKey($_x, $kingY), $opponentControlledKeys)) {
                 $possible = false;
                 break;
             }
         }
         // Unimpeded
         $rangeMin = min($kingX, $rookX, $newKingX, $newRookX);
         $rangeMax = min(8, max($kingX, $rookX, $newKingX, $newRookX) + 1);
         for ($_x = $rangeMin; $_x !== $rangeMax; $_x++) {
             if ($piece = $this->board->getPieceByKey(Board::posToKey($_x, $kingY))) {
                 if ($piece !== $king && $piece !== $rook) {
                     $possible = false;
                     break;
                 }
             }
         }
         if ($possible) {
             // If King moves one square or less (Chess variant)
             if (1 >= abs($kingX - $newKingX)) {
                 $newKingSquare = $rook->getSquare();
             } else {
                 $newKingSquare = $this->board->getSquareByPos($newKingX, $kingY);
             }
             $squares[] = $newKingSquare;
         }
     }
     return $squares;
 }
Exemplo n.º 2
0
 /**
  * Handle castling
  **/
 protected function castle(King $king, Square $to)
 {
     $isKingSide = $this->isCastleKingSide($king, $to);
     $y = $king->getY();
     if ($isKingSide) {
         $rook = $this->analyser->getCastleRookKingSide($king->getPlayer());
         $newRookSquare = $this->board->getSquareByPos(6, $y);
         $newKingSquare = $this->board->getSquareByPos(7, $y);
     } else {
         $rook = $this->analyser->getCastleRookQueenSide($king->getPlayer());
         $newRookSquare = $this->board->getSquareByPos(4, $y);
         $newKingSquare = $this->board->getSquareByPos(3, $y);
     }
     if (!$rook) {
         throw new \LogicException(sprintf('No rook for castle on %s side, king %s to %s', $isKingSide ? 'King' : 'Queen', $king->getSquareKey(), $to->getKey()));
     }
     $kingSquare = $king->getSquare();
     $rookSquare = $rook->getSquare();
     $this->board->castle($king, $rook, $newKingSquare->getX(), $newRookSquare->getX());
     $king->setFirstMove($this->game->getTurns());
     $rook->setFirstMove($this->game->getTurns());
     $this->stack->addEvent(array('type' => 'castling', 'king' => array($kingSquare->getKey(), $newKingSquare->getKey()), 'rook' => array($rookSquare->getKey(), $newRookSquare->getKey()), 'color' => $king->getColor()));
 }
Exemplo n.º 3
0
 /**
  * @depends testBoardCreation
  */
 public function testCleanSquares(Board $board)
 {
     $squares = array($board->getSquareByPos(1, 1), null, $board->getSquareByPos(3, 8), $board->getSquareByPos(3, 8));
     $cleanSquares = array($board->getSquareByPos(1, 1), $board->getSquareByPos(3, 8));
     $this->assertSame($cleanSquares, $board->cleanSquares($squares));
 }
Exemplo n.º 4
0
 protected function canCastle(King $king, $relativeX)
 {
     $_x = $king->getX() + $relativeX;
     return $_x > 0 && $_x < 9 && !$king->hasMoved() && ($rook = $this->board->getSquareByPos($king->getX() + $relativeX, $king->getY())->getPiece()) && ($rook->isClass('Rook') && !$rook->hasMoved());
 }