Esempio n. 1
0
 /**
  * @param MoveInterface $move
  *
  * @return string
  */
 public static function toNotation(MoveInterface $move)
 {
     if (null === $move->getPiece()) {
         return '';
     }
     $notation = '';
     $piece = $move->getPiece();
     $toLabel = strtolower($move->getToLabel());
     $isPawn = $piece->getType() === PieceInterface::TYPE_PAWN;
     $pieceLetter = PieceDecorator::toLetter($piece);
     if (null !== ($capture = $move->getCapture())) {
         if ($isPawn) {
             $column = BoardHelper::getColumnFromPosition($move->getFrom());
             $pieceLetter = BoardHelper::columnNumberToLetter($column);
         }
         $notation .= sprintf('%sx%s', $pieceLetter, $toLabel);
         if ($isPawn) {
             if ($move->getType() === MoveInterface::TYPE_CAPTURE_EN_PASSANT) {
                 $notation .= 'e.p.';
             }
         }
         return $notation;
     }
     if ($isPawn) {
         return $toLabel;
     }
     return sprintf('%s%s', $pieceLetter, $toLabel);
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function configureWalker(BoardWalker $walker, GameInterface $game)
 {
     $walker->omnidirectional(1);
     $kingPosition = BoardHelper::getKingPosition($game->getBoard(), $game->getCurrentColor());
     $kingColumn = BoardHelper::getColumnFromPosition($kingPosition);
     $kingRow = BoardHelper::getRowFromPosition($kingPosition);
     $board = $game->getBoard();
     $king = $board->getSquare($kingPosition)->getPiece();
     $track = $kingPosition === SquareInterface::POSITION_E1;
     // check for possible castle move
     if (empty($game->getMovesByPiece($king->getId()))) {
         // see if one of the rooks did not make any moves
         $rookCriteria = ['piece_type' => PieceInterface::TYPE_ROOK, 'piece_color' => $game->getCurrentColor()];
         foreach ($board->getPiecesBy($rookCriteria) as $rookPosition => $rook) {
             if (empty($game->getMovesByPiece($rook->getId()))) {
                 // see if there are no pieces between the king and this rook
                 $rookColumn = BoardHelper::getColumnFromPosition($rookPosition);
                 $columnDiff = abs($kingColumn - $rookColumn) - 1;
                 $track = $track === true && $columnDiff === 3;
                 if ($columnDiff > 1) {
                     $skip = false;
                     for ($x = 1; $x <= $columnDiff; $x++) {
                         if ($rookColumn > $kingColumn) {
                             $cursor = $rookColumn - $x . $kingRow;
                         } else {
                             $cursor = $rookColumn + $x . $kingRow;
                         }
                         if (null !== ($piece = $board->getSquare($cursor)->getPiece())) {
                             $skip = true;
                             break;
                         }
                     }
                     if ($skip) {
                         continue;
                     }
                     if ($kingColumn > $rookColumn) {
                         if ($game->getCurrentColor() === Color::WHITE) {
                             $walker->jump(BoardWalker::DIRECTION_LEFT, 2);
                         } else {
                             $walker->jump(BoardWalker::DIRECTION_RIGHT, 2);
                         }
                     } else {
                         if ($game->getCurrentColor() === Color::WHITE) {
                             $walker->jump(BoardWalker::DIRECTION_RIGHT, 2);
                         } else {
                             $walker->jump(BoardWalker::DIRECTION_LEFT, 2);
                         }
                     }
                 }
             }
         }
     }
 }
Esempio n. 3
0
 /**
  * {@inheritdoc}
  */
 public function getIndexedSquares($indexedBy = 'row')
 {
     $squares = [];
     switch ($indexedBy) {
         case 'row':
             $squares = [];
             foreach ($this->getSquares() as $square) {
                 $row = BoardHelper::getRowFromPosition($square->getPosition());
                 if (!array_key_exists($row, $squares)) {
                     $squares[$row] = [];
                 }
                 $squares[$row][$square->getPosition()] = $square;
             }
             break;
         case 'column':
             $squares = [];
             foreach ($this->getSquares() as $square) {
                 $column = BoardHelper::getColumnFromPosition($square->getPosition());
                 if (!array_key_exists($column, $squares)) {
                     $squares[$column] = [];
                 }
                 $squares[$column][$square->getPosition()] = $square;
             }
             break;
     }
     ksort($squares);
     return $squares;
 }
Esempio n. 4
0
 /**
  * @param int      $direction        The direction to step into
  * @param int      $jumps            The number of jumps to make in this direction
  * @param int|null $startingPosition
  * @param bool     $ignoreCapture
  *
  * @return int|null The expected position, or null if the move is not possible
  *
  * @throws \InvalidArgumentException
  */
 public function peek($direction, $jumps = 1, $startingPosition = null, $ignoreCapture = false, $requireAttack = false)
 {
     $newPosition = null;
     if ($startingPosition !== null) {
         $column = BoardHelper::getColumnFromPosition($startingPosition);
         $row = BoardHelper::getRowFromPosition($startingPosition);
     } else {
         $column = $this->getColumn();
         $row = $this->getRow();
     }
     switch ($direction) {
         case self::DIRECTION_FORWARD:
             if ($this->color === Color::WHITE) {
                 $newRow = $this->formatNumber($row + $jumps);
             } else {
                 $newRow = $this->formatNumber($row - $jumps);
             }
             if ($newRow !== null) {
                 $newPosition = intval($column . $newRow);
             }
             break;
         case self::DIRECTION_FORWARDRIGHT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column + $jumps);
                 $newRow = $this->formatNumber($row + $jumps);
             } else {
                 $newColumn = $this->formatNumber($column - $jumps);
                 $newRow = $this->formatNumber($row - $jumps);
             }
             if ($newColumn !== null && $newRow !== null) {
                 $newPosition = intval($newColumn . $newRow);
             }
             break;
         case self::DIRECTION_RIGHT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column + $jumps);
             } else {
                 $newColumn = $this->formatNumber($column - $jumps);
             }
             if ($newColumn !== null) {
                 $newPosition = intval($newColumn . $row);
             }
             break;
         case self::DIRECTION_BACKWARDRIGHT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column + $jumps);
                 $newRow = $this->formatNumber($row - $jumps);
             } else {
                 $newColumn = $this->formatNumber($column - $jumps);
                 $newRow = $this->formatNumber($row + $jumps);
             }
             if ($newColumn !== null && $newRow !== null) {
                 $newPosition = intval($newColumn . $newRow);
             }
             break;
         case self::DIRECTION_BACKWARD:
             if ($this->color === Color::WHITE) {
                 $newRow = $this->formatNumber($row - $jumps);
             } else {
                 $newRow = $this->formatNumber($row + $jumps);
             }
             if ($newRow !== null) {
                 $newPosition = intval($column . $newRow);
             }
             break;
         case self::DIRECTION_BACKWARDLEFT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column - $jumps);
                 $newRow = $this->formatNumber($row - $jumps);
             } else {
                 $newColumn = $this->formatNumber($column + $jumps);
                 $newRow = $this->formatNumber($row + $jumps);
             }
             if ($newColumn !== null && $newRow !== null) {
                 $newPosition = intval($newColumn . $newRow);
             }
             break;
         case self::DIRECTION_LEFT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column - $jumps);
             } else {
                 $newColumn = $this->formatNumber($column + $jumps);
             }
             if ($newColumn !== null) {
                 $newPosition = intval($newColumn . $row);
             }
             break;
         case self::DIRECTION_FORWARDLEFT:
             if ($this->color === Color::WHITE) {
                 $newColumn = $this->formatNumber($column - $jumps);
                 $newRow = $this->formatNumber($row + $jumps);
             } else {
                 $newColumn = $this->formatNumber($column + $jumps);
                 $newRow = $this->formatNumber($row - $jumps);
             }
             if ($newColumn !== null && $newRow !== null) {
                 $newPosition = intval($newColumn . $newRow);
             }
             break;
         default:
             throw new \InvalidArgumentException(sprintf('Unknown direction to calculate: %s', $direction));
     }
     if ($ignoreCapture !== true && $newPosition !== null) {
         $toPiece = $this->board->getSquare($newPosition)->getPiece();
         if (null !== $toPiece) {
             if ($toPiece->getColor() === $this->getColor()) {
                 // own piece, can't capture
                 return null;
             }
         } elseif ($requireAttack === true) {
             return null;
         }
     }
     return $newPosition;
 }
Esempio n. 5
0
 /**
  * @param MoveInterface $move
  * @param GameInterface $game
  *
  * @return int|null
  */
 private static function determineEnPassantType(MoveInterface $move, GameInterface $game)
 {
     if (null !== ($lastMove = $game->getLastMove())) {
         if ($lastMove->getPiece()->getType() === PieceInterface::TYPE_PAWN) {
             if (abs(BoardHelper::getColumnFromPosition($lastMove->getTo()) - BoardHelper::getColumnFromPosition($move->getFrom())) === 1 && abs(BoardHelper::getRowFromPosition($lastMove->getTo()) - BoardHelper::getRowFromPosition($lastMove->getFrom())) === 2 && BoardHelper::getRowFromPosition($move->getFrom()) === BoardHelper::getRowFromPosition($lastMove->getTo())) {
                 $toPiece = $game->getBoard()->getSquare($move->getTo())->getPiece();
                 $rowDiff = abs(BoardHelper::getRowFromPosition($move->getFrom()) - BoardHelper::getRowFromPosition($move->getTo()));
                 $columnDiff = abs(BoardHelper::getColumnFromPosition($move->getFrom()) - BoardHelper::getColumnFromPosition($move->getTo()));
                 if ($rowDiff === 1 && $columnDiff === 1) {
                     if ($toPiece === null) {
                         // en passant capture
                         return MoveInterface::TYPE_CAPTURE_EN_PASSANT;
                     } else {
                         return MoveInterface::TYPE_CAPTURE;
                     }
                 }
             }
         }
     }
     return null;
 }