Skip to content

Commit

Permalink
add: simulation reload
Browse files Browse the repository at this point in the history
  • Loading branch information
AsPJT committed Dec 10, 2024
1 parent 0570a10 commit 4575a48
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 133 deletions.
1 change: 1 addition & 0 deletions Data/MenuIcon/MenuIcons.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ texture_100c_l Data/MenuIcon/10kYearL.svg
texture_100c_r Data/MenuIcon/10kYearR.svg
texture_stop Data/MenuIcon/stop.svg
texture_playback Data/MenuIcon/playback.svg
texture_reload Data/MenuIcon/Reload.svg
texture_reverse_playback Data/MenuIcon/reverse-playback.svg
texture_1step Data/MenuIcon/1Step.svg
texture_delete_agent_data Data/MenuIcon/DeleteAgentData.svg
Expand Down
230 changes: 121 additions & 109 deletions Library/PAX_MAHOROBA/LocationPoint.hpp

Large diffs are not rendered by default.

44 changes: 32 additions & 12 deletions Library/PAX_MAHOROBA/StringViewer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ namespace paxs {
class StringViewerSiv3D {
private:
#ifdef PAXS_USING_SIMULATOR
void simulationInit(
std::unique_ptr<paxs::SettlementSimulator>& simulator, // コンパイル時の分岐により使わない場合あり
paxs::KoyomiSiv3D& koyomi_siv
) const {
simulator->init();
koyomi_siv.steps.setDay(0); // ステップ数を 0 にする
koyomi_siv.jdn.setDay(static_cast<double>(SimulationConstants::getInstance()->start_julian_day)); // シミュレーション初期時の日付に設定
koyomi_siv.calcDate();
koyomi_siv.is_agent_update = false;
koyomi_siv.move_forward_in_time = false; // 一時停止
koyomi_siv.go_back_in_time = false;
}

void simulation(
std::unique_ptr<paxs::SettlementSimulator>& simulator, // コンパイル時の分岐により使わない場合あり
paxs::TouchManager& tm_,
Expand All @@ -66,13 +79,14 @@ namespace paxs {
const std::unordered_map<std::uint_least32_t, paxg::Texture>& texture_dictionary = key_value_tsv.get();
const int time_icon_size = 40; // 時間操作アイコンの大きさ

std::string map_list_path = "Data/Simulations/MapList.tsv";
std::string japan_provinces_path = "Data/Simulations/Sample";

// シミュレーションが初期化されていない場合
if (simulator.get() == nullptr) {
texture_dictionary.at(MurMur3::calcHash("texture_load_geographic_data2")).resizedDraw(
time_icon_size, paxg::Vec2i(paxg::Window::width() - 360, debug_start_y));
if (tm_.get(paxg::Rect{ paxg::Vec2i(paxg::Window::width() - 360, debug_start_y), paxg::Vec2i(time_icon_size, time_icon_size) }.leftClicked())) {
std::string map_list_path = "Data/Simulations/MapList.tsv";
std::string japan_provinces_path = "Data/Simulations/Sample";

AppConfig::getInstance()->calcDataSettingsNotPath(MurMur3::calcHash("SimulationXYZTiles"),
[&](const std::string& path_) {map_list_path = path_; });
Expand All @@ -86,20 +100,11 @@ namespace paxs {
is_console_open = true;
}
#endif

std::random_device seed_gen;
simulator = std::make_unique<paxs::SettlementSimulator>(
map_list_path, japan_provinces_path,
seed_gen());
simulator->init();
koyomi_siv.steps.setDay(0); // ステップ数を 0 にする
koyomi_siv.jdn.setDay(static_cast<double>(SimulationConstants::getInstance()->start_julian_day)); // シミュレーション初期時の日付に設定
koyomi_siv.calcDate();

koyomi_siv.is_agent_update = false;

koyomi_siv.move_forward_in_time = false; // 一時停止
koyomi_siv.go_back_in_time = false;
simulationInit(simulator, koyomi_siv);
}
}
// シミュレーションが初期化されている場合
Expand All @@ -119,6 +124,21 @@ namespace paxs {
}
// シミュレーションが再生されていない場合
else {
// シミュレーション入力データを初期化
texture_dictionary.at(MurMur3::calcHash("texture_reload")).resizedDraw(
time_icon_size, paxg::Vec2i(paxg::Window::width() - 420, debug_start_y + 60));
if (tm_.get(paxg::Rect{ paxg::Vec2i(paxg::Window::width() - 420, debug_start_y + 60), paxg::Vec2i(time_icon_size, time_icon_size) }.leftClicked())) {
SimulationConstants::getInstance()->init();
}
// 人間データを初期化
texture_dictionary.at(MurMur3::calcHash("texture_load_agent_data2")).resizedDraw(
time_icon_size, paxg::Vec2i(paxg::Window::width() - 420, debug_start_y));
if (tm_.get(paxg::Rect{ paxg::Vec2i(paxg::Window::width() - 420, debug_start_y), paxg::Vec2i(time_icon_size, time_icon_size) }.leftClicked())) {
simulationInit(simulator, koyomi_siv);

koyomi_siv.steps.setDay(0); // ステップ数を 0 にする
koyomi_siv.calcDate();
}
// 地形データを削除
texture_dictionary.at(MurMur3::calcHash("texture_delete_geographic_data")).resizedDraw(
time_icon_size, paxg::Vec2i(paxg::Window::width() - 360, debug_start_y));
Expand Down
8 changes: 4 additions & 4 deletions Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ namespace paxs {
std::uint_least8_t hunter_gatherer = 0; // 狩猟採集
std::uint_least8_t farming = 0; // 農耕文化
std::uint_least8_t snp = 0; // SNP
std::uint_least32_t settlement_population_min_ad200 = 0;
std::uint_least32_t settlement_population_max_ad200 = 0;
std::uint_least32_t settlement_pop_min = 0;
std::uint_least32_t settlement_pop_max = 0;
std::uint_least32_t init_pop = 0;
std::uint_least32_t immigrant = 0;
double immigrant_f64 = 0;
Expand Down Expand Up @@ -281,8 +281,8 @@ namespace paxs {
district.hunter_gatherer = static_cast<std::uint_least8_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("hunter_gatherer")]]));
district.farming = static_cast<std::uint_least8_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("farming")]]));
district.snp = static_cast<std::uint_least8_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("snp")]]));
district.settlement_population_min_ad200 = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("min_pop_placed_per_cell")]]));
district.settlement_population_max_ad200 = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("max_pop_placed_per_cell")]]));
district.settlement_pop_min = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("min_pop_placed_per_cell")]]));
district.settlement_pop_max = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("max_pop_placed_per_cell")]]));
district.init_pop = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("init_pop")]]));
district.immigrant = static_cast<std::uint_least32_t>(std::stoul(sub_menu_v[menu[MurMur3::calcHash("immigrant")]]));
district.immigrant_f64 = static_cast<double>(district.immigrant);
Expand Down
16 changes: 14 additions & 2 deletions Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,15 @@ namespace paxs {
/// @brief 移動したかどうかを取得
bool isMoved() const noexcept { return is_moved; }

/// @brief Get the Bronze.
/// @brief 青銅を取得
std::uint_least32_t getBronze() const noexcept {
return bronze;
}
void setBronze(const std::uint_least32_t bronze_) noexcept {
bronze = bronze_;
}

/// @brief Get the population.
/// @brief 人口を取得
std::size_t getPopulation() const noexcept { return agents.size(); }
Expand Down Expand Up @@ -790,8 +799,6 @@ namespace paxs {
std::uint_least32_t id = 0;
/// @brief 集落の座標
Vector2 position{};
Vector2 old_position{ -1,-1 };
std::vector<Vector2> positions{};

std::mt19937* gen{}; // 乱数生成器

Expand All @@ -800,6 +807,11 @@ namespace paxs {
/// @brief エージェントの配列
std::vector<Agent> agents{};

std::uint_least32_t bronze = 0; // 青銅
/// @brief 集落の移動前の座標
Vector2 old_position{ -1,-1 };
std::vector<Vector2> positions{};

/// @brief Birth.
/// @brief 出産
void birth(KanakumaLifeSpan& kanakuma_life_span) noexcept {
Expand Down
29 changes: 25 additions & 4 deletions Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,18 @@ namespace paxs {
void init() {
initResults();
settlement_grids.clear();
population_num = 0; // 人口数
settlement_num = 0; // 集落数
processing_time = 0.0;
move_processing_time = 0.0;
marriage_processing_time = 0.0;
emigration_count = 0;
step_count = 0;
land_positions.clear();
marriage_pos_list.clear();

initRandomizeSettlements();
randomizeSettlements(true, false /* 在地人 */);
randomizeSettlements(true, false /* 在地人 */, false /*青銅文化は持たない*/);
calcPop(); // 人口を計算

// 可住地の数を出力
Expand Down Expand Up @@ -281,7 +291,7 @@ namespace paxs {
// 前901年から稲作文化開始
if (step_count >= SimulationConstants::getInstance()->immigration_start_steps &&
step_count <= SimulationConstants::getInstance()->immigration_end_steps) {
randomizeSettlements(false, true /* 渡来人 */);
randomizeSettlements(false, true /* 渡来人 */, (step_count >= SimulationConstants::getInstance()->bronze_start_steps)/*青銅*/);
}

m_start_time = std::chrono::system_clock::now(); // 婚姻計測開始
Expand Down Expand Up @@ -337,6 +347,12 @@ namespace paxs {
}
}
}
// 青銅交換
if (close_settlements.size() >= 2) {
std::uint_fast32_t bronze = (close_settlements.front()->getBronze() + close_settlements.back()->getBronze()) / 2;
close_settlements.front()->setBronze(bronze);
close_settlements.back()->setBronze(bronze);
}

for (auto& settlement : settlements) {
settlement.marriage(marriageable_female_index, male_settlement_pair, marriageable_agents_index_pair, marriage_settlements,
Expand Down Expand Up @@ -494,7 +510,8 @@ namespace paxs {
/// @brief 集落をランダムに配置する
void randomizeSettlements(
bool is_ad200,
bool is_farming // 渡来人であるか?
bool is_farming, // 渡来人であるか?
bool is_bronze // 青銅文化であるか?
) noexcept {
// 地区 ID の最大値
std::uint_least8_t district_id_max = 0;
Expand Down Expand Up @@ -555,7 +572,7 @@ namespace paxs {

// 配置する集落の人口を決定
paxs::District district = japan_provinces->cgetDistrict(district_id);
int settlement_population = std::uniform_int_distribution<>(district.settlement_population_min_ad200, district.settlement_population_max_ad200)(gen);
int settlement_population = std::uniform_int_distribution<>(district.settlement_pop_min, district.settlement_pop_max)(gen);
settlement_population = (std::min)(settlement_population, static_cast<int>(district_population_it->second));

// 集落をグリッドに配置
Expand All @@ -571,6 +588,8 @@ namespace paxs {
gen,
environment
);
// 青銅の持ち込み
if (is_bronze) settlement.setBronze(SimulationConstants::getInstance()->bronze);
settlement.setPosition(live_position);

// 渡来人込みの地区 ID
Expand Down Expand Up @@ -662,6 +681,8 @@ namespace paxs {
if (is_farming) ++emigration_count; // 農耕カウント
}
settlement.addAgents(agents);
// 青銅の持ち込み
if (is_bronze) settlement.setBronze(SimulationConstants::getInstance()->bronze);
}
}

Expand Down
14 changes: 12 additions & 2 deletions Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,18 @@ namespace paxs {
std::uint_least32_t cell_group_length = 64;

// 渡来開始ステップ数
std::uint_least64_t immigration_start_steps = 2401;
std::uint_least64_t immigration_start_steps = 2401; // 前 900 年
std::uint_least64_t immigration_end_steps = 21600;

// 青銅開始ステップ数
std::uint_least64_t bronze_start_steps = 9601; // 前 300 年

// 渡来地区 ID
std::uint_least8_t immigration_district_id = 73;

// 青銅量
std::uint_least64_t bronze = 100; // 渡来人が持ってくる青銅量

// 初期化時の寿命までの最低年数
AgeType init_lifespan_grace_period = 180;

Expand Down Expand Up @@ -200,7 +206,7 @@ namespace paxs {
return sr.getZ(area);
}

SimulationConstants() {
void init() {
std::string str = "";
AppConfig::getInstance()->calcDataSettings(MurMur3::calcHash("SimulationConstants"),
[&](const std::string& path_) {str = path_; });
Expand Down Expand Up @@ -272,6 +278,10 @@ namespace paxs {
pregnant_age_min_f64 = childbearing_age_min_f64 - static_cast<double>(birth_interval) / static_cast<double>(steps_per_year);
}

SimulationConstants() {
init();
}

};
SimulationConstants* SimulationConstants::instance = nullptr;
}
Expand Down

0 comments on commit 4575a48

Please sign in to comment.