コード例 #1
0
 public void Execute()
 {
     TradeAsks.Clear();
     TradeBids.Clear();
     DeltaMoney.Clear();
     ProfitsByLogic.Clear();
 }
コード例 #2
0
        public void Execute([ReadOnly] Entity entity, [ReadOnly] int index,
                            DynamicBuffer <InvContent> inventoryContents, [ReadOnly] ref Agent agent)
        {
            // Determining if surplus or shortage
            var targetInventory = inventoryContents.AsNativeArray();
            var targetIdeals    = IdealQuantities[agent.Logic].AsNativeArray();

            for (var good = 0; good < targetInventory.Length; good++)
            {
                var targetInvContent = targetInventory[good];
                if (targetInvContent.Quantity > targetIdeals[good])
                {
                    // Surplus. 2% markup
                    var reasonablePrice = math.clamp(targetInvContent.RecordedPrice * 1.02f, 0.005f, 5f);
                    //agent.NumProduct = targetGood.Quantity; // No clue what this does
                    // Intentional placing entire inventory out to market.
                    TradeAsks.Add(good, new Offer(entity, targetInvContent.Quantity, reasonablePrice));
                }
                else
                {
                    var       shortage = targetIdeals[good] - targetInvContent.Quantity;
                    const int bidPrice = 0; // Why not get it for free?

                    // Used to be based on preference but handling minimums and maximums were too memory expensive
                    // Possible randomness through gaussian curve?
                    var purchaseQuantity = Rng.NextFloat(0.5f, 1.5f) * shortage;

                    TradeBids.Add(good, new Offer(entity, purchaseQuantity, bidPrice));
                }
            }
        }
コード例 #3
0
        public void Execute(int index)
        {
            var currentAsks = new NativeList <Offer>(Allocator.Temp);
            var currentBids = new NativeList <Offer>(Allocator.Temp);

            var numAsks = 0f;
            var numBids = 0f;

            if (TradeAsks.TryGetFirstValue(index, out var currentOffer, out var iterator))
            {
                do
                {
                    currentAsks.Add(currentOffer);
                    numAsks += currentOffer.Units;
                } while (TradeAsks.TryGetNextValue(out currentOffer, ref iterator));

                // Descending order (3, 2, 1).
                currentAsks.AsArray().Sort();
            }

            if (TradeBids.TryGetFirstValue(index, out currentOffer, out iterator))
            {
                do
                {
                    currentBids.Add(currentOffer);
                    numBids += currentOffer.Units;
                } while (TradeBids.TryGetNextValue(out currentOffer, ref iterator));

                // Randomizing bids
                var n = currentBids.Length;
                while (n-- > 1)
                {
                    var k           = Rng.NextInt(n + 1);
                    var placeholder = currentBids[k];
                    currentBids[k] = currentBids[n];
                    currentBids[n] = placeholder;
                }
            }

            AskHistory[index] = math.lerp(AskHistory[index], numAsks, 0.75f);
            BidHistory[index] = math.lerp(BidHistory[index], numBids, 0.75f);
            var numTraded   = 0f;
            var moneyTraded = 0f;

            while (currentBids.Length > 0 && currentAsks.Length > 0)
            {
                // Descending order
                var buyer  = currentBids[currentBids.Length - 1];
                var seller = currentAsks[currentAsks.Length - 1];

                var quantityTraded = math.min(buyer.Units, seller.Units);
                var clearingPrice  = seller.Cost;

                if (quantityTraded > 0)
                {
                    // Transferring goods
                    seller.Units -= quantityTraded;
                    buyer.Units  -= quantityTraded;

                    // Recording history
                    numTraded   += quantityTraded;
                    moneyTraded += clearingPrice * quantityTraded;

                    currentAsks[currentAsks.Length - 1] = seller;
                    currentBids[currentBids.Length - 1] = buyer;

                    var targetInv   = InventoryContents[seller.Source].AsNativeArray();
                    var placeholder = targetInv[index];
                    placeholder.Quantity -= quantityTraded;
                    // TODO: Find out why this is causing skyrocketing prices.
                    placeholder.RecordedPrice = math.lerp(placeholder.RecordedPrice, clearingPrice,
                                                          quantityTraded / (quantityTraded + placeholder.Quantity));
                    targetInv[index] = placeholder;

                    targetInv   = InventoryContents[buyer.Source].AsNativeArray();
                    placeholder = targetInv[index];
                    placeholder.RecordedPrice = clearingPrice;
                    placeholder.Quantity     += quantityTraded;
                    targetInv[index]          = placeholder;

                    DeltaMoney.Add(seller.Source, clearingPrice * quantityTraded);
                    DeltaMoney.Add(buyer.Source, -clearingPrice * quantityTraded);
                }

                if (seller.Units <= 0)
                {
                    currentAsks.RemoveAtSwapBack(currentAsks.Length - 1);
                }

                if (buyer.Units <= 0)
                {
                    currentBids.RemoveAtSwapBack(currentBids.Length - 1);
                }
            }

            for (var unsold = 0; unsold < currentAsks.Length; unsold++)
            {
                var seller      = currentAsks[unsold];
                var targetInv   = InventoryContents[seller.Source].AsNativeArray();
                var placeholder = targetInv[index];
                placeholder.RecordedPrice = math.clamp(
                    placeholder.RecordedPrice * (1 - 0.01f * math.sqrt(seller.Units)),
                    0.005f, 10f);
                targetInv[index] = placeholder;
            }

            TradeHistory[index] = numTraded;
            if (numTraded > 0)
            {
                PriceHistory[index] = moneyTraded / numTraded;
            }
        }