Skip to content

Commit a2b3c71

Browse files
authored
Merge pull request #634 from OpenVicProject/switch_based_on_defines_and_score
Switch artisanal production based on defines and score
2 parents 4b095c0 + 6cfca48 commit a2b3c71

File tree

5 files changed

+31
-5
lines changed

5 files changed

+31
-5
lines changed

src/openvic-simulation/InstanceManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ InstanceManager::InstanceManager(
2424
good_instance_manager
2525
},
2626
artisanal_producer_deps {
27+
new_definition_manager.get_define_manager().get_economy_defines(),
2728
new_definition_manager.get_modifier_manager().get_modifier_effect_cache()
2829
},
2930
country_instance_deps {

src/openvic-simulation/economy/production/ArtisanalProducer.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cstddef>
55

66
#include "openvic-simulation/country/CountryInstance.hpp"
7+
#include "openvic-simulation/defines/EconomyDefines.hpp"
78
#include "openvic-simulation/economy/GoodDefinition.hpp"
89
#include "openvic-simulation/economy/GoodInstance.hpp"
910
#include "openvic-simulation/economy/production/ProductionType.hpp"
@@ -24,7 +25,8 @@ ArtisanalProducer::ArtisanalProducer(
2425
fixed_point_map_t<GoodDefinition const*>&& new_stockpile,
2526
ProductionType const* const new_production_type,
2627
fixed_point_t new_current_production
27-
) : modifier_effect_cache { artisanal_producer_deps.modifier_effect_cache },
28+
) : economy_defines { artisanal_producer_deps.economy_defines },
29+
modifier_effect_cache { artisanal_producer_deps.modifier_effect_cache },
2830
stockpile { std::move(new_stockpile) },
2931
production_type_nullable { nullptr },
3032
current_production { new_current_production }
@@ -374,9 +376,10 @@ ProductionType const* ArtisanalProducer::pick_production_type(
374376

375377
const fixed_point_t revenue = pop.get_artisanal_revenue();
376378
const fixed_point_t costs = costs_of_production;
379+
const fixed_point_t base_chance_to_switch_while_profitable = economy_defines.get_goods_focus_swap_chance();
377380
if (production_type_nullable == nullptr || (revenue <= costs)) {
378381
should_pick_new_production_type = true;
379-
} else {
382+
} else if (base_chance_to_switch_while_profitable > 0) {
380383
const fixed_point_t current_score = calculate_production_type_score(
381384
revenue,
382385
costs,
@@ -406,8 +409,26 @@ ProductionType const* ArtisanalProducer::pick_production_type(
406409
}
407410
}
408411

409-
//TODO decide based on score and randomness and defines.economy.GOODS_FOCUS_SWAP_CHANCE
410-
should_pick_new_production_type = relative_score < fixed_point_t::_0_50;
412+
//picked so the line hits 0 at relative_score = 2/3 and the area under the curve equals 1
413+
//2/3 was picked as being in the top 1/3 of production types makes it very unlikely you'll profit from switching.
414+
constexpr fixed_point_t slope = fixed_point_t{-9} / 2;
415+
constexpr fixed_point_t offset = 3;
416+
417+
const fixed_point_t change_modifier_from_relative_score = std::max(fixed_point_t::_0, slope * relative_score + offset);
418+
const fixed_point_t switch_chance = base_chance_to_switch_while_profitable * change_modifier_from_relative_score;
419+
if (switch_chance >= 1) {
420+
should_pick_new_production_type = true;
421+
} else {
422+
constexpr fixed_point_t weights_sum = 1;
423+
const fixed_point_t keep_current_chance = weights_sum - switch_chance;
424+
const std::array<fixed_point_t, 2> weights { keep_current_chance, switch_chance };
425+
const size_t should_switch = sample_weighted_index(
426+
random_number_generator(),
427+
weights,
428+
weights_sum
429+
);
430+
should_pick_new_production_type = should_switch == 1;
431+
}
411432
}
412433

413434
if (!should_pick_new_production_type) {

src/openvic-simulation/economy/production/ArtisanalProducer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace OpenVic {
1212
struct ArtisanalProducerDeps;
13+
struct EconomyDefines;
1314
struct GoodDefinition;
1415
struct GoodInstanceManager;
1516
struct ModifierEffectCache;
@@ -21,6 +22,7 @@ namespace OpenVic {
2122

2223
struct ArtisanalProducer {
2324
private:
25+
EconomyDefines const& economy_defines;
2426
ModifierEffectCache const& modifier_effect_cache;
2527
fixed_point_map_t<GoodDefinition const*> stockpile;
2628

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#pragma once
22

33
namespace OpenVic {
4+
struct EconomyDefines;
45
struct ModifierEffectCache;
56

67
struct ArtisanalProducerDeps {
8+
EconomyDefines const& economy_defines;
79
ModifierEffectCache const& modifier_effect_cache;
810
};
911
}

src/openvic-simulation/utility/WeightedSampling.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace OpenVic {
1010
OV_ALWAYS_INLINE static size_t sample_weighted_index(
1111
const uint32_t random_value,
12-
const std::span<fixed_point_t> positive_weights,
12+
const std::span<const fixed_point_t> positive_weights,
1313
const fixed_point_t weights_sum
1414
) {
1515
if (positive_weights.empty() || weights_sum <= 0) {

0 commit comments

Comments
 (0)