Exemple #1
0
 /**
  * Create and position pieces of the game for the forsyth string
  *
  * @param Game $game
  * @param string $forsyth
  * @return Game $game
  */
 public static function import(Game $game, $forsyth)
 {
     static $classes = array('p' => 'Pawn', 'r' => 'Rook', 'n' => 'Knight', 'b' => 'Bishop', 'q' => 'Queen', 'k' => 'King');
     $x = 1;
     $y = 8;
     $board = $game->getBoard();
     $forsyth = str_replace('/', '', preg_replace('#\\s*([\\w\\d/]+)\\s.+#i', '$1', $forsyth));
     $pieces = array('white' => array(), 'black' => array());
     for ($itForsyth = 0, $forsythLen = strlen($forsyth); $itForsyth < $forsythLen; $itForsyth++) {
         $letter = $forsyth[$itForsyth];
         if (is_numeric($letter)) {
             $x += intval($letter);
         } else {
             $color = ctype_lower($letter) ? 'black' : 'white';
             $pieces[$color][] = new Piece($x, $y, $classes[strtolower($letter)]);
             ++$x;
         }
         if ($x > 8) {
             $x = 1;
             --$y;
         }
     }
     foreach ($game->getPlayers() as $player) {
         $player->setPieces($pieces[$player->getColor()]);
     }
     $game->ensureDependencies();
 }
 public function __construct(Game $game, Stack $stack = null)
 {
     $autodraw = new Autodraw();
     $stack = $stack ?: new Stack();
     $analyser = new Analyser($game->getBoard());
     parent::__construct($game, $autodraw, $analyser, $stack);
 }
Exemple #3
0
 public function __construct(Game $game, Autodraw $autodraw, Analyser $analyser, Stack $stack)
 {
     $this->game = $game;
     $this->board = $game->getBoard();
     $this->autodraw = $autodraw;
     $this->analyser = $analyser;
     $this->stack = $stack;
 }
Exemple #4
0
 public function move(Game $game, $level)
 {
     $analyser = new Analyser($game->getBoard());
     $moveTree = $analyser->getPlayerPossibleMoves($game->getTurnPlayer());
     // choose random piece
     do {
         $from = array_rand($moveTree);
     } while (empty($moveTree[$from]));
     // choose random move
     $to = $moveTree[$from][array_rand($moveTree[$from])];
     return $from . ' ' . $to;
 }
Exemple #5
0
 /**
  * Dumps a single move to PGN notation
  *
  * @return string
  **/
 public function dumpMove(Game $game, Piece $piece, Square $from, Square $to, array $playerPossibleMoves, $killed, $isCastling, $isPromotion, $isEnPassant, array $options)
 {
     $board = $game->getBoard();
     $pieceClass = $piece->getClass();
     $fromKey = $from->getKey();
     $toKey = $to->getKey();
     if ($isCastling) {
         if ($this->isCastleKingSide($piece, $to)) {
             return 'O-O';
         } else {
             return 'O-O-O';
         }
     }
     if ($isEnPassant) {
         return $from->getFile() . 'x' . $to->getKey();
     }
     if ($isPromotion) {
         return $to->getKey() . '=' . ('Knight' === $options['promotion'] ? 'N' : $options['promotion'][0]);
     }
     $pgnFromPiece = $pgnFromFile = $pgnFromRank = '';
     if ('Pawn' != $pieceClass) {
         $pgnFromPiece = $piece->getPgn();
         $candidates = array();
         foreach ($playerPossibleMoves as $_from => $_tos) {
             if ($_from !== $fromKey && in_array($toKey, $_tos)) {
                 $_piece = $board->getPieceByKey($_from);
                 if ($_piece->getClass() === $pieceClass) {
                     $candidates[] = $_piece;
                 }
             }
         }
         if (!empty($candidates)) {
             $isAmbiguous = false;
             foreach ($candidates as $candidate) {
                 if ($candidate->getSquare()->getFile() === $from->getFile()) {
                     $isAmbiguous = true;
                     break;
                 }
             }
             if (!$isAmbiguous) {
                 $pgnFromFile = $from->getFile();
             } else {
                 $isAmbiguous = false;
                 foreach ($candidates as $candidate) {
                     if ($candidate->getSquare()->getRank() === $from->getRank()) {
                         $isAmbiguous = true;
                         break;
                     }
                 }
                 if (!$isAmbiguous) {
                     $pgnFromRank = $from->getRank();
                 } else {
                     $pgnFromFile = $from->getFile();
                     $pgnFromRank = $from->getRank();
                 }
             }
         }
     }
     if ($killed) {
         $pgnCapture = 'x';
         if ('Pawn' === $pieceClass) {
             $pgnFromFile = $from->getFile();
         }
     } else {
         $pgnCapture = '';
     }
     $pgnTo = $to->getKey();
     $pgn = $pgnFromPiece . $pgnFromFile . $pgnFromRank . $pgnCapture . $pgnTo;
     return $pgn;
 }
Exemple #6
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;
 }
 public function create(Game $game, Stack $stack = null)
 {
     $class = $this->class;
     $stack = $stack ?: new Stack();
     return new $class($game, $this->autodraw, $this->analyserFactory->create($game->getBoard()), $stack);
 }
 /**
  * @depends testGameCreation
  */
 public function testFilterNotClass(Entities\Game $game)
 {
     $piece1 = $game->getBoard()->getPieceByPos(1, 1);
     $piece2 = $game->getBoard()->getPieceByPos(2, 1);
     $this->assertSame(array($piece2), PieceFilter::filterNotClass(array($piece1, $piece2), 'Rook'));
 }