/**
   * Takes a table of nodes and adds a weighted score to each node score in the table. Nodes
   * touching hexes with better numbers get better scores. Also numbers that the player isn't
   * touching yet are better than ones that the player is already touching.
   *
   * @param nodes the table of nodes with scores: Hashtable<Integer,Integer> . Contents will
   *     be modified by the scoring.
   * @param player the player that we are doing the rating for, or <tt>null</tt>; will give a bonus
   *     to numbers the player isn't already touching
   * @param weight a number that is multiplied by the score
   */
  protected void bestSpotForNumbers(
      Hashtable<Integer, Integer> nodes, SOCPlayer player, int weight) {
    final int[] numRating = SOCNumberProbabilities.INT_VALUES;
    final SOCPlayerNumbers playerNumbers = (player != null) ? player.getNumbers() : null;
    final SOCBoard board = game.getBoard();

    // 80 is highest practical score (40 if player == null)
    final int maxScore = (player != null) ? 80 : 40;

    int oldScore;
    Enumeration<Integer> nodesEnum = nodes.keys();

    while (nodesEnum.hasMoreElements()) {
      final Integer node = nodesEnum.nextElement();

      // log.debug("BSN - looking at node "+Integer.toHexString(node.intValue()));
      oldScore = nodes.get(node).intValue();

      int score = 0;
      Enumeration<Integer> hexesEnum = board.getAdjacentHexesToNode(node.intValue()).elements();

      while (hexesEnum.hasMoreElements()) {
        final int hex = hexesEnum.nextElement().intValue();
        final int number = board.getNumberOnHexFromCoord(hex);
        score += numRating[number];

        if ((number != 0) && (playerNumbers != null) && !playerNumbers.hasNumber(number)) {
          /** add a bonus for numbers that the player doesn't already have */

          // log.debug("ADDING BONUS FOR NOT HAVING "+number);
          score += numRating[number];
        }

        // log.debug(" -- -- Adding "+numRating[board.getNumberOnHexFromCoord(hex)]);
      }

      /*
       * normalize score and multiply by weight
       * 80 is highest practical score (40 if player == null)
       * lowest score is 0
       */
      final int nScore = ((score * 100) / maxScore) * weight;
      final Integer finalScore = new Integer(nScore + oldScore);
      nodes.put(node, finalScore);

      // log.debug("BSN -- put node "+Integer.toHexString(node.intValue())+" with old score
      // "+oldScore+" + new score "+nScore);
    }
  }