Пример #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();
 }
Пример #2
0
 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));
 }
Пример #4
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;
 }
 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);
 }
Пример #6
0
 /**
  * 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;
 }
Пример #7
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;
 }
Пример #8
0
 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;
 }
Пример #9
0
 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;
 }
Пример #10
0
 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);
         }
     }
 }
Пример #11
0
 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;
 }
Пример #12
0
 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));
 }
Пример #13
0
 private function encodeLobbyEntry(Game $game)
 {
     $entry = array();
     foreach ($game->getPlayers() as $player) {
         $entry[] = $player->hasUser() ? $player->getUsername() : null;
         $entry[] = $player->getUsernameWithElo();
     }
     return implode("\$", $entry);
 }
Пример #14
0
 public function updateElo(User $user, $elo, Game $game)
 {
     $user->setElo($elo);
     $ts = date_create()->getTimestamp();
     $this->historyRepository->findOneByUserOrCreate($user)->addGame($ts, $elo, $game->getId());
 }
Пример #15
0
 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();
 }
Пример #16
0
 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 '*';
 }
Пример #17
0
 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);
 }
Пример #18
0
 protected function win(Game $game, $color = 'white')
 {
     $game->setStatus(Game::MATE);
     $game->setWinner($game->getPlayer($color));
     $this->finisher->finish($game);
 }
Пример #19
0
 /**
  * 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;
 }
Пример #20
0
 public function getVariant()
 {
     $variantNames = Game::getVariantNames();
     return ucfirst($variantNames[$this->config['variant']]);
 }
Пример #21
0
 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;
 }
Пример #22
0
 public function getIsMyTurn()
 {
     return $this->game->getTurns() % 2 xor 'white' === $this->color;
 }
Пример #23
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;
 }
Пример #24
0
 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));
 }
Пример #25
0
 public function findByGame(Game $game)
 {
     return $this->createQueryBuilder()->field('game.$id')->equals($game->getId())->getQuery()->execute();
 }
Пример #26
0
 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));
 }
Пример #27
0
 public function isMyTurn()
 {
     return $this->game->getTurns() % 2 xor 'white' === $this->c;
 }
Пример #28
0
 /**
  * @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'));
 }
Пример #29
0
 /**
  * @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());
 }