예제 #1
0
        public void ProcessExpedition(ExpeditionData data, uint currentRoundNumber)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (currentRoundNumber < data.StartingRound || currentRoundNumber > data.EndingRound)
            {
                return; // already processed
            }

            decimal militaryPower = this.CalculateCurrentExpeditionPower(data, PowerType.Military); // increase defense and range
            decimal sciencePower  = this.CalculateCurrentExpeditionPower(data, PowerType.Science);  // increases rare findings per turn
            decimal laborPower    = this.CalculateCurrentExpeditionPower(data, PowerType.Labour);   // increase range & findings per turn

            decimal rangeDelta = this.CalculateRangeIncrease(militaryPower, laborPower);

            data.CurrentRange += rangeDelta;

            // calculate new findings - depending on passing turn and total range
            var explorableResources = ResourceInfo.KnownResources.Where(r =>
                                                                        r.FindingProbability > 0.0m && r.BaseFindSize > 0.0m);

            foreach (var explorableResource in explorableResources)
            {
                var finding = this.CalculateFindingSize(explorableResource, militaryPower, sciencePower,
                                                        laborPower, data.CurrentRange);
                data.DiscoveredResources.Add(finding);
            }

            // calculate endangerment (if any) depending on passing turn (& range)
            decimal dangerLevel = this.CalculateDangerLevel(data.CurrentRange, data.StartingRound, currentRoundNumber);

            // fight
            var enemyForces = this.GenerateOpposingForce(dangerLevel);

            if (enemyForces.AnyOne())
            {
                FightOutcome outcome = this._fightLogic.CalculateFight(enemyForces, data.RemainingUnits);
                if (outcome.JunkProduced.Value > 0)
                {
                    data.DiscoveredResources.Add(outcome.JunkProduced);
                }

                // reduce units
                if (outcome.RazedDefenders.AnyOne())
                {
                    data.RemainingUnits.Substract(outcome.RazedDefenders);
                }
            }

            // left at least one worker and stop expedition at that point
            if (!data.RemainingUnits.AnyOne())
            {
                this._unitLogic.AddWorkers(data.RemainingUnits, 1);
                data.EndingRound = currentRoundNumber;
            }
        }
예제 #2
0
        private decimal CalculateCurrentExpeditionPower(ExpeditionData data, PowerType powerType)
        {
            switch (powerType)
            {
            case PowerType.Military:
                return(this._unitLogic.GetMilitaryPower(data.RemainingUnits, MilitarySide.Both));

            case PowerType.Science:
                return(this._unitLogic.GetSciencePower(data.RemainingUnits));

            case PowerType.Labour:
                return(this._unitLogic.GetLabourPower(data.RemainingUnits));

            case PowerType.Electric:
                throw new NotSupportedException("Power.Electric does not apply to Expedition calculations.");

            default:
                throw new ArgumentOutOfRangeException(nameof(powerType), powerType, null);
            }
        }