-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
279 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 108 additions & 7 deletions
115
src/openvic-simulation/economy/production/ArtisanalProducer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,114 @@ | ||
#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( | ||
ProductionType const& new_production_type, | ||
MarketInstance& new_market_instance, | ||
ModifierEffectCache const& new_modifier_effect_cache, | ||
Pop& new_pop, | ||
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) } {} | ||
ProductionType const& new_production_type, | ||
fixed_point_t new_current_production | ||
) : market_instance { new_market_instance }, | ||
modifier_effect_cache { new_modifier_effect_cache }, | ||
pop { new_pop }, | ||
stockpile { new_stockpile }, | ||
production_type { new_production_type }, | ||
current_production { new_current_production } | ||
{} | ||
|
||
void ArtisanalProducer::artisan_tick() { | ||
GoodDefinition::good_definition_map_t goods_to_buy_and_max_price { }; | ||
GoodDefinition::good_definition_map_t demand { }; | ||
fixed_point_t inputs_bought_scalar = fixed_point_t::_1(); | ||
if (production_type.get_input_goods().empty()) { | ||
inputs_bought_scalar = fixed_point_t::_1(); | ||
} else { | ||
GoodInstanceManager const& good_instance_manager = *market_instance.get_good_instance_manager(); | ||
for (auto const& [input_good_ptr, base_desired_quantity] : production_type.get_input_goods()) { | ||
const fixed_point_t desired_quantity = demand[input_good_ptr] = base_desired_quantity * pop.get_size() / production_type.get_base_workforce_size(); | ||
inputs_bought_scalar = std::min(stockpile[input_good_ptr] / desired_quantity, inputs_bought_scalar); | ||
GoodInstance const& good = *good_instance_manager.get_good_instance_by_identifier( | ||
input_good_ptr->get_identifier() | ||
); | ||
goods_to_buy_and_max_price[input_good_ptr] = good.get_max_next_price(); | ||
} | ||
|
||
if (inputs_bought_scalar > fixed_point_t::_0()) { | ||
for (auto const& [input_good_ptr, base_desired_quantity] : production_type.get_input_goods()) { | ||
const fixed_point_t desired_quantity = demand[input_good_ptr]; | ||
stockpile[input_good_ptr] = std::max( | ||
fixed_point_t::_0(), | ||
stockpile[input_good_ptr] - desired_quantity * inputs_bought_scalar | ||
); | ||
|
||
if (stockpile[input_good_ptr] >= desired_quantity) { | ||
goods_to_buy_and_max_price.erase(input_good_ptr); | ||
} | ||
} | ||
} | ||
|
||
const fixed_point_t total_cash_to_spend = pop.get_cash(); | ||
if (total_cash_to_spend > 0 && !goods_to_buy_and_max_price.empty()) { | ||
fixed_point_t max_possible_satisfaction = fixed_point_t::_1(); | ||
|
||
bool at_or_below_optimum = false; | ||
while (!at_or_below_optimum) { | ||
at_or_below_optimum = true; | ||
fixed_point_t total_demand_value = fixed_point_t::_0(); | ||
fixed_point_t total_stockpile_value = fixed_point_t::_0(); | ||
for (auto const& [input_good_ptr, max_price] : goods_to_buy_and_max_price) { | ||
total_demand_value += max_price * demand[input_good_ptr]; | ||
total_stockpile_value += max_price * stockpile[input_good_ptr]; | ||
} | ||
|
||
max_possible_satisfaction = std::min( | ||
fixed_point_t::_1(), | ||
(total_stockpile_value + total_cash_to_spend) / total_demand_value | ||
); | ||
|
||
for (auto const& [input_good_ptr, max_price] : goods_to_buy_and_max_price) { | ||
const fixed_point_t optimal_quantity = demand[input_good_ptr] * max_possible_satisfaction; | ||
if (stockpile[input_good_ptr] >= optimal_quantity) { | ||
goods_to_buy_and_max_price.erase(input_good_ptr); | ||
at_or_below_optimum = false; | ||
} | ||
} | ||
} | ||
|
||
for (auto const& [input_good_ptr, max_price] : goods_to_buy_and_max_price) { | ||
const fixed_point_t optimal_quantity = demand[input_good_ptr] * max_possible_satisfaction; | ||
const fixed_point_t money_to_spend = optimal_quantity * max_price; | ||
//TODO pop cash -= money_to_spend | ||
market_instance.place_buy_up_to_order({ | ||
*input_good_ptr, | ||
optimal_quantity, | ||
money_to_spend, | ||
[this, input_good_ptr](const BuyResult buy_result) -> void { | ||
//TODO pop cash += buy_result.get_money_left() | ||
stockpile[input_good_ptr] += buy_result.get_quantity_bought(); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
|
||
current_production = production_type.get_base_output_quantity() | ||
* inputs_bought_scalar | ||
* pop.get_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 ) | ||
} | ||
}); | ||
} | ||
} |
19 changes: 14 additions & 5 deletions
19
src/openvic-simulation/economy/production/ArtisanalProducer.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,31 @@ | ||
#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; | ||
GoodDefinition::good_definition_map_t stockpile; | ||
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, | ||
GoodDefinition::good_definition_map_t&& new_stockpile, | ||
ProductionType const& new_production_type, | ||
fixed_point_t new_current_production | ||
); | ||
void artisan_tick(); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include "BuyUpToOrder.hpp" | ||
|
||
using namespace OpenVic; | ||
|
||
GoodBuyUpToOrder::GoodBuyUpToOrder( | ||
const fixed_point_t new_max_quantity, | ||
const fixed_point_t new_money_to_spend, | ||
const std::function<void(const BuyResult)> new_after_trade | ||
) : max_quantity { new_max_quantity }, | ||
money_to_spend { new_money_to_spend }, | ||
after_trade { new_after_trade } | ||
{} | ||
|
||
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 | ||
) : GoodBuyUpToOrder( | ||
new_max_quantity, | ||
new_money_to_spend, | ||
new_after_trade | ||
), | ||
good { &new_good } | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#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 GoodBuyUpToOrder { | ||
private: | ||
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: | ||
GoodBuyUpToOrder( | ||
const fixed_point_t new_max_quantity, | ||
const fixed_point_t new_money_to_spend, | ||
const std::function<void(const BuyResult)> new_after_trade | ||
); | ||
}; | ||
|
||
struct BuyUpToOrder : GoodBuyUpToOrder { | ||
private: | ||
GoodDefinition const* const PROPERTY(good); | ||
|
||
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 | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.