Beispiel #1
0
        public void SellPhase()
        {
            // Get all goods up for sale.
            _productSupply = Populous.SellPhase();

            // Reset Shortfall to zero.
            Shortfall = new ProductAmountCollection();

            // Fill Surplus preemtively, we'll remove bought products later.
            _surplus = ProductSupply.Copy();

            // While we're at it, also get total demand of all products
            _productDemand = Populous.TotalDemand();

            // And the hypothetical total production available.
            _productionCapacity = Populous.TotalProduction();
        }
Beispiel #2
0
 public void LossPhase()
 {
     // Carry out losses.
     var losses = Populous.LossPhase();
 }
Beispiel #3
0
 public void ConsumptionPhase()
 {
     // Kick down to populations.
     Populous.Consume();
 }
Beispiel #4
0
 /// <summary>
 /// Run through all productions that can be done and add them to the market.
 /// </summary>
 public void ProductionPhase()
 {
     // Run through production
     Populous.ProductionPhase();
 }
Beispiel #5
0
        /// <summary>
        /// Buys good from the market.
        /// </summary>
        /// <param name="buyer">The one buying the good.</param>
        /// <param name="good">The good they are trying to buy.</param>
        /// <param name="amount">How much they are trying to buy.</param>
        /// <returns>The Receipt of purchases</returns>
        public IProductAmountCollection BuyGoodsFromMarket(IPopulationGroup buyer,
                                                           IProduct good, double amount)
        {
            if (buyer is null)
            {
                throw new ArgumentNullException(nameof(buyer));
            }
            if (good is null)
            {
                throw new ArgumentNullException(nameof(good));
            }
            if (amount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(amount));
            }

            // The result of the purchases.
            IProductAmountCollection result = new ProductAmountCollection();

            // First buy from local merchants, they only accept cash.
            result = Populous.Merchants
                     .BuyGood(buyer.GetCash(AcceptedCurrencies), good, amount, this);

            // see how much was bought.
            double remainder = 0;

            // if any was bought, update what we are seeking.
            if (result.Contains(good))
            {
                remainder = amount - result.GetProductValue(good);
                // and complete the transaction
                buyer.CompleteTransaction(result);
            }

            // if no remainder, return
            if (remainder <= 0)
            {
                return(result);
            }

            // Then buy from everyone else via both cash and barter.
            foreach (var seller in Populous.GetPopsSellingProduct(good))
            {
                // If someone is selling the good, buy or barter with them.
                var reciept = BuyGoods(buyer, good, remainder, seller);

                // if something was bought
                if (reciept.Count() > 0)
                {
                    // remove it from the remainder
                    remainder -= reciept.GetProductValue(good);

                    // add it to our result
                    result.AddProducts(reciept);
                }

                // if nothing remains, we're done.
                if (remainder <= 0)
                {
                    return(result);
                }
            }

            // Finish buy going to the travelling merchants, if all else fails.
            foreach (var travSeller in TravellingMerchantsSelling(good))
            {
                var reciept = travSeller.BuyGood(buyer.GetCash(AcceptedCurrencies), good, remainder, this);

                // if something was bought
                if (reciept.Count() > 0)
                {
                    // remove it from remainder
                    remainder -= reciept.GetProductValue(good);

                    // Complete the transaction for the buyer
                    buyer.CompleteTransaction(reciept);

                    // add it to the result
                    result.AddProducts(reciept);
                }

                // if nothing remains, return
                if (remainder <= 0)
                {
                    return(result);
                }
            }

            // return the ultimate receipt.
            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// Grows the population, prioritizing those which are happiest/most successful over others.
        /// </summary>
        public void PopGrowth()
        {
            // The average growth we achieve each day.
            var popGrowth = 0.01; // to be divided later represents one year growth average.

            // Get the success of the total populous.
            var lifeSat  = Populous.LifeNeedsSatisfaction();
            var dailySat = Populous.DailyNeedsSatisfaction();

            // modify growth by satisfaction.
            if (lifeSat >= 0.99)
            { // Effectively totally satisfied.
                // The higher the Daily need Satisfaction, the greater the pop growth.
                popGrowth += 0.01 * dailySat;
            }
            else
            {                                      // Life sat not satisfied, remove 3 times the missing life need satisfaction.
                popGrowth -= 0.03 * (1 - lifeSat); // This bottoms out at -0.02.
            }

            // Randomize growth today.
            var variance = rand.NextDouble(-0.01, 0.01); // -0.01 to 0.01

            popGrowth += variance;

            // Get the new pops to add (divide by our year length)
            var newPops = TotalPopulation * popGrowth / 360;

            // add fractional pops to the carryover growth
            carryoverGrowth += newPops % 1;

            // remove fraction from newPops
            newPops -= newPops % 1;

            // if carry over growth greater than 1 (positive or negative)
            if (Math.Abs(carryoverGrowth) > 1)
            {
                // add (or remove) the whole number value of carry over.
                newPops += carryoverGrowth - (carryoverGrowth % 1);

                // update carryoverGrowth
                carryoverGrowth = carryoverGrowth % 1;
            }

            // Get pops ordered by success (descending order)
            var popsBySuccess = Populous.Pops.OrderByDescending(x => x.Success());

            // get total weight of the populous (all positive values, no negatives)
            double totalWeight = 0;

            foreach (var pop in popsBySuccess)
            {
                // get the success
                totalWeight += pop.Success();
            }

            // Now, we figure out where to put the pops.
            foreach (var pop in popsBySuccess)
            {
                // get pop's success again
                var success = pop.Success();

                // if pop is not successful, regardless of reason, GTFO, failing pops don't grow
                // and if the pop is not successful, no following pops will be either.
                if (success <= 0.5)
                {
                    break;
                }

                // get pop growth, divided by weight, and multiplied by success
                var born = newPops / totalWeight * success;

                // modify up or down by 50%
                born *= (0.5 + rand.NextDouble());

                // remove hanging decimals
                born -= born % 1;

                // add new pops to group
                pop.AddPop(born);

                // remove born from new pops
                newPops -= born;

                // remove the success from the total weight
                totalWeight -= success;
            }

            // any remainder pop, just add to the most successful pop.
            popsBySuccess.First().AddPop(newPops - (newPops % 1)); // any extra just drop.
        }