/**
   * Calculate what resources this player will get on each die roll, optionally taking the robber
   * into account.
   *
   * @param numbers the numbers that the player is touching
   * @param robberHex Robber location from {@link SOCBoard#getRobberHex()}, or -1 to ignore the
   *     robber
   */
  public void recalculateResourcesForRoll(SOCPlayerNumbers numbers, final int robberHex) {
    // D.ebugPrintln("@@@@@@@@ recalculateResourcesForRoll");
    // D.ebugPrintln("@@@@@@@@ numbers = "+numbers);
    // D.ebugPrintln("@@@@@@@@ robberHex = "+Integer.toHexString(robberHex));
    recalc = true;

    for (int diceResult = 2; diceResult <= 12; diceResult++) {
      Vector<Integer> resources =
          (robberHex != -1)
              ? numbers.getResourcesForNumber(diceResult, robberHex)
              : numbers.getResourcesForNumber(diceResult);

      if (resources != null) {
        SOCResourceSet resourceSet = resourcesForRoll[diceResult];

        if (resourceSet == null) {
          resourceSet = new SOCResourceSet();
          resourcesForRoll[diceResult] = resourceSet;
        } else {
          resourceSet.clear();
        }

        Enumeration<Integer> resourcesEnum = resources.elements();

        while (resourcesEnum.hasMoreElements()) {
          Integer resourceInt = resourcesEnum.nextElement();
          resourceSet.add(1, resourceInt.intValue());
        }

        // D.ebugPrintln("### resources for "+diceResult+" = "+resourceSet);
      }
    }
  }
Пример #2
0
  /**
   * DOCUMENT ME!
   *
   * @param b DOCUMENT ME!
   */
  public void setVisible(boolean b) {
    if (b) {
      /** set initial values */
      SOCPlayer player =
          playerInterface.getGame().getPlayer(playerInterface.getClient().getNickname());
      SOCResourceSet resources = player.getResources();
      keep[0].setIntValue(resources.getAmount(SOCResourceConstants.CLAY));
      keep[1].setIntValue(resources.getAmount(SOCResourceConstants.ORE));
      keep[2].setIntValue(resources.getAmount(SOCResourceConstants.SHEEP));
      keep[3].setIntValue(resources.getAmount(SOCResourceConstants.WHEAT));
      keep[4].setIntValue(resources.getAmount(SOCResourceConstants.WOOD));

      discardBut.requestFocus();
    }

    super.setVisible(b);
  }
Пример #3
0
  /**
   * DOCUMENT ME!
   *
   * @param e DOCUMENT ME!
   */
  public void actionPerformed(ActionEvent e) {
    Object target = e.getSource();

    if (target == discardBut) {
      SOCResourceSet rsrcs =
          new SOCResourceSet(
              disc[0].getIntValue(),
              disc[1].getIntValue(),
              disc[2].getIntValue(),
              disc[3].getIntValue(),
              disc[4].getIntValue(),
              0);

      if (rsrcs.getTotal() == numDiscards) {
        playerInterface.getClient().discard(playerInterface.getGame(), rsrcs);
        dispose();
      }
    }
  }
  /**
   * this figures out how many rolls it would take this player to get the target set of resources
   * given a starting set
   *
   * @param startingResources the starting resources
   * @param targetResources the target resources
   * @param cutoff throw an exception if the total speed is greater than this
   * @param ports a list of port flags
   * @return the number of rolls and our resources when the target is reached. If {@link
   *     SOCResourceSet#contains(SOCResourceSet) startingResources.contains(targetResources)},
   *     returns 0 rolls and a {@code null} resource set.
   * @throws CutoffExceededException if estimate more than {@code cutoff} turns to obtain {@code
   *     targetResources}
   */
  protected SOCResSetBuildTimePair calculateRollsAccurate(
      SOCResourceSet startingResources, SOCResourceSet targetResources, int cutoff, boolean[] ports)
      throws CutoffExceededException {
    D.ebugPrintln("calculateRollsAccurate");
    D.ebugPrintln("  start: " + startingResources);
    D.ebugPrintln("  target: " + targetResources);

    SOCResourceSet ourResources = startingResources.copy();
    int rolls = 0;

    @SuppressWarnings("unchecked")
    Hashtable<SOCResourceSet, Float>[] resourcesOnRoll = new Hashtable[2];
    resourcesOnRoll[0] = new Hashtable<SOCResourceSet, Float>();
    resourcesOnRoll[1] = new Hashtable<SOCResourceSet, Float>();

    int lastRoll = 0;
    int thisRoll = 1;

    resourcesOnRoll[lastRoll].put(ourResources, new Float(1.0));

    boolean targetReached = ourResources.contains(targetResources);
    SOCResourceSet targetReachedResources = null;
    float targetReachedProb = (float) 0.0;

    while (!targetReached) {
      if (D.ebugOn) {
        D.ebugPrintln("roll: " + rolls);
        D.ebugPrintln("resourcesOnRoll[lastRoll]:");

        Enumeration<SOCResourceSet> roltEnum = resourcesOnRoll[lastRoll].keys();

        while (roltEnum.hasMoreElements()) {
          SOCResourceSet rs = roltEnum.nextElement();
          Float prob = resourcesOnRoll[lastRoll].get(rs);
          D.ebugPrintln("---- prob:" + prob);
          D.ebugPrintln("---- rsrcs:" + rs);
          D.ebugPrintln();
        }

        D.ebugPrintln("targetReachedProb: " + targetReachedProb);
        D.ebugPrintln("===================================");
      }

      rolls++;

      if (rolls > cutoff) {
        D.ebugPrintln(
            "startingResources="
                + startingResources
                + "\ntargetResources="
                + targetResources
                + "\ncutoff="
                + cutoff
                + "\nourResources="
                + ourResources);
        throw new CutoffExceededException();
      }

      //
      //  get our resources for the roll
      //
      for (int diceResult = 2; diceResult <= 12; diceResult++) {
        SOCResourceSet gainedResources = resourcesForRoll[diceResult];
        float diceProb = SOCNumberProbabilities.FLOAT_VALUES[diceResult];

        //
        //  add the resources that we get on this roll to
        //  each set of resources that we got on the last
        //  roll and multiply the probabilities
        //
        Enumeration<SOCResourceSet> lastResourcesEnum = resourcesOnRoll[lastRoll].keys();

        while (lastResourcesEnum.hasMoreElements()) {
          SOCResourceSet lastResources = lastResourcesEnum.nextElement();
          Float lastProb = resourcesOnRoll[lastRoll].get(lastResources);
          SOCResourceSet newResources = lastResources.copy();
          newResources.add(gainedResources);

          float newProb = lastProb.floatValue() * diceProb;

          if (!newResources.contains(targetResources)) {
            //
            // do any possible trading with the bank/ports
            //
            for (int giveResource = SOCResourceConstants.CLAY;
                giveResource <= SOCResourceConstants.WOOD;
                giveResource++) {
              if ((newResources.getAmount(giveResource) - targetResources.getAmount(giveResource))
                  > 1) {
                //
                // find the ratio at which we can trade
                //
                int tradeRatio;

                if (ports[giveResource]) {
                  tradeRatio = 2;
                } else if (ports[SOCBoard.MISC_PORT]) {
                  tradeRatio = 3;
                } else {
                  tradeRatio = 4;
                }

                //
                // get the target resources
                //
                int numTrades =
                    (newResources.getAmount(giveResource) - targetResources.getAmount(giveResource))
                        / tradeRatio;

                // D.ebugPrintln("))) ***");
                // D.ebugPrintln("))) giveResource="+giveResource);
                // D.ebugPrintln("))) tradeRatio="+tradeRatio);
                // D.ebugPrintln("))) newResources="+newResources);
                // D.ebugPrintln("))) targetResources="+targetResources);
                // D.ebugPrintln("))) numTrades="+numTrades);
                for (int trades = 0; trades < numTrades; trades++) {
                  //
                  // find the most needed resource by looking at
                  // which of the resources we still need takes the
                  // longest to aquire
                  //
                  int mostNeededResource = -1;

                  for (int resource = SOCResourceConstants.CLAY;
                      resource <= SOCResourceConstants.WOOD;
                      resource++) {
                    if (newResources.getAmount(resource) < targetResources.getAmount(resource)) {
                      if (mostNeededResource < 0) {
                        mostNeededResource = resource;
                      } else {
                        if (rollsPerResource[resource] > rollsPerResource[mostNeededResource]) {
                          mostNeededResource = resource;
                        }
                      }
                    }
                  }

                  //
                  // make the trade
                  //
                  // D.ebugPrintln("))) want to trade "+tradeRatio+" "+giveResource+" for a
                  // "+mostNeededResource);
                  if ((mostNeededResource != -1)
                      && (newResources.getAmount(giveResource) >= tradeRatio)) {
                    // D.ebugPrintln("))) trading...");
                    newResources.add(1, mostNeededResource);

                    if (newResources.getAmount(giveResource) < tradeRatio) {
                      System.err.println("@@@ rsrcs=" + newResources);
                      System.err.println("@@@ tradeRatio=" + tradeRatio);
                      System.err.println("@@@ giveResource=" + giveResource);
                      System.err.println("@@@ target=" + targetResources);
                    }

                    newResources.subtract(tradeRatio, giveResource);

                    // D.ebugPrintln("))) newResources="+newResources);
                  }

                  if (newResources.contains(targetResources)) {
                    break;
                  }
                }

                if (newResources.contains(targetResources)) {
                  break;
                }
              }
            }
          }

          //
          //  if this set of resources is already in the list
          //  of possible outcomes, add this probability to
          //  that one, else just add this to the list
          //
          Float probFloat = resourcesOnRoll[thisRoll].get(newResources);
          float newProb2 = newProb;

          if (probFloat != null) {
            newProb2 = probFloat.floatValue() + newProb;
          }

          //
          //  check to see if we reached our target
          //
          if (newResources.contains(targetResources)) {
            D.ebugPrintln("-----> TARGET HIT *");
            D.ebugPrintln("newResources: " + newResources);
            D.ebugPrintln("newProb: " + newProb);
            targetReachedProb += newProb;

            if (targetReachedResources == null) {
              targetReachedResources = newResources;
            }

            if (targetReachedProb >= 0.5) {
              targetReached = true;
            }
          } else {
            resourcesOnRoll[thisRoll].put(newResources, new Float(newProb2));
          }
        }
      }

      //
      //  copy the resourcesOnRoll[thisRoll] table to the
      //  resourcesOnRoll[lastRoll] table and clear the
      //  resourcesOnRoll[thisRoll] table
      //
      int tmp = lastRoll;
      lastRoll = thisRoll;
      thisRoll = tmp;
      resourcesOnRoll[thisRoll].clear();
    }

    if (D.ebugOn) {
      float probSum = (float) 0.0;
      D.ebugPrintln("**************** TARGET REACHED ************");
      D.ebugPrintln("targetReachedResources: " + targetReachedResources);
      D.ebugPrintln("targetReachedProb: " + targetReachedProb);
      D.ebugPrintln("roll: " + rolls);
      D.ebugPrintln("resourcesOnRoll[lastRoll]:");

      Enumeration<SOCResourceSet> roltEnum = resourcesOnRoll[lastRoll].keys();

      while (roltEnum.hasMoreElements()) {
        SOCResourceSet rs = roltEnum.nextElement();
        Float prob = resourcesOnRoll[lastRoll].get(rs);
        probSum += prob.floatValue();
        D.ebugPrintln("---- prob:" + prob);
        D.ebugPrintln("---- rsrcs:" + rs);
        D.ebugPrintln();
      }

      D.ebugPrintln("probSum = " + probSum);
      D.ebugPrintln("===================================");
    }

    return (new SOCResSetBuildTimePair(targetReachedResources, rolls));
  }
  /**
   * this figures out how many rolls it would take this player to get the target set of resources
   * given a starting set
   *
   * <p>Before v2.0.00, this was {@code calculateRollsFast}.
   *
   * @param startingResources the starting resources
   * @param targetResources the target resources
   * @param cutoff throw an exception if the total speed is greater than this
   * @param ports a list of port flags
   * @return the number of rolls, and startingResources after any trading. If {@link
   *     SOCResourceSet#contains(SOCResourceSet) startingResources.contains(targetResources)},
   *     returns 0 rolls and a copy of {@code startingResources} with identical amounts.
   * @throws CutoffExceededException if total number of rolls &gt; {@code cutoff}
   * @see #calculateRollsFast(SOCResourceSet, SOCResourceSet, int, boolean[])
   */
  protected SOCResSetBuildTimePair calculateRollsAndRsrcFast(
      final SOCResourceSet startingResources,
      final SOCResourceSet targetResources,
      final int cutoff,
      final boolean[] ports)
      throws CutoffExceededException {
    // D.ebugPrintln("calculateRolls");
    // D.ebugPrintln("  start: "+startingResources);
    // D.ebugPrintln("  target: "+targetResources);
    SOCResourceSet ourResources = startingResources.copy();
    int rolls = 0;

    if (!ourResources.contains(targetResources)) {
      /** do any possible trading with the bank/ports */
      for (int giveResource = SOCResourceConstants.CLAY;
          giveResource <= SOCResourceConstants.WOOD;
          giveResource++) {
        /** find the ratio at which we can trade */
        int tradeRatio;

        if (ports[giveResource]) {
          tradeRatio = 2;
        } else if (ports[SOCBoard.MISC_PORT]) {
          tradeRatio = 3;
        } else {
          tradeRatio = 4;
        }

        /** get the target resources */
        int numTrades =
            (ourResources.getAmount(giveResource) - targetResources.getAmount(giveResource))
                / tradeRatio;

        // D.ebugPrintln("))) ***");
        // D.ebugPrintln("))) giveResource="+giveResource);
        // D.ebugPrintln("))) tradeRatio="+tradeRatio);
        // D.ebugPrintln("))) ourResources="+ourResources);
        // D.ebugPrintln("))) targetResources="+targetResources);
        // D.ebugPrintln("))) numTrades="+numTrades);
        for (int trades = 0; trades < numTrades; trades++) {
          /**
           * find the most needed resource by looking at which of the resources we still need takes
           * the longest to aquire
           */
          int mostNeededResource = -1;

          for (int resource = SOCResourceConstants.CLAY;
              resource <= SOCResourceConstants.WOOD;
              resource++) {
            if (ourResources.getAmount(resource) < targetResources.getAmount(resource)) {
              if (mostNeededResource < 0) {
                mostNeededResource = resource;
              } else {
                if (rollsPerResource[resource] > rollsPerResource[mostNeededResource]) {
                  mostNeededResource = resource;
                }
              }
            }
          }

          /** make the trade */

          // D.ebugPrintln("))) want to trade "+tradeRatio+" "+giveResource+" for a
          // "+mostNeededResource);
          if ((mostNeededResource != -1) && (ourResources.getAmount(giveResource) >= tradeRatio)) {
            // D.ebugPrintln("))) trading...");
            ourResources.add(1, mostNeededResource);

            if (ourResources.getAmount(giveResource) < tradeRatio) {
              System.err.println("@@@ rsrcs=" + ourResources);
              System.err.println("@@@ tradeRatio=" + tradeRatio);
              System.err.println("@@@ giveResource=" + giveResource);
              System.err.println("@@@ target=" + targetResources);
            }

            ourResources.subtract(tradeRatio, giveResource);

            // D.ebugPrintln("))) ourResources="+ourResources);
          }

          if (ourResources.contains(targetResources)) {
            break;
          }
        }

        if (ourResources.contains(targetResources)) {
          break;
        }
      }
    }

    while (!ourResources.contains(targetResources)) {
      // D.ebugPrintln("roll: "+rolls);
      // D.ebugPrintln("resources: "+ourResources);
      rolls++;

      if (rolls > cutoff) {
        // D.ebugPrintln("startingResources="+startingResources+"\ntargetResources="+targetResources+"\ncutoff="+cutoff+"\nourResources="+ourResources);
        throw new CutoffExceededException();
      }

      for (int resource = SOCResourceConstants.CLAY;
          resource <= SOCResourceConstants.WOOD;
          resource++) {
        // D.ebugPrintln("resource: "+resource);
        // D.ebugPrintln("rollsPerResource: "+rollsPerResource[resource]);

        /** get our resources for the roll */
        if ((rollsPerResource[resource] == 0) || ((rolls % rollsPerResource[resource]) == 0)) {
          ourResources.add(1, resource);
        }
      }

      if (!ourResources.contains(targetResources)) {
        /** do any possible trading with the bank/ports */
        for (int giveResource = SOCResourceConstants.CLAY;
            giveResource <= SOCResourceConstants.WOOD;
            giveResource++) {
          /** find the ratio at which we can trade */
          int tradeRatio;

          if (ports[giveResource]) {
            tradeRatio = 2;
          } else if (ports[SOCBoard.MISC_PORT]) {
            tradeRatio = 3;
          } else {
            tradeRatio = 4;
          }

          /** get the target resources */
          int numTrades =
              (ourResources.getAmount(giveResource) - targetResources.getAmount(giveResource))
                  / tradeRatio;

          // D.ebugPrintln("))) ***");
          // D.ebugPrintln("))) giveResource="+giveResource);
          // D.ebugPrintln("))) tradeRatio="+tradeRatio);
          // D.ebugPrintln("))) ourResources="+ourResources);
          // D.ebugPrintln("))) targetResources="+targetResources);
          // D.ebugPrintln("))) numTrades="+numTrades);
          for (int trades = 0; trades < numTrades; trades++) {
            /**
             * find the most needed resource by looking at which of the resources we still need
             * takes the longest to aquire
             */
            int mostNeededResource = -1;

            for (int resource = SOCResourceConstants.CLAY;
                resource <= SOCResourceConstants.WOOD;
                resource++) {
              if (ourResources.getAmount(resource) < targetResources.getAmount(resource)) {
                if (mostNeededResource < 0) {
                  mostNeededResource = resource;
                } else {
                  if (rollsPerResource[resource] > rollsPerResource[mostNeededResource]) {
                    mostNeededResource = resource;
                  }
                }
              }
            }

            /** make the trade */

            // D.ebugPrintln("))) want to trade "+tradeRatio+" "+giveResource+" for a
            // "+mostNeededResource);
            if ((mostNeededResource != -1)
                && (ourResources.getAmount(giveResource) >= tradeRatio)) {
              // D.ebugPrintln("))) trading...");
              ourResources.add(1, mostNeededResource);

              if (ourResources.getAmount(giveResource) < tradeRatio) {
                System.err.println("@@@ rsrcs=" + ourResources);
                System.err.println("@@@ tradeRatio=" + tradeRatio);
                System.err.println("@@@ giveResource=" + giveResource);
                System.err.println("@@@ target=" + targetResources);
              }

              ourResources.subtract(tradeRatio, giveResource);

              // D.ebugPrintln("))) ourResources="+ourResources);
            }

            if (ourResources.contains(targetResources)) {
              break;
            }
          }

          if (ourResources.contains(targetResources)) {
            break;
          }
        }
      }
    }

    return (new SOCResSetBuildTimePair(ourResources, rolls));
  }