/** * @param string $asciiBoard * @param array $movesAndRanking * * @dataProvider getRankedMoves() */ public function testRank($asciiBoard, array $movesAndRanking) { $game = $this->createGameFromAsciiBoard($asciiBoard); foreach ($movesAndRanking as $data) { list($from, $to, $expectedRanking) = $data; $move = new Move($from, $to); $actualRanking = $this->moveRanker->rank($move, $game, $this->moveCalculator); $this->assertEquals($expectedRanking, $actualRanking, sprintf('Actual ranking should match expected ranking for move from %s to %s', $move->getFromLabel(), $move->getToLabel())); } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $game = $this->getGame($input->getArgument('id'), $input->getOption('storage')); $moves = []; $moveCalculator = new MoveCalculator(); foreach ($input->getArgument('moves') as $move) { list($from, $to) = explode('->', $move); $moves[] = new Move($from, $to); } $bestMove = MoveRanker::best($moves, $game, $moveCalculator); $output->writeln(sprintf('Best move is: %s from %s to %s', $bestMove->getPiece()->getTypeLabel(), $bestMove->getFromLabel(), $bestMove->getToLabel())); }
/** * @param MoveInterface[] $moves * @param GameInterface $game * @param MoveCalculatorInterface $moveCalculator * @param int $depth * * @return MoveInterface */ public static function best(array $moves, GameInterface $game, MoveCalculatorInterface $moveCalculator, $depth = 0) { $highestRanking = null; $highestRankingMove = null; foreach ($moves as $move) { $ranking = MoveRanker::rank($move, $game, $moveCalculator, $depth); if (!isset($highestRanking) || $ranking > $highestRanking) { $highestRanking = $ranking; $highestRankingMove = $move; } } if ($highestRankingMove === null) { throw new \RuntimeException('The highest ranking move should have been determined at this point'); } $highestRankingMove->setRanking($highestRanking); return $highestRankingMove; }
/** * {@inheritdoc} */ public function doEngineMove(MoveCalculator $moveCalculator) { $currentPlayer = $this->getCurrentPlayer(); if ($currentPlayer->isHuman()) { throw new \LogicException('Can\\t make an engine-move with a human player'); } $possibleMoves = $moveCalculator->possibleMovesBy($currentPlayer->getColor(), $this->getBoard()); if (empty($possibleMoves)) { throw new \RuntimeException('Failed to find a move for the engine... probably because this scenario wasn\'t worked out yet'); } $highestRankingMove = MoveRanker::best($possibleMoves, $this, $moveCalculator); MoveHelper::apply($highestRankingMove, $this); $this->addState($this->createStateFromMove($highestRankingMove)); return $highestRankingMove; }