Exemplo n.º 1
0
 public function getPiecePossibleMoves(Piece $piece)
 {
     $player = $piece->getPlayer();
     $isKingAttacked = $this->isKingAttacked($player);
     $allOpponentPieces = PieceFilter::filterNotClass(PieceFilter::filterAlive($player->getOpponent()->getPieces()), 'King');
     $king = $player->getKing();
     $kingSquareKey = $king->getSquareKey();
     $pieceOriginalX = $piece->getX();
     $pieceOriginalY = $piece->getY();
     $opponentPieces = PieceFilter::filterProjection($allOpponentPieces);
     //if we are not moving the king, and the king is not attacked, don't check pawns nor knights
     if (!$piece instanceof King && !$isKingAttacked) {
         $opponentPieces = PieceFilter::filterProjection($opponentPieces);
     }
     $squares = $this->board->keysToSquares($piece->getBasicTargetKeys());
     if ($piece instanceof King && !$isKingAttacked && !$piece->hasMoved()) {
         $squares = $this->addCastlingSquares($piece, $squares);
     }
     foreach ($squares as $it => $square) {
         // kings move to its target so we update its position
         if ($piece instanceof King) {
             $kingSquareKey = $square->getKey();
         }
         // kill opponent piece
         if ($killedPiece = $square->getPiece()) {
             $killedPiece->setIsDead(true);
         }
         $this->board->move($piece, $square->getX(), $square->getY());
         foreach ($opponentPieces as $opponentPiece) {
             if (null !== $killedPiece && $opponentPiece->getIsDead()) {
                 continue;
             }
             // if our king gets attacked
             if (in_array($kingSquareKey, $this->getPieceControlledKeys($opponentPiece, $piece instanceof King))) {
                 // can't go here
                 unset($squares[$it]);
                 break;
             }
         }
         $this->board->move($piece, $pieceOriginalX, $pieceOriginalY);
         // if a piece has been killed, bring it back to life
         if ($killedPiece) {
             $killedPiece->setIsDead(false);
             $this->board->add($killedPiece);
         }
     }
     return $this->board->squaresToKeys($squares);
 }
Exemplo n.º 2
0
 /**
  * @depends testGameCreation
  */
 public function testFilterProjection(Entities\Game $game)
 {
     $piece1 = $game->getBoard()->getPieceByPos(1, 1);
     $piece2 = $game->getBoard()->getPieceByPos(2, 1);
     $this->assertSame(array($piece1), PieceFilter::filterProjection(array($piece1, $piece2)));
 }
Exemplo n.º 3
0
 /**
  * @return array key => array keys
  */
 public function getPlayerPossibleMoves(Player $player, $isKingAttacked = null)
 {
     $possibleMoves = array();
     $isKingAttacked = null === $isKingAttacked ? $this->isKingAttacked($player) : $isKingAttacked;
     $allOpponentPieces = PieceFilter::filterAlive($player->getOpponent()->getPieces());
     $attackOpponentPieces = PieceFilter::filterNotClass($allOpponentPieces, 'King');
     $projectionOpponentPieces = PieceFilter::filterProjection($allOpponentPieces);
     $king = $player->getKing();
     foreach (PieceFilter::filterAlive($player->getPieces()) as $piece) {
         $kingSquareKey = $king->getSquareKey();
         $pieceOriginalX = $piece->getX();
         $pieceOriginalY = $piece->getY();
         $pieceClass = $piece->getClass();
         //if we are not moving the king, and the king is not attacked, don't check pawns nor knights
         if ('King' === $pieceClass) {
             $opponentPieces = $allOpponentPieces;
         } elseif ($isKingAttacked) {
             $opponentPieces = $attackOpponentPieces;
         } else {
             $opponentPieces = $projectionOpponentPieces;
         }
         $squares = $this->board->keysToSquares($piece->getBasicTargetKeys());
         foreach ($squares as $it => $square) {
             // king move to its target so we update its position
             if ('King' === $pieceClass) {
                 $kingSquareKey = $square->getKey();
             }
             // kill opponent piece
             if ($killedPiece = $square->getPiece()) {
                 $killedPiece->setIsDead(true);
             } elseif ('Pawn' === $pieceClass && $square->getX() !== $pieceOriginalX) {
                 $killedPiece = $square->getSquareByRelativePos(0, $player->isWhite() ? -1 : 1)->getPiece();
                 $killedPiece->setIsDead(true);
             }
             $this->board->move($piece, $square->getX(), $square->getY());
             foreach ($opponentPieces as $opponentPiece) {
                 if (null !== $killedPiece && $opponentPiece->getIsDead()) {
                     continue;
                 }
                 // if our king gets attacked
                 if (in_array($kingSquareKey, $opponentPiece->getAttackTargetKeys())) {
                     // can't go here
                     unset($squares[$it]);
                     break;
                 }
             }
             $this->board->move($piece, $pieceOriginalX, $pieceOriginalY);
             // if a piece has been killed, bring it back to life
             if ($killedPiece) {
                 $killedPiece->setIsDead(false);
                 $this->board->add($killedPiece);
             }
         }
         if ('King' === $pieceClass && !$isKingAttacked && !$piece->hasMoved()) {
             $squares = $this->addCastlingSquares($piece, $squares);
         }
         if (!empty($squares)) {
             $possibleMoves[$piece->getSquareKey()] = $this->board->squaresToKeys($squares);
         }
     }
     return $possibleMoves;
 }