/** * 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); }
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; }
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; }
/** * 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; }
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')); }