11#include " ArtisanalProducer.hpp"
22
33#include < cstddef>
4- #include < random >
4+ #include < XoshiroCpp.hpp >
55
66#include " openvic-simulation/country/CountryInstance.hpp"
77#include " openvic-simulation/economy/GoodDefinition.hpp"
1414#include " openvic-simulation/pop/PopValuesFromProvince.hpp"
1515#include " openvic-simulation/types/fixed_point/FixedPoint.hpp"
1616#include " openvic-simulation/utility/Typedefs.hpp"
17+ #include " openvic-simulation/utility/WeightedSampling.hpp"
1718
1819using namespace OpenVic ;
1920
@@ -48,14 +49,21 @@ void ArtisanalProducer::set_production_type(ProductionType const* const new_prod
4849void ArtisanalProducer::artisan_tick (
4950 Pop& pop,
5051 PopValuesFromProvince const & values_from_province,
52+ XoshiroCpp::Xoshiro128StarStar& random_number_generator,
5153 IndexedFlatMap<GoodDefinition, char >& reusable_goods_mask,
5254 memory::vector<fixed_point_t >& pop_max_quantity_to_buy_per_good,
5355 memory::vector<fixed_point_t >& pop_money_to_spend_per_good,
5456 memory::vector<fixed_point_t >& reusable_map_0,
5557 memory::vector<fixed_point_t >& reusable_map_1
5658) {
5759 ProductionType const * const old_production_type = production_type_nullable;
58- set_production_type (pick_production_type (pop, values_from_province));
60+ set_production_type (
61+ pick_production_type (
62+ pop,
63+ values_from_province,
64+ random_number_generator
65+ )
66+ );
5967 if (production_type_nullable == nullptr ) {
6068 return ;
6169 }
@@ -340,7 +348,8 @@ fixed_point_t ArtisanalProducer::calculate_production_type_score(
340348
341349ProductionType const * ArtisanalProducer::pick_production_type (
342350 Pop& pop,
343- PopValuesFromProvince const & values_from_province
351+ PopValuesFromProvince const & values_from_province,
352+ XoshiroCpp::Xoshiro128StarStar& random_number_generator
344353) const {
345354 bool should_pick_new_production_type;
346355 const auto ranked_artisanal_production_types = values_from_province.get_ranked_artisanal_production_types ();
@@ -396,25 +405,11 @@ ProductionType const* ArtisanalProducer::pick_production_type(
396405 weights_sum += weight;
397406 }
398407
399- // TODO move to utilities or something
400- std::random_device rd;
401- std::mt19937 rng { rd () };
402- std::uniform_int_distribution<fixed_point_t ::value_type> distribution {
403- fixed_point_t ::_0.get_raw_value (),
404- weights_sum.get_raw_value ()
405- };
406-
407- const fixed_point_t random_number = fixed_point_t::parse_raw (distribution (rng));
408- fixed_point_t weights_running_total = 0 ;
409- ProductionType const * new_production_type = ranked_artisanal_production_types.back ().first ;
410- for (auto it = weights.begin (); it < weights.end (); ++it) {
411- weights_running_total += *it;
412- if (random_number <= weights_running_total) {
413- const size_t i = it - weights.begin ();
414- new_production_type = ranked_artisanal_production_types[i].first ;
415- break ;
416- }
417- }
408+ const size_t sample_index = sample_weighted_index (
409+ random_number_generator (),
410+ weights,
411+ weights_sum
412+ );
418413
419- return new_production_type ;
414+ return ranked_artisanal_production_types[sample_index]. first ;
420415}
0 commit comments