Example #1
0
  /**
   * Alpha-Beta Negamax algorithm. Go check on wikipedia!
   *
   * @param evaluatedBoard The board currently evaluated.
   * @param resultBoard (Optional) The board that will store the result of the best move.
   * @param alpha Alpha parameter, to cut some leaves on the multiverse tree.
   * @param beta Alpha parameter, to cut even more leaves on the multiverse tree.
   * @param depth The current depth of the reflexion.
   * @return The best you can do with the worst the other player can do with the best you can do
   *     with...
   */
  public int negaMax(Board evaluatedBoard, Board resultBoard, int alpha, int beta, int depth) {
    // If it's a leaf, evaluate.
    if (depth == MAX_DEPTH
        || evaluatedBoard.numberOf(DWARF) == 0
        || evaluatedBoard.numberOf(TROLL) == 0) {
      return evaluate(evaluatedBoard);
    }

    List<Board> childrenBoards = evaluatedBoard.childrenBoards();
    /* Map<Board, Integer> boardValues = new HashMap<>();
    for (Board childrenBoard : childrenBoards)
    {
    boardValues.put(childrenBoard, evaluate(childrenBoard));
    }

    // Sort those boards with the evaluation method, to evaluate the most interesting moves.
    Collections.sort(childrenBoards, (board1, board2) -> Integer.compare(boardValues.get(board2), boardValues.get(board1))); */

    // Look for the best value on children boards.
    int boardIndex;
    int bestValue = -INFINITY;
    for (boardIndex = 0; boardIndex < childrenBoards.size(); boardIndex++) {
      // Update the progress callback, if any.
      if (depth == 0 && progressCallback != null) {
        progressCallback.accept(100 * boardIndex / childrenBoards.size());
      }

      Board childBoard = childrenBoards.get(boardIndex);
      // Get the score of the child. The negamax, a specific implementation of the Minimax, requires
      // switching and inverting values here.
      int score = -negaMax(childBoard, null, -beta, -alpha, depth + 1);

      if (score > bestValue) {
        bestValue = score;
        // If we're at depth zero, keep track of the best board.
        if (depth == 0) {
          if (resultBoard != null) {
            resultBoard.set(childBoard);
          }
        }
      }

      // Alpha-beta pruning
      alpha = Math.max(alpha, score);
      if (alpha >= beta) {
        break;
      }
    }

    return bestValue;
  }