public Player CreateNewPlayer(IDieScoreCalculator dieScoreCalculator, IDieRoller dieRoller, IUserInterface userInterface, string playerName)
        {
            var gameState           = new PlayerGameState();
            var playerTurnProcessor = new PlayerTurnProcessor(dieScoreCalculator, dieRoller, userInterface, gameState);

            return(new Player(gameState, playerTurnProcessor, playerName));
        }
 public PlayerTurnProcessor(IDieScoreCalculator dieScoreCalculator, IDieRoller dieRoller, IUserInterface userInterface, PlayerGameState playerGameState)
 {
     DieScoreCalculator = dieScoreCalculator;
     DieRoller          = dieRoller;
     PlayerGameState    = playerGameState;
     UserInterface      = userInterface;
 }
        /// <summary>
        /// Gets the die roller based on specified type.
        /// </summary>
        /// <param name="type">Type string</param>
        /// <param name="tracker">Die roll tracker to use</param>
        /// <returns>Instance of die roller, or null if none found.</returns>
        public IDieRoller GetDieRoller(string type, IDieRollTracker tracker = null)
        {
            IDieRoller roller = null;

            if (type == typeof(ConstantDieRoller).ToString())
            {
                roller = new ConstantDieRoller();
            }
            else if (type == typeof(RandomDieRoller).ToString())
            {
                roller = new RandomDieRoller(tracker);
            }
            else if (type == typeof(SecureRandomDieRoller).ToString())
            {
                roller = new SecureRandomDieRoller(tracker);
            }
            else if (type == typeof(MathNetDieRoller).ToString())
            {
                roller = new MathNetDieRoller(tracker);
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(type));
            }

            return(roller);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DiceRollerViewModel"/> class.
        /// </summary>
        public DiceRollerViewModel()
        {
            AppServices services = AppServices.Instance;

            this.dice = services.DiceService;
            string rollerType = services.AppSettingsService.CurrentDieRollerType;

            this.dieRoller = services.DieRollerFactory.GetDieRoller(rollerType, services.DiceFrequencyTracker);
        }
Beispiel #5
0
        /// <inheritdoc/>
        public IReadOnlyList <TermResult> CalculateResults(IDieRoller dieRoller)
        {
            List <TermResult> results = new List <TermResult>
            {
                new TermResult {
                    Scalar = 1, Value = this.constant, Type = this.GetType().Name
                }
            };

            return(results.AsReadOnly());
        }
        /// <summary>
        /// Parses the specified dice expression and converts it into a
        /// Dice instance to perform oprations on.
        /// </summary>
        /// <param name="expression">String expression to parse</param>
        /// <param name="config">Dice config to tell whether this result will be bounded or unbounded</param>
        /// <param name="dieRoller">Die roller to use</param>
        /// <returns>Dice result</returns>
        public DiceResult Parse(string expression, DiceConfiguration config, IDieRoller dieRoller)
        {
            this.config = config;

            // first clean up expression
            expression = this.CorrectExpression(expression);

            // then break the expression down into tokens.
            List <string> tokens = this.Tokenize(expression);

            // finally parse and evaluate the expression tokens
            return(this.ParseLogic(expression, tokens, dieRoller));
        }
Beispiel #7
0
        public IEnumerable <TermResult> GetResults(IDieRoller dieRoller)
        {
            IEnumerable <TermResult> results =
                from i in Enumerable.Range(0, Multiplicity)
                select new TermResult
            {
                Scalar = Scalar,
                Value  = dieRoller.RollDie(Sides),
                Type   = "d" + Sides
            };

            return(results.OrderByDescending(d => d.Value).Take(Choose));
        }
Beispiel #8
0
        /// <inheritdoc/>
        public IReadOnlyList <TermResult> CalculateResults(IDieRoller dieRoller)
        {
            // ensure we have a die roller.
            if (dieRoller == null)
            {
                throw new ArgumentNullException(nameof(dieRoller));
            }

            List <TermResult> results  = new List <TermResult>();
            string            termType = string.Format(this.FormatResultType, this.GetType().Name, this.sides);
            int rerolls = 0;

            // go through the number of dice and roll each one, saving them as term results.
            for (int i = 0; i < this.numberDice + rerolls; i++)
            {
                int value = this.RollTerm(dieRoller, this.sides);
                if (this.exploding != null && value >= this.exploding)
                {
                    if (rerolls > MaxRerollsAllowed)
                    {
                        throw new OverflowException("Rolling dice past the maximum allowed number of rerolls.");
                    }

                    rerolls++;
                }

                results.Add(new TermResult
                {
                    Scalar = this.scalar,
                    Value  = value,
                    Type   = termType
                });
            }

            // order by their value (high to low) and only take the amount specified in choose.
            int tempChoose = this.choose ?? results.Count;
            var ordered    = (tempChoose > 0) ? results.OrderByDescending(d => d.Value).ToList() : results.OrderBy(d => d.Value).ToList();

            for (int i = Math.Abs(tempChoose); i < ordered.Count(); i++)
            {
                ordered[i].AppliesToResultCalculation = false;
            }

            return(results);
        }
        /// <inheritdoc/>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            // when focus comes back to this page, then reset any app settings that may have
            // changed,
            if (this.appSettings != null)
            {
                if (this.ViewToggleButton.IsChecked != this.appSettings.UseDiceExpressionEditor)
                {
                    // if the dice roll view has changed since last view, then reset the UI.
                    this.ViewToggleButton.IsChecked = this.appSettings.UseDiceExpressionEditor;
                    this.ViewToggleButton_Click(this, null);
                }

                if (this.appSettings.ClearResultsList == true)
                {
                    // if user wanted results list cleared, then clear the list and reset the setting.
                    this.DiceRollResults.Clear();
                    this.appSettings.ClearResultsList = false;
                }

                // set the dice configuration.
                this.diceService.Configuration.DefaultDieSides  = this.appSettings.DefaultDiceSides;
                this.diceService.Configuration.HasBoundedResult = !this.appSettings.UseUnboundedResults;

                // get the current die roller to use.
                this.dieRoller = this.dieRollerFactory.GetDieRoller(
                    this.appSettings.CurrentDieRollerType, this.diceFrequencyTracker);
            }

            // setup a time to save die frequency data every 5 minutes.
            DispatcherTimer timer = new DispatcherTimer();

            timer.Tick    += this.Timer_Tick;
            timer.Interval = new TimeSpan(0, 5, 0);
            timer.Start();
        }
        /// <summary>
        /// Parses the specified list of tokens with appropriate logic to convert
        /// it into a Dice instance to evaluate oprations on.
        /// </summary>
        /// <param name="expression">dice expression rolled</param>
        /// <param name="tokens">String expression to parse</param>
        /// <param name="dieRoller">Die roller to use</param>
        /// <returns>Dice result</returns>
        private DiceResult ParseLogic(string expression, List <string> tokens, IDieRoller dieRoller)
        {
            List <TermResult> results = new List <TermResult>();

            while (tokens.IndexOf(this.GroupStartOperator) != -1)
            {
                // getting data between grouping symbols: "(" and ")"
                int open  = tokens.LastIndexOf(this.GroupStartOperator);
                int close = tokens.IndexOf(this.GroupEndOperator, open);

                if (open >= close)
                {
                    throw new ArithmeticException("No matching close-open parenthesis.");
                }

                // get a subexpression list for elements within the grouping symbols
                List <string> subExpression = new List <string>();
                for (var i = open + 1; i < close; i++)
                {
                    subExpression.Add(tokens[i]);
                }

                // run the operations on the subexpression
                int subValue = this.HandleBasicOperation(results, subExpression, dieRoller);

                // when subexpression calculation is done, replace the grouping start symbol
                // and removing the tokens for the subexpression from the token list
                tokens[open] = subValue.ToString();
                tokens.RemoveRange(open + 1, close - open);
            }

            // at this point, we should have replaced all groups in the expression
            // with the appropriate values, so need to calculate last simple expression
            int value = this.HandleBasicOperation(results, tokens, dieRoller);

            // now return the dice result from the final value and TermResults list
            return(new DiceResult(expression, value, results, dieRoller.GetType().ToString(), this.config));
        }
Beispiel #11
0
 /// <summary>
 /// Performs the actual dice rolls for this term.
 /// </summary>
 /// <param name="dieRoller">IDieRoller to use</param>
 /// <param name="sides">Number of sides to roll</param>
 /// <returns>Returns rolled value.</returns>
 protected virtual int RollTerm(IDieRoller dieRoller, int sides)
 {
     return(dieRoller.Roll(sides));
 }
Beispiel #12
0
 public DieRollTrackerWithMathNetRollerTests()
 {
     this.roller = new MathNetDieRoller(new MersenneTwister(), this.tracker);
 }
Beispiel #13
0
        /// <inheritdoc/>
        public DiceResult Roll(IDieRoller dieRoller)
        {
            List <TermResult> termResults = this.terms.SelectMany(t => t.CalculateResults(dieRoller)).ToList();

            return(new DiceResult(this.ToString(), termResults, dieRoller.GetType().ToString(), this.Configuration));
        }
Beispiel #14
0
 /// <inheritdoc/>
 public DiceResult Roll(string expression, IDieRoller dieRoller)
 {
     return(this.parser.Parse(expression, this.Configuration, dieRoller));
 }
Beispiel #15
0
 public Rules(IDieRoller dieRoller)
 {
     this.dieRoller = dieRoller;
 }
Beispiel #16
0
 /// <inheritdoc/>
 protected override int RollTerm(IDieRoller dieRoller, int sides)
 {
     return(dieRoller.Roll(sides, FudgeFactor));
 }
        /// <summary>
        /// Evaluate the term and save the value and results, and updates the token list to
        /// reflect the completion of the operation.
        /// </summary>
        /// <param name="results">List of term results</param>
        /// <param name="tokens">String expression to parse</param>
        /// <param name="dieRoller">Die roller to use</param>
        /// <param name="opPosition">Current operator position in tokens list</param>
        /// <param name="length">length of tokens that were affected</param>
        /// <param name="term">Dice term to evaluate</param>
        private void EvaluateDiceTerm(List <TermResult> results, List <string> tokens, IDieRoller dieRoller, int opPosition, int length, IExpressionTerm term)
        {
            IReadOnlyList <TermResult> t = term.CalculateResults(dieRoller);
            int value = t.Sum(r => (int)Math.Round(r.AppliesToResultCalculation ? r.Value * r.Scalar : 0));

            results.AddRange(t);

            // put the evaluation result in the first entry and remove
            // the remaining processed tokens
            tokens[opPosition - 1] = value.ToString();
            tokens.RemoveRange(opPosition, length);
        }
Beispiel #18
0
 public DiceResult(IEnumerable <TermResult> results, IDieRoller rollerUsed)
 {
     RollerUsed = rollerUsed;
     Results    = new ReadOnlyCollection <TermResult>(results.ToList());
     Value      = results.Sum(r => r.Value * r.Scalar);
 }
        /// <summary>
        /// Handles the dice operator and its sub-expressions, and returns the result of the
        /// dice rolls in the results list and token value.
        /// </summary>
        /// <param name="results">List of term results</param>
        /// <param name="tokens">String expression to parse</param>
        /// <param name="op">current operator</param>
        /// <param name="dieRoller">Die roller to use</param>
        private void HandleDieOperator(List <TermResult> results, List <string> tokens, string op, IDieRoller dieRoller)
        {
            if (tokens.IndexOf("f") >= 0)
            {
                throw new FormatException("Fudge dice and regular dice cannot be used in the same expression");
            }

            // find the previous and next numbers in the token list
            int opPosition = tokens.IndexOf(op);
            int sides = 0, length = 0;

            int numDice = int.Parse(tokens[opPosition - 1]);

            // allow default value for dice (if not digit is specified)
            if (opPosition + 1 < tokens.Count && char.IsDigit(tokens[opPosition + 1], 0))
            {
                sides   = int.Parse(tokens[opPosition + 1]);
                length += 2;
            }
            else
            {
                sides = this.config.DefaultDieSides;
                length++;
            }

            // look-ahead to find other dice operators (like the choose-keep/drop operators)
            int?choose  = this.ChooseLookAhead(tokens, opPosition, numDice, ref length);
            int?explode = this.ExplodeLookAhead(tokens, opPosition, sides, ref length);

            // create a dice term based on the values
            DiceTerm term = new DiceTerm(numDice, sides, 1, choose, explode);

            // then evaluate the dice term to roll dice and get the result
            this.EvaluateDiceTerm(results, tokens, dieRoller, opPosition, length, term);
        }
        /// <summary>
        /// Handles the fudge dice operator and its sub-expressions, and returns the result of the
        /// dice rolls in the results list and token value.
        /// </summary>
        /// <param name="results">List of term results</param>
        /// <param name="tokens">String expression to parse</param>
        /// <param name="op">current operator</param>
        /// <param name="dieRoller">Die roller to use</param>
        private void HandleFudgeOperator(List <TermResult> results, List <string> tokens, string op, IDieRoller dieRoller)
        {
            // find the previous and next numbers in the token list
            int opPosition = tokens.IndexOf(op);

            int numDice = int.Parse(tokens[opPosition - 1]);
            int length  = 1;

            // look-ahead to find other dice operators (like the choose-keep/drop operators)
            int?choose = this.ChooseLookAhead(tokens, opPosition, numDice, ref length);

            // create a dice term based on the values
            IExpressionTerm term = new FudgeDiceTerm(numDice, choose);

            // then evaluate the dice term to roll dice and get the result
            this.EvaluateDiceTerm(results, tokens, dieRoller, opPosition, length, term);
        }
        /// <summary>
        /// Processes through all of the operator and evaluates the tokens for a single strand
        /// of values.
        /// </summary>
        /// <param name="results">List of term results</param>
        /// <param name="tokens">String expression to parse</param>
        /// <param name="dieRoller">Die roller to use</param>
        /// <returns>value of operation total.</returns>
        private int HandleBasicOperation(List <TermResult> results, List <string> tokens, IDieRoller dieRoller)
        {
            if (tokens.Count == 0)
            {
                // if there's nothing in the list, just return 0
                return(0);
            }
            else if (tokens.Count == 1)
            {
                // if there is only one token, then it much be a constant
                return(int.Parse(tokens[0]));
            }

            // loop through each operator in our operator list
            // operators order in the list signify their order of operations
            foreach (var op in this.Operators)
            {
                // loop through all of the tokens until we find the operator in the list
                while (tokens.IndexOf(op) != -1)
                {
                    try
                    {
                        if (op == "d")
                        {
                            // if current operator is the die operator, then process
                            // that part of the expression accordingly
                            this.HandleDieOperator(results, tokens, op, dieRoller);
                        }
                        else if (op == "f")
                        {
                            // if current operator is the fudge die operator, then process
                            // that part of the expression accordingly
                            this.HandleFudgeOperator(results, tokens, op, dieRoller);
                        }
                        else
                        {
                            // otherwise, treat the operator as an arimethic operator,
                            // and perform the correct math operation
                            this.HandleArithmeticOperators(results, tokens, op);
                        }
                    }
                    catch (Exception ex)
                    {
                        // if any error happens within this processing, then throw an exception
                        throw new FormatException("Dice expression string is incorrect format.", ex);
                    }
                }

                // if we are out of tokens, then just stop processing
                if (tokens.Count == 0)
                {
                    break;
                }
            }

            if (tokens.Count == 1)
            {
                // if there is only one token left, then return it as the evaluation of this list of tokens
                return(int.Parse(tokens[0]));
            }
            else
            {
                // if there are left over toknes, then the parsing/evaluation failed
                throw new FormatException("Dice expression string is incorrect format: unexpected symbols in the string expression.");
            }
        }
 public DieRollTrackerWithSecureRollerTests()
 {
     this.roller = new SecureRandomDieRoller(this.tracker);
 }
 public BattleCalculator(IDieRoller dieRoller)
 {
     _dieRoller = dieRoller;
 }
        public List <Player> CreateNPlayers(int n, IDieScoreCalculator dieScoreCalculator, IDieRoller dieRoller,
                                            IUserInterface userInterface)
        {
            var playerList = new List <Player>();

            for (var i = 0; i < n; i++)
            {
                var playerName = string.Format("Player {0}", i + 1);
                playerList.Add(CreateNewPlayer(dieScoreCalculator, dieRoller, userInterface, playerName));
            }

            return(playerList);
        }
Beispiel #25
0
 public DieRollTrackerWithRandomRollerTests()
 {
     this.roller = new RandomDieRoller(this.tracker);
 }
 public IEnumerable <TermResult> GetResults(IDieRoller dieRoller)
 {
     return(new[] { new TermResult {
                        Scalar = 1, Value = _constant, Type = "constant"
                    } });
 }
Beispiel #27
0
        public DiceResult Roll(IDieRoller roller)
        {
            IEnumerable <TermResult> termResults = _terms.SelectMany(t => t.GetResults(roller)).ToList();

            return(new DiceResult(termResults, roller));
        }