diff options
Diffstat (limited to 'src/openvic-simulation/economy')
10 files changed, 194 insertions, 12 deletions
diff --git a/src/openvic-simulation/economy/GoodInstance.cpp b/src/openvic-simulation/economy/GoodInstance.cpp index 3e3d88e..e48624c 100644 --- a/src/openvic-simulation/economy/GoodInstance.cpp +++ b/src/openvic-simulation/economy/GoodInstance.cpp @@ -13,6 +13,17 @@ GoodInstance::GoodInstance(GoodDefinition const& new_good_definition) market_sell_order_callbacks {} {} +void GoodInstance::add_buy_up_to_order( + const fixed_point_t max_quantity, + const fixed_point_t money_to_spend, + const std::function<void(const BuyResult)> callback +) { + demand_running_total += max_quantity; + buy_up_to_order_max_quantities.push_back(max_quantity); + buy_up_to_order_money_to_spend.push_back(money_to_spend); + buy_up_to_order_callbacks.push_back(callback); +} + void GoodInstance::add_market_sell_order(const fixed_point_t quantity, const std::function<void(SellResult)> callback) { supply_running_total += quantity; market_sell_order_quantities.push_back(quantity); @@ -20,8 +31,13 @@ void GoodInstance::add_market_sell_order(const fixed_point_t quantity, const std } void GoodInstance::clear_orders() { + total_demand_yesterday = demand_running_total; + demand_running_total = fixed_point_t::_0(); total_supply_yesterday = supply_running_total; supply_running_total = fixed_point_t::_0(); + + buy_up_to_order_max_quantities.clear(); + buy_up_to_order_callbacks.clear(); market_sell_order_quantities.clear(); market_sell_order_callbacks.clear(); } diff --git a/src/openvic-simulation/economy/GoodInstance.hpp b/src/openvic-simulation/economy/GoodInstance.hpp index e9f2298..a733557 100644 --- a/src/openvic-simulation/economy/GoodInstance.hpp +++ b/src/openvic-simulation/economy/GoodInstance.hpp @@ -3,6 +3,7 @@ #include <vector> #include "openvic-simulation/economy/GoodDefinition.hpp" +#include "openvic-simulation/economy/trading/BuyResult.hpp" #include "openvic-simulation/economy/trading/SellResult.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" #include "openvic-simulation/types/HasIdentifier.hpp" @@ -19,8 +20,13 @@ namespace OpenVic { GoodDefinition const& PROPERTY(good_definition); fixed_point_t PROPERTY(price); bool PROPERTY(is_available); + fixed_point_t demand_running_total; fixed_point_t supply_running_total; + fixed_point_t PROPERTY(total_demand_yesterday); fixed_point_t PROPERTY(total_supply_yesterday); + std::vector<fixed_point_t> PROPERTY(buy_up_to_order_max_quantities); + std::vector<fixed_point_t> PROPERTY(buy_up_to_order_money_to_spend); + std::vector<std::function<void(BuyResult)>> PROPERTY(buy_up_to_order_callbacks); std::vector<fixed_point_t> PROPERTY(market_sell_order_quantities); std::vector<std::function<void(SellResult)>> PROPERTY(market_sell_order_callbacks); @@ -29,6 +35,11 @@ namespace OpenVic { public: GoodInstance(GoodInstance&&) = default; + void add_buy_up_to_order( + const fixed_point_t max_quantity, + const fixed_point_t money_to_spend, + const std::function<void(const BuyResult)> callback + ); void add_market_sell_order(const fixed_point_t quantity, const std::function<void(SellResult)> callback); void clear_orders(); }; diff --git a/src/openvic-simulation/economy/production/ArtisanalProducer.cpp b/src/openvic-simulation/economy/production/ArtisanalProducer.cpp index d5cc3d3..2613d12 100644 --- a/src/openvic-simulation/economy/production/ArtisanalProducer.cpp +++ b/src/openvic-simulation/economy/production/ArtisanalProducer.cpp @@ -1,13 +1,65 @@ #include "ArtisanalProducer.hpp" +#include "openvic-simulation/economy/GoodDefinition.hpp" +#include "openvic-simulation/economy/trading/BuyResult.hpp" +#include "openvic-simulation/economy/trading/SellResult.hpp" + using namespace OpenVic; ArtisanalProducer::ArtisanalProducer( + MarketInstance& new_market_instance, + ModifierEffectCache const& new_modifier_effect_cache, + Pop& new_pop, + Pop::pop_size_t new_previous_pop_size, + fixed_point_t new_inputs_bought_scalar, ProductionType const& new_production_type, - GoodDefinition::good_definition_map_t&& new_stockpile, - fixed_point_t new_current_production, - GoodDefinition::good_definition_map_t&& new_current_needs -) : production_type { new_production_type }, - stockpile { std::move(new_stockpile) }, - current_production { new_current_production }, - current_needs { std::move(new_current_needs) } {} + fixed_point_t new_current_production +) : market_instance { new_market_instance }, + modifier_effect_cache { new_modifier_effect_cache }, + pop { new_pop }, + previous_pop_size { new_previous_pop_size }, + inputs_bought_scalar { new_inputs_bought_scalar }, + production_type { new_production_type }, + current_production { new_current_production } + {} + +void ArtisanalProducer::artisan_tick() { + current_production = production_type.get_base_output_quantity() + * inputs_bought_scalar + * previous_pop_size / production_type.get_base_workforce_size(); + + GoodDefinition const& output_good = production_type.get_output_good(); + if (current_production > 0) { + market_instance.place_market_sell_order({ + output_good, + current_production, + [this](const SellResult sell_result) -> void { + //TODO add artisanal income to pop (part of https://github.com/OpenVicProject/OpenVic-Simulation/issues/225 ) + } + }); + } + + const fixed_point_t total_cash_to_spend = pop.get_cash(); + if (production_type.get_input_goods().empty()) { + inputs_bought_scalar = fixed_point_t::_1(); + } + else if (total_cash_to_spend > 0) { + int input_goods_count = static_cast<int>(production_type.get_input_goods().size()); + for (auto const& [input_good_ptr, base_desired_quantity] : production_type.get_input_goods()) { + const fixed_point_t money_to_spend = total_cash_to_spend / input_goods_count; + const fixed_point_t desired_quantity = base_desired_quantity * pop.get_size() / production_type.get_base_workforce_size(); + //TODO pop cash -= money_to_spend + market_instance.place_buy_up_to_order({ + *input_good_ptr, + desired_quantity, + money_to_spend, + [this, desired_quantity](const BuyResult buy_result) -> void { + //TODO pop cash += buy_result.get_money_left() + inputs_bought_scalar = std::min(inputs_bought_scalar, buy_result.get_quantity_bought() / desired_quantity); + } + }); + } + } + + previous_pop_size = pop.get_size(); +}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/production/ArtisanalProducer.hpp b/src/openvic-simulation/economy/production/ArtisanalProducer.hpp index 65aa3fa..3287b40 100644 --- a/src/openvic-simulation/economy/production/ArtisanalProducer.hpp +++ b/src/openvic-simulation/economy/production/ArtisanalProducer.hpp @@ -1,22 +1,33 @@ #pragma once -#include "openvic-simulation/economy/GoodDefinition.hpp" #include "openvic-simulation/economy/production/ProductionType.hpp" +#include "openvic-simulation/economy/trading/MarketInstance.hpp" +#include "openvic-simulation/modifier/ModifierEffectCache.hpp" +#include "openvic-simulation/pop/Pop.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" #include "openvic-simulation/utility/Getters.hpp" namespace OpenVic { struct ArtisanalProducer { private: + MarketInstance& market_instance; + ModifierEffectCache const& modifier_effect_cache; + Pop& pop; + Pop::pop_size_t previous_pop_size; + fixed_point_t inputs_bought_scalar; ProductionType const& PROPERTY(production_type); - GoodDefinition::good_definition_map_t PROPERTY(stockpile); fixed_point_t PROPERTY(current_production); - GoodDefinition::good_definition_map_t PROPERTY(current_needs); public: ArtisanalProducer( - ProductionType const& new_production_type, GoodDefinition::good_definition_map_t&& new_stockpile, - fixed_point_t new_current_production, GoodDefinition::good_definition_map_t&& new_current_needs + MarketInstance& new_market_instance, + ModifierEffectCache const& new_modifier_effect_cache, + Pop& new_pop, + Pop::pop_size_t new_previous_pop_size, + fixed_point_t new_inputs_bought_scalar, + ProductionType const& new_production_type, + fixed_point_t new_current_production ); + void artisan_tick(); }; } diff --git a/src/openvic-simulation/economy/trading/BuyResult.cpp b/src/openvic-simulation/economy/trading/BuyResult.cpp new file mode 100644 index 0000000..452f3b9 --- /dev/null +++ b/src/openvic-simulation/economy/trading/BuyResult.cpp @@ -0,0 +1,11 @@ +#include "BuyResult.hpp" + +using namespace OpenVic; + +BuyResult::BuyResult( + const fixed_point_t new_quantity_bought, + const fixed_point_t new_money_left +) : + quantity_bought { new_quantity_bought }, + money_left { new_money_left } + {}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/BuyResult.hpp b/src/openvic-simulation/economy/trading/BuyResult.hpp new file mode 100644 index 0000000..9eabff7 --- /dev/null +++ b/src/openvic-simulation/economy/trading/BuyResult.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" + +namespace OpenVic { + struct BuyResult { + private: + fixed_point_t PROPERTY(quantity_bought); + fixed_point_t PROPERTY(money_left); + public: + BuyResult( + const fixed_point_t new_quantity_bought, + const fixed_point_t new_money_left + ); + }; +}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/BuyUpToOrder.cpp b/src/openvic-simulation/economy/trading/BuyUpToOrder.cpp new file mode 100644 index 0000000..6994e18 --- /dev/null +++ b/src/openvic-simulation/economy/trading/BuyUpToOrder.cpp @@ -0,0 +1,14 @@ +#include "BuyUpToOrder.hpp" + +using namespace OpenVic; + +BuyUpToOrder::BuyUpToOrder( + GoodDefinition const& new_good, + const fixed_point_t new_max_quantity, + const fixed_point_t new_money_to_spend, + const std::function<void(const BuyResult)> new_after_trade +) : good { &new_good }, + max_quantity { new_max_quantity }, + money_to_spend { new_money_to_spend }, + after_trade { new_after_trade } + {}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/BuyUpToOrder.hpp b/src/openvic-simulation/economy/trading/BuyUpToOrder.hpp new file mode 100644 index 0000000..b19cf36 --- /dev/null +++ b/src/openvic-simulation/economy/trading/BuyUpToOrder.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "openvic-simulation/economy/GoodDefinition.hpp" +#include "openvic-simulation/economy/trading/BuyResult.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/utility/Getters.hpp" + +namespace OpenVic { + struct BuyUpToOrder { + private: + GoodDefinition const* const PROPERTY(good); + const fixed_point_t PROPERTY(max_quantity); + const fixed_point_t PROPERTY(money_to_spend); + const std::function<void(const BuyResult)> PROPERTY(after_trade); + + public: + BuyUpToOrder( + GoodDefinition const& new_good, + const fixed_point_t new_max_quantity, + const fixed_point_t new_money_to_spend, + const std::function<void(const BuyResult)> new_after_trade + ); + }; +}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/MarketInstance.cpp b/src/openvic-simulation/economy/trading/MarketInstance.cpp index 5539cdb..fc0c215 100644 --- a/src/openvic-simulation/economy/trading/MarketInstance.cpp +++ b/src/openvic-simulation/economy/trading/MarketInstance.cpp @@ -3,6 +3,8 @@ #include "openvic-simulation/economy/GoodDefinition.hpp" #include "openvic-simulation/economy/GoodInstance.hpp" #include "openvic-simulation/economy/trading/MarketSellOrder.hpp" +#include "economy/trading/BuyResult.hpp" +#include "types/fixed_point/FixedPoint.hpp" using namespace OpenVic; @@ -11,6 +13,16 @@ bool MarketInstance::setup(GoodInstanceManager& new_good_instance_manager) { return true; } +void MarketInstance::place_buy_up_to_order(const BuyUpToOrder buy_up_to_order) { + GoodDefinition const* const good = buy_up_to_order.get_good(); + GoodInstance* const good_instance = good_instance_manager->get_good_instance_by_identifier(good->get_identifier()); + good_instance->add_buy_up_to_order( + buy_up_to_order.get_max_quantity(), + buy_up_to_order.get_money_to_spend(), + buy_up_to_order.get_after_trade() + ); +} + void MarketInstance::place_market_sell_order(const MarketSellOrder market_sell_order) { GoodDefinition const* const good = market_sell_order.get_good(); GoodInstance* const good_instance = good_instance_manager->get_good_instance_by_identifier(good->get_identifier()); @@ -31,6 +43,19 @@ void MarketInstance::execute_orders() { market_sell_quantity * price }); } + + std::vector<fixed_point_t> const& buy_up_to_max_quantities = good_instance.get_buy_up_to_order_max_quantities(); + std::vector<fixed_point_t> const& buy_up_to_money_to_spend = good_instance.get_buy_up_to_order_money_to_spend(); + std::vector<std::function<void(const BuyResult)>> const& buy_up_to_max_callbacks = good_instance.get_buy_up_to_order_callbacks(); + + for(int i = 0; i < buy_up_to_max_quantities.size(); i++) { + const fixed_point_t money_to_spend = buy_up_to_money_to_spend[i]; + const fixed_point_t quantity_bought = std::min(buy_up_to_max_quantities[i], money_to_spend / price); + buy_up_to_max_callbacks[i]({ + quantity_bought, + money_to_spend - quantity_bought * price + }); + } good_instance.clear_orders(); } diff --git a/src/openvic-simulation/economy/trading/MarketInstance.hpp b/src/openvic-simulation/economy/trading/MarketInstance.hpp index 2d8a651..51b25b4 100644 --- a/src/openvic-simulation/economy/trading/MarketInstance.hpp +++ b/src/openvic-simulation/economy/trading/MarketInstance.hpp @@ -1,6 +1,7 @@ #pragma once #include "openvic-simulation/economy/GoodInstance.hpp" +#include "openvic-simulation/economy/trading/BuyUpToOrder.hpp" #include "openvic-simulation/economy/trading/MarketSellOrder.hpp" namespace OpenVic { @@ -9,6 +10,7 @@ namespace OpenVic { GoodInstanceManager* PROPERTY(good_instance_manager); public: bool setup(GoodInstanceManager& new_good_instance_manager); + void place_buy_up_to_order(const BuyUpToOrder buy_up_to_order); void place_market_sell_order(const MarketSellOrder market_sell_order); void execute_orders(); }; |