aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation')
-rw-r--r--src/openvic-simulation/economy/GoodInstance.cpp16
-rw-r--r--src/openvic-simulation/economy/GoodInstance.hpp11
-rw-r--r--src/openvic-simulation/economy/production/ArtisanalProducer.cpp66
-rw-r--r--src/openvic-simulation/economy/production/ArtisanalProducer.hpp21
-rw-r--r--src/openvic-simulation/economy/trading/BuyResult.cpp11
-rw-r--r--src/openvic-simulation/economy/trading/BuyResult.hpp16
-rw-r--r--src/openvic-simulation/economy/trading/BuyUpToOrder.cpp14
-rw-r--r--src/openvic-simulation/economy/trading/BuyUpToOrder.hpp24
-rw-r--r--src/openvic-simulation/economy/trading/MarketInstance.cpp25
-rw-r--r--src/openvic-simulation/economy/trading/MarketInstance.hpp2
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();
};