Example #1
0
  /**
   * Main method Boy, does this need testing!
   *
   * @param args
   */
  public static void main(final String[] args) {
    Logging.setDebugMode(true);

    for (int i = 0; i < args.length; ++i) {
      final RollInfo ri = new RollInfo(args[i]);
      Logging.debugPrint(ri + ": " + RollInfo.roll());
    }
  }
Example #2
0
  public static String parseRollInfo(RollInfo rollInfo, String rollString) {
    // To really do this right, we change the token string
    // as we go along so that we maintain parser state by
    // means of the tokens rather than something more
    // explicit.  In truth, this is an ideal application
    // of flex and friends for a "mini-language" whose
    // statements evaluate to dice rolls.  Too much LISP
    // on the brain.  --bko
    final StringTokenizer st = new StringTokenizer(rollString, " ", true);

    try {
      String tok = st.nextToken("d");

      if ("d".equals(tok)) {
        rollInfo.times = 1;
      } else {
        rollInfo.times = Integer.parseInt(tok);

        if (st.hasMoreTokens()) {
          tok = st.nextToken("d"); // discard the 'd'

          if (!"d".equals(tok)) {
            return "Bad roll parsing in '" + rollString + "': missing 'd'";
          }
        } else {
          rollInfo.sides = 1;

          return "";
        }
      }

      String parseChars = "/\\|mM+-tT";
      rollInfo.sides = Integer.parseInt(st.nextToken(parseChars));

      if (rollInfo.sides < 1) {
        return "Bad roll parsing in '" + rollString + "': sides < 1: " + rollInfo.sides;
      }

      while (st.hasMoreTokens()) {
        tok = st.nextToken(parseChars);

        switch (tok.charAt(0)) {
          case '/':
            parseChars = "mM+-tT";

            final int keepTop = Integer.parseInt(st.nextToken(parseChars));

            if (keepTop > rollInfo.times) {
              return "Bad keepTop in '"
                  + rollString
                  + "': times: "
                  + rollInfo.times
                  + "; keepTop: "
                  + keepTop;
            }

            rollInfo.keepList = new boolean[rollInfo.times];

            // Rely on fact boolean is false by default.  --bko
            for (int i = rollInfo.times - keepTop; i < rollInfo.times; ++i) {
              rollInfo.keepList[i] = true;
            }

            break;

          case '\\':
            parseChars = "mM+-tT";

            final int keepBottom = Integer.parseInt(st.nextToken(parseChars));

            if (keepBottom > rollInfo.times) {
              return "Bad keepBottom in '"
                  + rollString
                  + "': times: "
                  + rollInfo.times
                  + "; keepBottom: "
                  + keepBottom;
            }

            rollInfo.keepList = new boolean[rollInfo.times];

            // Rely on fact boolean is false by default.  --bko
            for (int i = 0; i < keepBottom; ++i) {
              rollInfo.keepList[i] = true;
            }

            break;

          case '|':
            parseChars = "mM+-tT";
            tok = st.nextToken(parseChars);
            rollInfo.keepList = new boolean[rollInfo.times];

            final StringTokenizer keepSt = new StringTokenizer(tok, ",");

            while (keepSt.hasMoreTokens()) {
              rollInfo.keepList[Integer.parseInt(keepSt.nextToken(",")) - 1] = true;
            }

            break;

          case 'm':
            parseChars = "M+-tT";
            rollInfo.rerollBelow = Integer.parseInt(st.nextToken(parseChars));

            break;

          case 'M':
            parseChars = "m+-tT";
            rollInfo.rerollAbove = Integer.parseInt(st.nextToken(parseChars));

            break;

          case '+':
            parseChars = "tT";
            rollInfo.modifier = Integer.parseInt(st.nextToken(" "));

            break;

          case '-':
            parseChars = "tT";
            rollInfo.modifier = -Integer.parseInt(st.nextToken(" "));

            break;

          case 't':
            parseChars = "T";
            rollInfo.totalFloor = Integer.parseInt(st.nextToken(" "));

            break;

          case 'T':
            parseChars = "t";
            rollInfo.totalCeiling = Integer.parseInt(st.nextToken(" "));

            break;

          default:
            Logging.errorPrint(
                "Bizarre dice parser error in '" + rollString + "': not a valid delimiter");
            return "Bad roll parsing in '"
                + rollString
                + "': invalid delimiter '"
                + tok.charAt(0)
                + "'.";
        }
      }
    } catch (NumberFormatException ex) {
      if (Logging.isDebugMode()) {
        Logging.debugPrint("Bad roll string in '" + rollString + "': " + ex, ex);
      }
      return "Bad roll string in '" + rollString + "': " + ex;
    }
    return "";
  }
Example #3
0
 /**
  * Construct a <code>RollInfo</code> from a string. The rules:
  *
  * <ol>
  *   <li>Optional positive integer, <var>times</var>.
  *   <li>Literal 'd' followed by positive integer, <var>sides</var>.
  *   <li>Optional literal '/' followed by positive integer, <var>keepTop</var>, or literal '\'
  *       followed by positive integer, <var>keepBottom</var>, or literal '|' followed by
  *       comma-separated list of postitive integers, <var>keepList</var> (1-indexed after dice
  *       have been sorted).
  *   <li>Optional literal 'm' (minimum) followed by positive integer, <var>rerollAbove</var>, or
  *       literal 'M' (maximum) followed by postive integer, <var>rerollBelow</var>.
  *   <li>Optional literal '+' or '-' followed by positive integer, <var>modifier</var>.
  *   <li>Optional literal 't' followed by positive integer, <var>totalFloor</var>, or literal 'T'
  *       followed by a positive *integer, <var>totalCeiling</var>.
  * </ol>
  *
  * Unlike previous versions of this method, it is <strong>case-sensitive</strong> with respect to
  * the alphabetic characters, e.g., only <code>d</code> (lower-case) is now valid, not also <code>
  * D</code> (upper-case). This is to accommodate the expanded ways to roll.
  *
  * @param rollString String compact representation of dice rolls
  */
 public RollInfo(final String rollString) {
   String errMsg = RollInfo.parseRollInfo(this, rollString);
   if (!StringUtils.isBlank(errMsg)) {
     Logging.errorPrint(errMsg);
   }
 }