/** * 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 createPieces(Game $game) { $pieces = array(); $player = $game->getPlayer('white'); // Bishop on black square $file = 2 * mt_rand(1, 4) - 1; $pieces[$file] = $this->createPiece('Bishop', $file, 1); // Bishop on white square $file = 2 * mt_rand(1, 4); $pieces[$file] = $this->createPiece('Bishop', $file, 1); // Queen and Knights foreach (array(6 => 'Queen', 5 => 'Knight', 4 => 'Knight') as $rand => $class) { $file = $this->getEmptyFile($pieces, mt_rand(1, $rand)); $pieces[$file] = $this->createPiece($class, $file, 1); } // Rooks and King foreach (array('Rook', 'King', 'Rook') as $class) { $file = $this->getEmptyFile($pieces, 1); $pieces[$file] = $this->createPiece($class, $file, 1); } // Pawns for ($it = 1; $it <= 8; $it++) { $pieces[] = $this->createPiece('Pawn', $it, 2); } $pieces = array_values($pieces); $player->setPieces($pieces); $player->getOpponent()->setPieces($this->mirrorPieces($pieces)); $game->ensureDependencies(); $game->setInitialFen(Forsyth::export($game)); }
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 createPiecesMinimal(Game $game) { $pieces = array(); $player = $game->getPlayer('white'); $pieces[] = new Piece(1, 2, 'Pawn'); $player->setPieces($pieces); $player->getOpponent()->setPieces($this->mirrorPieces($pieces)); $game->setInitialFen(null); }
/** * Return the average available time per move * * @return float **/ protected function calculateTimePerMove(Game $game) { if ($clock = $game->getClock()) { $totalTime = $clock->getLimit() + $game->getFullmoveNumber() * $clock->getIncrement(); $timePerMove = $totalTime / $game->getFullmoveNumber(); } else { $timePerMove = 60; } return $timePerMove; }
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; }
protected function fewMaterial(Game $game) { $white = $game->getPlayer('white'); $black = $game->getPlayer('black'); $whiteNbPieces = $white->getNbAlivePieces(); $blackNbPieces = $black->getNbAlivePieces(); if (2 < $whiteNbPieces || 2 < $blackNbPieces) { return false; } $whitePiece = $this->getLastPiece($white); $blackPiece = $this->getLastPiece($black); if ($this->canNotMate($white) && $this->canNotMate($black)) { return true; } return false; }
public function detectCheater(Game $game) { if ($game->getTurns() != $this->turns && $game->getTurns() != $this->turns + 1) { return false; } if ($game->getInvited()->getIsAi()) { return false; } // Detect client using internal AI $similarGames = $this->gameRepository->findSimilar($game, new DateTime('-5 minutes')); foreach ($similarGames as $similarGame) { if ($similarGame->getInvited()->getIsAi()) { return $game->getPlayer($similarGame->getInvited()->getColor()); } } return false; }
protected function addMessage(Game $game, $author, $message) { $author = (string) $author; $message = (string) $message; if ('' === $message) { throw new \InvalidArgumentException('Messenger: Can not add empty message'); } if (mb_strlen($message) > 140) { throw new \InvalidArgumentException('Messenger: message is too long'); } if ($game->addRoomMessage($author, $message)) { $sayEvent = array('type' => 'message', 'message' => array($author, $message)); foreach ($game->getPlayers() as $player) { $player->addEventToStack($sayEvent); } } }
public function start(Game $game) { $game->start(); if ($game->getInvited()->getIsAi()) { return array(); } $messages = array(); $messages[] = ucfirst($game->getCreator()->getColor()) . ' creates the game'; $messages[] = ucfirst($game->getInvited()->getColor()) . ' joins the game'; if ($game->hasClock()) { $messages[] = 'Clock: ' . $game->getClock()->getName(); } if ($game->getIsRated()) { $messages[] = 'This game is rated'; } return $messages; }
public function renderGameFen(Game $game, User $user = null) { $player = $game->getPlayerByUserOrCreator($user); $authUser = $this->container->get('security.context')->getToken()->getUser(); if ($authUser instanceof User && ($authPlayer = $game->getPlayerByUser($authUser))) { $gameUrl = $this->getUrlGenerator()->generate('lichess_player', array('id' => $authPlayer->getFullId())); } else { $gameUrl = $this->getUrlGenerator()->generate('lichess_game', array('id' => $game->getId(), 'color' => $player->getColor())); } return sprintf('<a href="%s" title="%s" class="mini_board parse_fen" data-color="%s" data-fen="%s"></a>', $gameUrl, $this->getTranslator()->trans('View in full size'), $player->getColor(), Forsyth::export($game)); }
private function encodeLobbyEntry(Game $game) { $entry = array(); foreach ($game->getPlayers() as $player) { $entry[] = $player->hasUser() ? $player->getUsername() : null; $entry[] = $player->getUsernameWithElo(); } return implode("\$", $entry); }
public function updateElo(User $user, $elo, Game $game) { $user->setElo($elo); $ts = date_create()->getTimestamp(); $this->historyRepository->findOneByUserOrCreate($user)->addGame($ts, $elo, $game->getId()); }
public function findSimilar(Game $game, \DateTime $since) { return $this->createQueryBuilder()->field('id')->notEqual($game->getId())->field('updatedAt')->gt(new \MongoDate($since->getTimestamp()))->field('status')->equals(Game::STARTED)->field('turns')->equals($game->getTurns())->field('pgnMoves')->equals($game->getPgnMoves())->hint(array('updatedAt' => -1))->getQuery()->execute(); }
protected function getPgnResult(Game $game) { if ($game->getIsFinished()) { if ($game->getPlayer('white')->getIsWinner()) { return '1-0'; } elseif ($game->getPlayer('black')->getIsWinner()) { return '0-1'; } return '1/2-1/2'; } return '*'; }
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); }
protected function win(Game $game, $color = 'white') { $game->setStatus(Game::MATE); $game->setWinner($game->getPlayer($color)); $this->finisher->finish($game); }
/** * Create a game from a visual block notation like: r bqkb r ppp ppp p n n p B P N PPPP PPP RNBQK R */ public function createGameFromVisualBlock($data) { $data = $this->fixVisualBlock($data); $game = new Game(); $players = array(); foreach (array('white', 'black') as $color) { $game->addPlayer(new Player($color)); } $game->setCreator($game->getPlayer('white')); foreach (explode("\n", $data) as $_y => $line) { $y = 8 - $_y; for ($x = 1; $x < 9; $x++) { $byte = $line[$x - 1]; if (' ' === $byte) { continue; } $color = ctype_lower($byte) ? 'black' : 'white'; $player = $game->getPlayer($color); switch (strtolower($byte)) { 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; } $player->addPiece(new Piece($x, $y, $class)); } } return $game; }
public function getVariant() { $variantNames = Game::getVariantNames(); return ucfirst($variantNames[$this->config['variant']]); }
protected function createGame() { $game = new Game(); $game->addPlayer(new Player('white')); $game->addPlayer(new Player('black')); $game->setCreatorColor('white'); $positionGenerator = new StandardPositionGenerator(); $positionGenerator->createPiecesMinimal($game); return $game; }
public function getIsMyTurn() { return $this->game->getTurns() % 2 xor 'white' === $this->color; }
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; }
protected function updateElo(Game $game) { // Game can be aborted if (!$game->getIsFinished()) { return; } if (!$game->getIsRated()) { return; } // Don't rate games with less than 2 moves if ($game->getTurns() < 2) { return; } $white = $game->getPlayer('white'); $black = $game->getPlayer('black'); $whiteUser = $white->getUser(); $blackUser = $black->getUser(); // Don't rate games when one ore more player is not registered if (!$whiteUser || !$blackUser) { return; } if ($winner = $game->getWinner()) { $win = $winner->isWhite() ? -1 : 1; } else { $win = 0; } list($whiteElo, $blackElo) = $this->calculator->calculate($white->getElo(), $black->getElo(), $win); $white->setEloDiff($whiteEloDiff = $whiteElo - $white->getElo()); $black->setEloDiff($blackEloDiff = $blackElo - $black->getElo()); $this->eloUpdater->updateElo($whiteUser, $whiteUser->getElo() + $whiteEloDiff, $game); $this->eloUpdater->updateElo($blackUser, $blackUser->getElo() + $blackEloDiff, $game); $this->logger->notice($game, sprintf('Elo exchanged: %s', $whiteEloDiff)); }
public function findByGame(Game $game) { return $this->createQueryBuilder()->field('game.$id')->equals($game->getId())->getQuery()->execute(); }
public function expandGame(Game $game) { return sprintf('game(%s,%s,%s,%s,%d,%s)', $game->getVariantName(), $game->getClockName(), $game->getIsRated() ? 'rated' : 'casual', $game->getIsPlayable() ? 'playable' : $game->getStatusMessage(), $game->getTurns(), $this->generator->generate('lichess_game', array('id' => $game->getId()), true)); }
public function isMyTurn() { return $this->game->getTurns() % 2 xor 'white' === $this->c; }
/** * @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')); }
/** * @depends testGameCreationStandard */ public function testPlayerQueens(Document\Game $game) { $player = $game->getPlayer('white'); $queens = $player->getPiecesByClass('Queen'); $this->assertTrue($queens[0] instanceof Document\Piece\Queen); $this->assertEquals(1, $queens[0]->getY()); $this->assertEquals(1, count($queens)); $this->assertSame($player, $queens[0]->getPlayer()); $this->assertTrue($queens[0]->isClass('Queen')); $this->assertFalse($queens[0]->getIsDead()); }