public static void main(String[] args) throws Exception { Board board = new Board(); board.setup(); Turn turn = Turn.BLACK; boolean hasPassed = false; // Player blackPlayer = new HumanPlayer(Turn.BLACK); // Player blackPlayer = new SimpleAI(Turn.BLACK); // Player blackPlayer = new MinMaxSimpleAIPlayer(Turn.BLACK, 5); // Player blackPlayer = new NegaMaxBoardScoreAIPlayer(Turn.BLACK, 5); Player blackPlayer = new PerfectPlayWrapperPlayer(new NegaScoutAdvancedAIPlayer(Turn.BLACK, 7), 15); // Player blackPlayer = new AlphaBetaSimpleAI(Turn.BLACK, 5); // Player blackPlayer = new LearnedAI(turn, 9, 15); // Player whitePlayer = new SimpleAI(Turn.WHITE); // Player whitePlayer = new MinMaxSimpleAIPlayer(Turn.WHITE, 5); // Player whitePlayer = new NegaMaxSimpleAIPlayer(Turn.WHITE, 5); Player whitePlayer = new PerfectPlayWrapperPlayer(new NegaScoutLearnedAIPlayer(Turn.WHITE, 7), 15); // Player whitePlayer = new NegaMaxBoardScoreAIPlayer(Turn.WHITE, 5); // Player whitePlayer = new NegaMaxAdvancedAI(Turn.WHITE, 5); // Player whitePlayer = new AlphaBetaSimpleAI(Turn.WHITE, 5); // Player whitePlayer = new AlphaBetaEvaluationSimpleWithCompleteReadingAI(Turn.WHITE, 5, 15); // Player whitePlayer = new NegaScoutEvaluationSimpleAI(Turn.WHITE, 5); // Player whitePlayer = new NegaScoutEvaluationSimpleWithCompleteReadingAI(Turn.WHITE, 5, 15); // Player whitePlayer = new TranpositionEvaluationSimpleAI(Turn.WHITE, 5); // Player whitePlayer = new TranpositionEvaluationCompleteReadingSimpleAI(Turn.WHITE, 5, 15); while (true) { // 盤を見やすいように表示 board.show(); // どこかに置けないならばパスをしなければならない。 if (!board.isPuttableSomewhere(turn.stone())) { if (hasPassed) // 2連続パスすると終了 break; hasPassed = true; turn = turn.flip(); continue; } hasPassed = false; Position p; if (turn == Turn.BLACK) p = blackPlayer.play(board); else p = whitePlayer.play(board); board.put(p.x, p.y, turn.stone()); turn = turn.flip(); } System.out.printf("BLACK = %d\n", board.countStone(Stone.BLACK)); System.out.printf("WHITE = %d\n", board.countStone(Stone.WHITE)); }
private EvalResult eval( Board board, int restDepth, Turn currentTurn, Evaluator evaluator, double alpha, double beta) { if (restDepth == 0) return new EvalResult(evaluator.score(board, currentTurn), null); // 置ける手を全て列挙 List<Position> puttablePositions = board.findPuttableHands(currentTurn.stone()); // 自分がおける場所がないならば、相手のターンになる。 if (puttablePositions.isEmpty()) { double score = -eval(board, restDepth - 1, currentTurn.flip(), evaluator, -beta, -alpha).getScore(); return new EvalResult(score, null); } if (restDepth >= 5) doMoveOrdering(board, puttablePositions, currentTurn, evaluator); // 自分の番では、評価が最も大きくなるものを選ぶ。 double maxScore = Double.NEGATIVE_INFINITY; Position selectedPosition = null; for (Position p : puttablePositions) { Board b = board.clone(); Evaluator e = evaluator.clone(); e.willPut(b, p.x, p.y, currentTurn.stone()); b.put(p.x, p.y, currentTurn.stone()); double a = Math.max(alpha, maxScore); double score = -eval(b, restDepth - 1, currentTurn.flip(), e, -(a + 1), -a).getScore(); if (a < score && score < beta) { e = evaluator.clone(); e.willPut(board, p.x, p.y, currentTurn.stone()); score = -eval(b, restDepth - 1, currentTurn.flip(), e, -beta, -score).getScore(); } if (maxScore < score) { maxScore = score; selectedPosition = p; } // beta cut if (maxScore >= beta) return new EvalResult(score, p); } assert (selectedPosition != null); return new EvalResult(maxScore, selectedPosition); }
protected List<Position> doMoveOrdering( Board board, List<Position> ps, Turn currentTurn, Evaluator evaluator) { List<EvalResult> shallowEvaluation = new ArrayList<EvalResult>(); for (Position p : ps) { Board b = board.clone(); Evaluator e = evaluator.clone(); e.willPut(board, p.x, p.y, currentTurn.stone()); b.put(p.x, p.y, currentTurn.stone()); EvalResult er = eval(b, 2, currentTurn.flip(), e); shallowEvaluation.add(new EvalResult(-er.getScore(), p)); } // スコアの大きい方から並べる。 Collections.sort(shallowEvaluation, new HandComparator()); List<Position> result = new ArrayList<Position>(); for (EvalResult er : shallowEvaluation) result.add(er.getPosition()); return result; }