public void Execute() { TradeAsks.Clear(); TradeBids.Clear(); DeltaMoney.Clear(); ProfitsByLogic.Clear(); }
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)); } } }
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; } }