Пример #1
0
  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));
  }
  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;
  }
  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);
  }