// TODO redesign keep strategy to allow keeping both highest and lowest private static BigInteger roll(BigInteger dieType, long dieCount, long keepCount, KeepStrategy keepStrategy) { if (dieType <= 1) { throw new InvalidExpressionException ("invalid die"); } // if the diecount is negative we will roll with the positive diecount, but negate the end result. // basically, "-5d6" is treated as "-(5d6)" bool negative = false; if (dieCount < 0) { negative = true; dieCount = -dieCount; } keepCount = Math.Min(keepCount, dieCount); // roll the dice and keep them in an array BigInteger[] results = new BigInteger[dieCount]; for (int i = 0; i < dieCount; i++) { BigInteger num = new BigInteger (); num.genRandomBits (dieType.bitCount (), RAND); results [i] = num; } // add up the results based on the strategy used BigInteger result = 0; if (keepStrategy == KeepStrategy.ALL) { for (int i = 0; i < dieCount; i++) { result += results [i]; } } else { // we are only keeping some, so sort the list Array.Sort (results); if (keepStrategy == KeepStrategy.HIGHEST) { for (long i = dieCount - 1; i >= dieCount - keepCount; i--) { result += results [i]; } } else if (keepStrategy == KeepStrategy.LOWEST) { for (int i = 0; i < keepCount; i++) { result += results [i]; } } } if (negative) { result = -result; } return result; }
/// <summary> /// Constructs a DiceToken using a BigInteger instead of a postfix token list /// </summary> public DiceToken(BigInteger count, BigInteger type, long keepCount, KeepStrategy strategy, Roller r) : this(new List<Token> (), type, keepCount, strategy, r) { this.countTokens.Add (new NumToken(count)); }
/// <summary> /// Constructs a DiceToken using a postfix token list as the diecount (allowing expressions determining how many dice to roll) /// </summary> public DiceToken(List<Token> count, BigInteger type, long keepCount, KeepStrategy strategy, Roller r) { this.countTokens = count; this.type = type; this.keepCount = keepCount; this.strategy = strategy; this.r = r; }