/**
   * estimate the rarity of each resource
   *
   * @return an array of rarity numbers where estimates[SOCBoard.CLAY_HEX] == the clay rarity
   */
  protected int[] estimateResourceRarity(SOCGame game) {
    if (resourceEstimates == null) {
      SOCBoard board = game.getBoard();
      int[] numberWeights = SOCNumberProbabilities.INT_VALUES;

      resourceEstimates = new int[6];

      resourceEstimates[0] = 0;

      // look at each hex
      final int L = board.getNumberLayout().length;
      for (int i = 0; i < L; i++) {
        int hexNumber = board.getNumberOnHexFromNumber(i);

        if (hexNumber > 0) {
          resourceEstimates[board.getHexTypeFromNumber(i)] += numberWeights[hexNumber];
        }
      }
    }

    // D.ebugPrint("Resource Estimates = ");
    for (int i = 1; i < 6; i++) {
      // D.ebugPrint(i+":"+resourceEstimates[i]+" ");
    }

    // log.debug();
    return resourceEstimates;
  }
  /**
   * Estimate the rarity of each resource, given this board's resource locations vs dice numbers.
   * Useful for initial settlement placement and free-resource choice (when no other info
   * available). This is based on the board and doesn't change when pieces are placed. Cached after
   * the first call, as {@link #resourceEstimates}.
   *
   * <p>Calls each hex's {@link SOCBoard#getHexTypeFromCoord(int)}, ignores all hex types besides
   * the usual {@link SOCBoard#CLAY_HEX} through {@link SOCBoard#WOOD_HEX} and {@link
   * SOCBoardLarge#GOLD_HEX}.
   *
   * @return an array of rarity numbers, where estimates[SOCBoard.CLAY_HEX] == the clay rarity, as
   *     an integer percentage 0-100 of dice rolls.
   */
  public int[] estimateResourceRarity() {
    if (resourceEstimates == null) {
      final SOCBoard board = game.getBoard();
      final int[] numberWeights = SOCNumberProbabilities.INT_VALUES;

      resourceEstimates = new int[SOCResourceConstants.UNKNOWN]; // uses 1 to 5 (CLAY to WOOD)
      resourceEstimates[0] = 0;

      // look at each hex
      if (board.getBoardEncodingFormat() <= SOCBoard.BOARD_ENCODING_6PLAYER) {
        // v1 or v2 encoding
        final int L = board.getNumberLayout().length;
        for (int i = 0; i < L; i++) {
          final int hexNumber = board.getNumberOnHexFromNumber(i);
          if (hexNumber > 0)
            resourceEstimates[board.getHexTypeFromNumber(i)] += numberWeights[hexNumber];
        }
      } else {
        // v3 encoding
        final int[] hcoord = board.getLandHexCoords();
        if (hcoord != null) {
          final int L = hcoord.length;
          for (int i = 0; i < L; i++) {
            final int hexNumber = board.getNumberOnHexFromCoord(hcoord[i]);
            if (hexNumber == 0) continue;

            final int htype = board.getHexTypeFromCoord(hcoord[i]);
            if (htype == SOCBoardLarge.GOLD_HEX) {
              // Count gold as all resource types
              for (int ht = SOCBoard.CLAY_HEX; ht <= SOCBoard.WOOD_HEX; ++ht)
                resourceEstimates[ht] += numberWeights[hexNumber];
            } else if ((htype >= 0) && (htype <= SOCBoard.WOOD_HEX)) {
              resourceEstimates[htype] += numberWeights[hexNumber];
            }
          }
        }
      }
    }

    // D.ebugPrint("Resource Estimates = ");
    // for (int i = 1; i < 6; i++)
    // {
    // D.ebugPrint(i+":"+resourceEstimates[i]+" ");
    // }

    // log.debug();

    return resourceEstimates;
  }