/// <summary> /// Run through all purchasing that takes place. /// </summary> public void BuyPhase() { // go through each pop in order of priority foreach (var buyer in Populous.PopsByPriority) { // go through their list of needs foreach (var needPair in buyer.TotalNeeds) { // Check that there is stuff that the pop // can trade for goods if (buyer.ForSale.All(x => x.Item2 <= 0)) { break; // if they don't they stop } // get the product and amount var need = needPair.Item1; var desired = needPair.Item2; // the units desired try { // Check if the product is available to buy if (ProductSupply.GetProductValue(need) <= 0) { // if nothing is available, add it to the shortfall. Shortfall.AddProducts(need, desired); continue; // and go to the next need } } catch (KeyNotFoundException) // If it doesn't exist in the supply at all. { // Add it in at 0 ProductSupply.IncludeProduct(need); // Subtract the missing product from shortfall. Shortfall.AddProducts(need, desired); continue; // and skip it here. } // Go to the market and buy what we can. var reciept = BuyGoodsFromMarket(buyer, need, desired); // process our reciept, getting how satisfied our need was. var satisfaction = reciept.GetProductValue(need); // Add satisfaction to our purchased good recorder _purchasedGoods.AddProducts(need, satisfaction); // Remove bought good from supply ProductSupply.SubtractProducts(need, satisfaction); // get the number of goods that couldn't be bought. var shortfall = desired - satisfaction; // add that to shortfall Shortfall.AddProducts(need, shortfall); } } // with all buying done, get surplus supply available by removing bought goods. _surplus.AddProducts(PurchasedGoods.Multiply(-1)); }
/// <summary> /// Readjust and Recalulate Prices. /// </summary> public void RecalculatePrices() { // TODO Allow for this to be modified by variations // TODO Create a way to allow for faster Price changes, when supply/demand differences are large. // for each product in the market. foreach (var pair in ProductPrices) { // Get the product var product = pair.Item1; double surplus; double shortfall; try { // get surplus product not spent surplus = Surplus.GetProductValue(product); // get product that was desired to buy. shortfall = Shortfall.GetProductValue(product); } catch (KeyNotFoundException) { // if the item does not exist in surplus or shortfal, then it probably was not // sold or desired in the market. Give it a boost to denote it's rarity, and try and encourage it. ProductPrices.AddProducts(product, 0.01); continue; } // the amount of change to make to the good's price. double priceChange = 0; // If any surplus and shortfall exists, price was too high if (surplus > 0 && shortfall > 0) { priceChange += -0.01; } else if (surplus > 0) { // If no shortfall but still surplus, try lowering price to sell it, oversupply is not good. priceChange += -0.01; } else if (shortfall > 0) { // if shortfall but no surplus, price is too low. priceChange += 0.01; } // In no surplus nor shortfall, then we have hit equilibrium. // No change in price. // add the change in price to the new price // TODO make this more flexible and reactive. // going in 0.01 ABS price unit sized steps is too small // and may make prices too stagnant var newPrice = ProductPrices.GetProductValue(product) + priceChange; // update to said price. ProductPrices.SetProductAmount(product, newPrice); } }