public McRunnable(Player player, CopiableStructure stuff) { LgrfTable table = null; try { table = stuff.get(LgrfTable.class); } catch (final IllegalArgumentException e) { // If we get here, we're not using LGRF } final CopiableStructure copy = stuff.copy(); board = copy.get(Board.class); coords = board.getCoordinateSystem(); suggesters = copy.get(Suggester[].class); weights = copy.get(int[].class); this.player = player; random = new MersenneTwisterFast(); mover = copy.get(Mover.class); if (table != null) { final LgrfSuggester lgrf = copy.get(LgrfSuggester.class); lgrf.setTable(table); } scorer = copy.get(ChinesePlayoutScorer.class); mercyObserver = copy.get(StoneCountObserver.class); historyObserver = copy.get(HistoryObserver.class); filter = copy.get(Predicate.class); fancyHashes = new long[coords.getMaxMovesPerGame() + 1]; playedPoints = new ShortSet(coords.getFirstPointBeyondBoard()); }
/** * Plays moves to the end of the game and returns the winner: BLACK, WHITE, or (in rare event of a * tie or a playout canceled because it hits the maximum number of moves) VACANT. * * @param mercy True if we should abandon the playout when one color has many more stones than the * other. */ public Color playout(boolean mercy) { do { if (board.getTurn() >= coords.getMaxMovesPerGame()) { // Playout ran out of moves, probably due to superko return VACANT; } if (board.getPasses() < 2) { selectAndPlayOneMove(); } if (board.getPasses() >= 2) { // Game ended return scorer.winner(); } final Color mercyWinner = mercyObserver.mercyWinner(); if (mercy && mercyWinner != null) { // One player has far more stones on the board return mercyWinner; } } while (true); }