Exemplo n.º 1
0
 /**
  * @depends testGetBoard
  */
 public function testGetBasicTargetSquaresSecondMove(Board $board)
 {
     $piece = $board->getPieceByKey('b1');
     $piece->setX(3);
     $piece->setY(4);
     $board->compile();
     $expected = array('a3', 'a5', 'b6', 'd6', 'e5', 'e3');
     $this->assertSquareKeys($expected, $piece->getBasicTargetKeys());
 }
Exemplo n.º 2
0
 /**
  * @depends testGetBoard
  */
 public function testGetBasicTargetSquaresSecondMove(Board $board)
 {
     $piece = $board->getPieceByKey('d1');
     $piece->setX(3);
     $piece->setY(4);
     $board->compile();
     $expected = array('b3', 'b5', 'a6', 'd5', 'e6', 'f7', 'd3', 'a4', 'b4', 'd4', 'e4', 'f4', 'g4', 'h4', 'c3', 'c5', 'c6', 'c7');
     $this->assertSquareKeys($expected, $piece->getBasicTargetKeys());
 }
Exemplo n.º 3
0
 public function getAttackTargetKeys()
 {
     $keys = array();
     $mySquare = $this->board->getSquareByKey($this->getSquareKey());
     $x = $this->x;
     $y = $this->y;
     $dy = 'white' === $this->color ? 1 : -1;
     $_y = $y + $dy;
     foreach (array(-1, 1) as $dx) {
         $_x = $x + $dx;
         if ($_x < 1 || $_x > 8) {
             continue;
         }
         // eat
         $key = Board::posToKey($_x, $_y);
         if ($piece = $this->board->getPieceByKey($key)) {
             if ($piece->getColor() !== $this->color) {
                 $keys[] = $key;
             }
         }
         // en passant
         if (5 === $y || 4 === $y) {
             $opponentKey = Board::posToKey($_x, $y);
             if (($piece = $this->board->getPieceByKey($opponentKey)) && $piece instanceof Pawn && $piece->getColor() !== $this->color && $piece->getFirstMove() === $this->getPlayer()->getGame()->getTurns() - 1 && !$this->board->hasPieceByKey($key)) {
                 $keys[] = $key;
             }
         }
     }
     return $keys;
 }
Exemplo n.º 4
0
 public function getBasicTargetKeys()
 {
     $mySquare = $this->getSquare();
     $x = $mySquare->getX();
     $y = $mySquare->getY();
     $keys = array();
     $board = $this->getBoard();
     /**
      * That's ugly and could be done easily in a nicer way.
      * But I needed performance optimization.
      */
     for ($dx = -1; $dx < 2; $dx++) {
         $_x = $x + $dx;
         if ($_x > 0 && $_x < 9) {
             for ($dy = -1; $dy < 2; $dy++) {
                 if (0 === $dx && 0 === $dy) {
                     continue;
                 }
                 $_y = $y + $dy;
                 if ($_y > 0 && $_y < 9) {
                     $key = Board::posToKey($_x, $_y);
                     if (($piece = $board->getPieceByKey($key)) && $piece->getColor() === $this->color) {
                         continue;
                     }
                     $keys[] = $key;
                 }
             }
         }
     }
     return $keys;
 }
Exemplo n.º 5
0
 public function getBasicTargetKeys()
 {
     $mySquare = $this->getSquare();
     $x = $mySquare->getX();
     $y = $mySquare->getY();
     $keys = array();
     $board = $this->getBoard();
     /**
      * That's ugly and could be done easily in a nicer way.
      * But I needed performance optimization.
      */
     static $deltas = array(array(-1, 2), array(1, -2), array(2, -1), array(2, 1), array(1, 2), array(-1, -2), array(-2, 1), array(-2, -1));
     foreach ($deltas as $delta) {
         $_x = $x + $delta[0];
         $_y = $y + $delta[1];
         if ($_x > 0 && $_x < 9 && $_y > 0 && $_y < 9) {
             $key = Board::posToKey($_x, $_y);
             if (($piece = $board->getPieceByKey($key)) && $piece->getPlayer() === $this->player) {
                 continue;
             }
             $keys[] = $key;
         }
     }
     return $keys;
 }
Exemplo n.º 6
0
 protected function getCastleRookInDirection(Player $player, $dx)
 {
     $king = $player->getKing();
     if ($king->hasMoved()) {
         return null;
     }
     for ($x = $king->getX() + $dx; $x < 9 && $x > 0; $x += $dx) {
         if ($piece = $this->board->getPieceByPos($x, $king->getY())) {
             if ('Rook' === $piece->getClass() && !$piece->hasMoved() && $piece->getColor() === $king->getColor()) {
                 return $piece;
             }
         }
     }
 }
Exemplo n.º 7
0
 /**
  * Handle castling
  **/
 protected function castling(King $king, Square $to)
 {
     if (7 === $to->getX()) {
         $rookSquare = $to->getSquareByRelativePos(1, 0);
         $newRookSquare = $to->getSquareByRelativePos(-1, 0);
     } else {
         $rookSquare = $to->getSquareByRelativePos(-2, 0);
         $newRookSquare = $to->getSquareByRelativePos(1, 0);
     }
     $rook = $rookSquare->getPiece();
     $this->board->move($rook, $newRookSquare->getX(), $newRookSquare->getY());
     $rook->setFirstMove($this->game->getTurns());
     if ($this->stack) {
         $this->stack->add(array('type' => 'castling', 'from' => $rookSquare->getKey(), 'to' => $newRookSquare->getKey()));
     }
 }
Exemplo n.º 8
0
 /**
  * @depends testGetBoard
  */
 public function testGetBasicTargetSquaresEnPassant(Board $board)
 {
     $board->getGame()->setTurns(10);
     $piece = $board->getPieceByKey('f2');
     $piece->setY('5');
     $piece->setFirstMove(1);
     $board->getPieceByKey('g7')->setY(5);
     $board->getPieceByKey('g7')->setFirstMove(9);
     $board->compile();
     $expected = array('f6');
     $this->assertSquareKeys($expected, $piece->getBasicTargetKeys());
 }
Exemplo n.º 9
0
 public function getAttackTargetKeys()
 {
     $keys = array();
     $dy = 'white' === $this->color ? 1 : -1;
     $_y = $this->y + $dy;
     foreach (array(-1, 1) as $dx) {
         $_x = $this->x + $dx;
         if ($_x < 1 || $_x > 8) {
             continue;
         }
         $key = Board::posToKey($_x, $_y);
         $piece = $this->board->getPieceByKey($key);
         if (!$piece || $piece->getColor() !== $this->color) {
             $keys[] = $key;
         }
     }
     return $keys;
 }
Exemplo n.º 10
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.º 11
0
    /**
     * @depends testBoardCreation
     */
    public function testDump(Board $board)
    {
        $expected = <<<EOF
rnbqkbnr
pppppppp




PPPPPPPP
RNBQKBNR
EOF;
        $this->assertEquals("\n" . Generator::fixVisualBlock($expected) . "\n", $board->dump());
    }
Exemplo n.º 12
0
 public function diffToMove(Game $game, $forsythe)
 {
     $moves = array('from' => array(), 'to' => array());
     $x = 1;
     $y = 8;
     $board = $game->getBoard();
     $forsythe = str_replace('/', '', preg_replace('#\\s*([\\w\\d/]+)\\s.+#i', '$1', $forsythe));
     for ($itForsythe = 0, $forsytheLen = strlen($forsythe); $itForsythe < $forsytheLen; $itForsythe++) {
         $letter = $forsythe[$itForsythe];
         $key = Board::posToKey($x, $y);
         if (is_numeric($letter)) {
             for ($x = $x, $max = $x + intval($letter); $x < $max; $x++) {
                 $_key = Board::posToKey($x, $y);
                 if (!$board->getSquareByKey($_key)->isEmpty()) {
                     $moves['from'][] = $_key;
                 }
             }
         } else {
             $color = ctype_lower($letter) ? 'black' : 'white';
             switch (strtolower($letter)) {
                 case 'p':
                     $class = 'Pawn';
                     break;
                 case 'r':
                     $class = 'Rook';
                     break;
                 case 'n':
                     $class = 'Knight';
                     break;
                 case 'b':
                     $class = 'Bishop';
                     break;
                 case 'q':
                     $class = 'Queen';
                     break;
                 case 'k':
                     $class = 'King';
                     break;
             }
             if ($piece = $board->getPieceByKey($key)) {
                 if ($class != $piece->getClass() || $color !== $piece->getColor()) {
                     $moves['to'][] = $key;
                 }
             } else {
                 $moves['to'][] = $key;
             }
             ++$x;
         }
         if ($x > 8) {
             $x = 1;
             --$y;
         }
     }
     if (empty($moves['from'])) {
         return null;
     }
     // two pieces moved: it's a castle
     if (2 === count($moves['from'])) {
         if ($board->getPieceByKey($moves['from'][0])->isClass('King')) {
             $from = $moves['from'][0];
         } else {
             $from = $moves['from'][1];
         }
         if (in_array($board->getSquareByKey($moves['to'][0])->getX(), array(3, 7))) {
             $to = $moves['to'][0];
         } else {
             $to = $moves['to'][1];
         }
     } else {
         $from = $moves['from'][0];
         $to = $moves['to'][0];
     }
     return $from . ' ' . $to;
 }
Exemplo n.º 13
0
 public function getSquareKey()
 {
     return Board::posToKey($this->x, $this->y);
 }
Exemplo n.º 14
0
    /**
     * @depends testBoardCreation
     */
    public function testDump(Board $board)
    {
        $expected = <<<EOF

rnbqkbnr
pppppppp
        
        
        
        
PPPPPPPP
RNBQKBNR

EOF;
        $this->assertEquals($expected, $board->dump());
    }
Exemplo n.º 15
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());
 }
Exemplo n.º 16
0
 public function extractPieces()
 {
     $pieces = array();
     if (!empty($this->ps)) {
         foreach (explode(' ', $this->ps) as $p) {
             $pos = Board::keyToPos(Board::piotrToKey($p[0]));
             $class = Piece::letterToClass(strtolower($p[1]));
             $piece = new Piece($pos[0], $pos[1], $class);
             if (ctype_upper($p[1])) {
                 $piece->setIsDead(true);
             }
             $pieces[] = $piece;
         }
     }
     $this->setPieces($pieces);
 }
Exemplo n.º 17
0
 public static function diffToMove(Game $game, $forsyth)
 {
     $moves = array('from' => array(), 'to' => array());
     $x = 1;
     $y = 8;
     $board = $game->getBoard();
     $forsyth = str_replace('/', '', preg_replace('#\\s*([\\w\\d/]+)\\s.+#i', '$1', $forsyth));
     for ($itForsyth = 0, $forsythLen = strlen($forsyth); $itForsyth < $forsythLen; $itForsyth++) {
         $letter = $forsyth[$itForsyth];
         $key = Board::posToKey($x, $y);
         if (is_numeric($letter)) {
             for ($x = $x, $max = $x + intval($letter); $x < $max; $x++) {
                 $_key = Board::posToKey($x, $y);
                 if (!$board->getSquareByKey($_key)->isEmpty()) {
                     $moves['from'][] = $_key;
                 }
             }
         } else {
             $color = ctype_lower($letter) ? 'black' : 'white';
             switch (strtolower($letter)) {
                 case 'p':
                     $class = 'Pawn';
                     break;
                 case 'r':
                     $class = 'Rook';
                     break;
                 case 'n':
                     $class = 'Knight';
                     break;
                 case 'b':
                     $class = 'Bishop';
                     break;
                 case 'q':
                     $class = 'Queen';
                     break;
                 case 'k':
                     $class = 'King';
                     break;
             }
             if ($piece = $board->getPieceByKey($key)) {
                 if ($class != $piece->getClass() || $color !== $piece->getColor()) {
                     $moves['to'][] = $key;
                 }
             } else {
                 $moves['to'][] = $key;
             }
             ++$x;
         }
         if ($x > 8) {
             $x = 1;
             --$y;
         }
     }
     if (empty($moves['from'])) {
         return null;
     } elseif (1 === count($moves['from']) && 1 === count($moves['to'])) {
         $from = $moves['from'][0];
         $to = $moves['to'][0];
     } elseif (2 === count($moves['from']) && 2 === count($moves['to'])) {
         if ($board->getPieceByKey($moves['from'][0])->isClass('King')) {
             $from = $moves['from'][0];
         } else {
             $from = $moves['from'][1];
         }
         if (in_array($board->getSquareByKey($moves['to'][0])->getX(), array(3, 7))) {
             $to = $moves['to'][0];
         } else {
             $to = $moves['to'][1];
         }
     } elseif (2 === count($moves['from']) && 1 === count($moves['to']) && $board->getPieceByKey($moves['from'][0])->isClass('Pawn') && $board->getPieceByKey($moves['from'][1])->isClass('Pawn') && !$board->hasPieceByKey($moves['to'][0])) {
         if ($moves['from'][0][0] === $moves['to'][0][0]) {
             $from = $moves['from'][1];
         } else {
             $from = $moves['from'][0];
         }
         $to = $moves['to'][0];
     } else {
         throw new \RuntimeException(sprintf('Forsyth:diffToMove game:%s, variant:%s, moves: %s, forsyth:%s', $game->getId(), $game->getVariantName(), str_replace("\n", " ", var_export($moves, true)), $forsyth));
     }
     return $from . ' ' . $to;
 }