Beispiel #1
0
        public AttackResult SimulateAttack(ArmyComposition attackingForce, ArmyComposition defendingForce, uint trials)
        {
            var outcomes = new ConcurrentDictionary <short, uint>();

            // Random isn't thread safe so don't parallelize
            //   Parallel.For(0, trials, (i) =>
            for (int i = 0; i < trials; i++)
            {
                outcomes.AddOrUpdate(RunTrial(attackingForce, defendingForce), 1, (s, u) => u + 1);
            }
            //);

            var ret = new AttackResult()
            {
                Trials        = trials,
                AttackingArmy = attackingForce,
                DefendingArmy = defendingForce,
            };

            var wins = 0u;

            foreach (var outcome in outcomes)
            {
                ret.AllOutcomeChances.Add(outcome.Key, ((double)outcome.Value) / trials);
                if (outcome.Key > 0)
                {
                    wins += outcome.Value;
                }
            }

            ret.SuccessChance = ((double)wins) / trials;

            return(ret);
        }
Beispiel #2
0
        private short RunTrial(ArmyComposition attackingForce, ArmyComposition defendingForce)
        {
            var atkRemaining = attackingForce.Size;
            var defRemaining = defendingForce.Size;

            while (atkRemaining > 0 && defRemaining > 0)
            {
                var atkRolls = new List <byte>(3);
                var defRolls = new List <byte>(2);

                for (int i = 0; i < Math.Min((short)3, atkRemaining); i++)
                {
                    atkRolls.Add((byte)numGen.Next(6));
                }

                for (int i = 0; i < Math.Min((short)2, defRemaining); i++)
                {
                    defRolls.Add((byte)numGen.Next(6));
                }

                var numToCompare = Math.Min(atkRolls.Count, defRolls.Count);

                var modAtkRolls = atkRolls.OrderByDescending(b => b).Take(numToCompare).Select(b => (sbyte)b).ToArray();
                var modDefRolls = defRolls.OrderByDescending(b => b).Take(numToCompare).Select(b => (sbyte)b).ToArray();

                modAtkRolls[0] += attackingForce.HighestModifier;
                modDefRolls[0] += defendingForce.HighestModifier;

                modAtkRolls[numToCompare - 1] += attackingForce.LowestModifier;
                modDefRolls[numToCompare - 1] += defendingForce.LowestModifier;

                for (int i = 0; i < numToCompare; i++)
                {
                    if (modAtkRolls[i] + attackingForce.AllModifier > modDefRolls[i] + defendingForce.AllModifier)
                    {
                        defRemaining--;
                    }
                    else
                    {
                        atkRemaining--;
                    }
                }
            }

            return((short)(atkRemaining - defRemaining));
        }