From 4575a4804c9f0129ccdcd40df6b8e35664efe7fc Mon Sep 17 00:00:00 2001
From: wanotaitei <wanotaitei@gmail.com>
Date: Tue, 10 Dec 2024 16:16:08 +0900
Subject: [PATCH] add: simulation reload

---
 Data/MenuIcon/MenuIcons.tsv                   |   1 +
 Library/PAX_MAHOROBA/LocationPoint.hpp        | 230 +++++++++---------
 Library/PAX_MAHOROBA/StringViewer.hpp         |  44 +++-
 .../Simulation/JapanProvinces.hpp             |   8 +-
 .../PAX_SAPIENTICA/Simulation/Settlement.hpp  |  16 +-
 .../Simulation/SettlementSimulator.hpp        |  29 ++-
 .../Simulation/SimulationConst.hpp            |  14 +-
 7 files changed, 209 insertions(+), 133 deletions(-)

diff --git a/Data/MenuIcon/MenuIcons.tsv b/Data/MenuIcon/MenuIcons.tsv
index 397754b1c..c0d2e26d0 100644
--- a/Data/MenuIcon/MenuIcons.tsv
+++ b/Data/MenuIcon/MenuIcons.tsv
@@ -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
diff --git a/Library/PAX_MAHOROBA/LocationPoint.hpp b/Library/PAX_MAHOROBA/LocationPoint.hpp
index 36c66fdc8..286e4348d 100644
--- a/Library/PAX_MAHOROBA/LocationPoint.hpp
+++ b/Library/PAX_MAHOROBA/LocationPoint.hpp
@@ -559,6 +559,8 @@ namespace paxs {
         std::size_t select_draw = 1;
         // 線を表示するか
         bool is_line = false;
+        // 移動線(矢印)を表示するか
+        bool is_arrow = true;
 #ifdef PAXS_USING_SIV3D
         // 選択肢を表示するフォント
         const s3d::Font select_font{ 30, s3d::Typeface::Bold };
@@ -694,6 +696,9 @@ namespace paxs {
             case 5:
                 text = U"5. 言語 Language";
                 break;
+            case 6:
+                text = U"6. 青銅 Bronze";
+                break;
             };
             // 選択項目を描画
             const s3d::RectF rect = select_font(text).region();
@@ -714,8 +719,10 @@ namespace paxs {
             else if (s3d::Key3.pressed()) select_draw = 3;
             else if (s3d::Key4.pressed()) select_draw = 4;
             else if (s3d::Key5.pressed()) select_draw = 5;
+            else if (s3d::Key6.pressed()) select_draw = 6;
             // グリッド線を描画する
             else if (s3d::KeyL.up()) is_line = (!is_line);
+            else if (s3d::KeyK.up()) is_arrow = (!is_arrow);
 #endif
 
             // 地名を描画
@@ -773,6 +780,9 @@ namespace paxs {
                                 //const double
                                 pop_original = settlement.getSNP() * 75.0;
                                 break;
+                            case 6:
+                                pop_original = static_cast<double>(settlement.getBronze());
+                                break;
                             }
 
                             const std::uint_least8_t pop = (pop_original >= 75) ? 75 : static_cast<std::uint_least8_t>(pop_original);
@@ -865,14 +875,108 @@ namespace paxs {
             }
 
             // 移動線を描画
-            for (const auto& agent : agents) {
-                for (const auto& settlement : agent.second.cgetSettlements()) {
+            if (is_arrow) {
+                for (const auto& agent : agents) {
+                    for (const auto& settlement : agent.second.cgetSettlements()) {
+                        // エージェントの初期設定を定義
+                        const auto lli = LocationPoint{
+                            std::unordered_map < std::uint_least32_t, std::string>(),
+                                paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                paxs::Vector2<int>(
+                        settlement.getPosition().x,settlement.getPosition().y), 10)),
+                                1, 1, 10, 100,0,0,99999999,
+                            MurMur3::calcHash("agent1")
+                            ,0 /* 出典なし */
+                            ,1.0 // 拡大率
+                        };
+
+                        // 経緯度の範囲外を除去
+                        if (lli.coordinate.x < (map_view_center_x - map_view_width / 1.6)
+                            || lli.coordinate.x >(map_view_center_x + map_view_width / 1.6)
+                            || lli.coordinate.y < (map_view_center_y - map_view_height / 1.6)
+                            || lli.coordinate.y >(map_view_center_y + map_view_height / 1.6)) continue;
+
+                        // 範囲内の場合
+                        if (lli.min_view > map_view_height || lli.max_view < map_view_height || lli.min_year > jdn || lli.max_year < jdn) {
+                            if (lli.min_year > jdn) continue;
+                            if (lli.max_year < jdn) continue;
+
+                            // 描画位置
+                            const paxg::Vec2i draw_pos = paxg::Vec2i{
+        static_cast<int>((lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+            static_cast<int>(double(paxg::Window::height()) - ((lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                            };
+
+                            if (settlement.getOldPosition().x != -1 && settlement.getOldPosition().x != 0) {
+                                if (settlement.getPositions().size() >= 1) {
+
+                                    // 過去の位置
+                                    auto old_lli = lli;
+                                    old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                        paxs::Vector2<int>(
+                                            settlement.getOldPosition().x,
+                                            settlement.getOldPosition().y), 10));
+                                    const paxg::Vec2i draw_old_pos = paxg::Vec2i{
+            static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+                static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                                    };
+
+                                    s3d::Array<s3d::Vec2> va;
+                                    va << s3d::Vec2{ draw_pos.x(), draw_pos.y() };
+                                    for (auto&& p : settlement.getPositions()) {
+                                        auto one_lli = lli;
+                                        one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                            paxs::Vector2<int>(p.x, p.y), 10));
+                                        const paxg::Vec2i draw_one_pos = paxg::Vec2i{
+        static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+            static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                                        };
+                                        va << s3d::Vec2{ draw_one_pos.x(), draw_one_pos.y() };
+                                    }
+                                    va << s3d::Vec2{ draw_old_pos.x(), draw_old_pos.y() };
+
+                                    const s3d::Spline2D spline(va);
+                                    spline.draw(2, Palette::Black);
+
+                                    // 過去の位置
+                                    auto one_lli = lli;
+                                    one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                        paxs::Vector2<int>(
+                                            settlement.getPositions()[0].x,
+                                            settlement.getPositions()[0].y), 10));
+                                    const paxg::Vec2i draw_one_pos = paxg::Vec2i{
+            static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+                static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                                    };
+                                    s3d::Line{ draw_one_pos.x(), draw_one_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(0.1, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
+                                }
+                                else {
+                                    // 過去の位置
+                                    auto old_lli = lli;
+                                    old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                        paxs::Vector2<int>(
+                                            settlement.getOldPosition().x,
+                                            settlement.getOldPosition().y), 10));
+                                    const paxg::Vec2i draw_old_pos = paxg::Vec2i{
+            static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+                static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                                    };
+                                    s3d::Line{ draw_old_pos.x(), draw_old_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(2, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
+                                }
+                            }
+
+                        }
+
+                    }
+                }
+                // 移動線を描画
+                for (const auto& marriage_pos : marriage_pos_list) {
                     // エージェントの初期設定を定義
                     const auto lli = LocationPoint{
                         std::unordered_map < std::uint_least32_t, std::string>(),
                             paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
                             paxs::Vector2<int>(
-                    settlement.getPosition().x,settlement.getPosition().y), 10)),
+                    marriage_pos.ex,marriage_pos.ey), 10)),
                             1, 1, 10, 100,0,0,99999999,
                         MurMur3::calcHash("agent1")
                         ,0 /* 出典なし */
@@ -896,114 +1000,22 @@ namespace paxs {
         static_cast<int>(double(paxg::Window::height()) - ((lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
                         };
 
-                        if (settlement.getOldPosition().x != -1 && settlement.getOldPosition().x != 0) {
-                            if (settlement.getPositions().size() >= 1) {
-
-                                // 過去の位置
-                                auto old_lli = lli;
-                                old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                                    paxs::Vector2<int>(
-                                        settlement.getOldPosition().x,
-                                        settlement.getOldPosition().y), 10));
-                                const paxg::Vec2i draw_old_pos = paxg::Vec2i{
-        static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-            static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                                };
-
-                                s3d::Array<s3d::Vec2> va;
-                                va << s3d::Vec2{ draw_pos.x(), draw_pos.y() };
-                                for (auto&& p : settlement.getPositions()) {
-                                    auto one_lli = lli;
-                                    one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                                        paxs::Vector2<int>(p.x, p.y), 10));
-                                    const paxg::Vec2i draw_one_pos = paxg::Vec2i{
-    static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-        static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                                    };
-                                    va << s3d::Vec2{ draw_one_pos.x(), draw_one_pos.y() };
-                                }
-                                va << s3d::Vec2{ draw_old_pos.x(), draw_old_pos.y() };
-
-                                const s3d::Spline2D spline(va);
-                                spline.draw(2, Palette::Black);
-
-                                // 過去の位置
-                                auto one_lli = lli;
-                                one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                                    paxs::Vector2<int>(
-                                        settlement.getPositions()[0].x,
-                                        settlement.getPositions()[0].y), 10));
-                                const paxg::Vec2i draw_one_pos = paxg::Vec2i{
-        static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-            static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                                };
-                                s3d::Line{ draw_one_pos.x(), draw_one_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(0.1, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
-                            }
-                            else {
-                                // 過去の位置
-                                auto old_lli = lli;
-                                old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                                    paxs::Vector2<int>(
-                                        settlement.getOldPosition().x,
-                                        settlement.getOldPosition().y), 10));
-                                const paxg::Vec2i draw_old_pos = paxg::Vec2i{
-        static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-            static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                                };
-                                s3d::Line{ draw_old_pos.x(), draw_old_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(2, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
-                            }
-                    }
-
-                    }
-
-                }
-            }
-            // 移動線を描画
-            for (const auto& marriage_pos : marriage_pos_list) {
-                // エージェントの初期設定を定義
-                const auto lli = LocationPoint{
-                    std::unordered_map < std::uint_least32_t, std::string>(),
-                        paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                        paxs::Vector2<int>(
-                marriage_pos.ex,marriage_pos.ey), 10)),
-                        1, 1, 10, 100,0,0,99999999,
-                    MurMur3::calcHash("agent1")
-                    ,0 /* 出典なし */
-                    ,1.0 // 拡大率
-                };
-
-                // 経緯度の範囲外を除去
-                if (lli.coordinate.x < (map_view_center_x - map_view_width / 1.6)
-                    || lli.coordinate.x >(map_view_center_x + map_view_width / 1.6)
-                    || lli.coordinate.y < (map_view_center_y - map_view_height / 1.6)
-                    || lli.coordinate.y >(map_view_center_y + map_view_height / 1.6)) continue;
-
-                // 範囲内の場合
-                if (lli.min_view > map_view_height || lli.max_view < map_view_height || lli.min_year > jdn || lli.max_year < jdn) {
-                    if (lli.min_year > jdn) continue;
-                    if (lli.max_year < jdn) continue;
-
-                    // 描画位置
-                    const paxg::Vec2i draw_pos = paxg::Vec2i{
-static_cast<int>((lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-    static_cast<int>(double(paxg::Window::height()) - ((lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                    };
-
-                    if (marriage_pos.sx != -1 && marriage_pos.sx != 0) {
-                        // 過去の位置
-                        auto old_lli = lli;
-                        old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
-                            paxs::Vector2<int>(
-                                marriage_pos.sx,
-                                marriage_pos.sy), 10));
-                        const paxg::Vec2i draw_old_pos = paxg::Vec2i{
-static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
-    static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
-                        };
-                        s3d::Line{ draw_old_pos.x(), draw_old_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(2, s3d::Vec2{ 8, 16 }, s3d::Color(221, 67, 98));
+                        if (marriage_pos.sx != -1 && marriage_pos.sx != 0) {
+                            // 過去の位置
+                            auto old_lli = lli;
+                            old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
+                                paxs::Vector2<int>(
+                                    marriage_pos.sx,
+                                    marriage_pos.sy), 10));
+                            const paxg::Vec2i draw_old_pos = paxg::Vec2i{
+    static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
+        static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
+                            };
+                            s3d::Line{ draw_old_pos.x(), draw_old_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(2, s3d::Vec2{ 8, 16 }, s3d::Color(221, 67, 98));
+                        }
                     }
                 }
-            }
+        }
 #endif
         }
 
diff --git a/Library/PAX_MAHOROBA/StringViewer.hpp b/Library/PAX_MAHOROBA/StringViewer.hpp
index 05cd5a2d1..e01b73d9c 100644
--- a/Library/PAX_MAHOROBA/StringViewer.hpp
+++ b/Library/PAX_MAHOROBA/StringViewer.hpp
@@ -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_,
@@ -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_; });
@@ -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);
                     }
                 }
                 // シミュレーションが初期化されている場合
@@ -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));
diff --git a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp
index 9552ba6f4..3f1ddd51b 100644
--- a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp
+++ b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp
@@ -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;
@@ -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);
diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
index bd70626c8..3a8bf7a44 100644
--- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
+++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
@@ -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(); }
@@ -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{}; // 乱数生成器
         
@@ -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 {
diff --git a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
index 4fd12eae6..648889615 100644
--- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
+++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
@@ -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(); // 人口を計算
 
             // 可住地の数を出力
@@ -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();  // 婚姻計測開始
@@ -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,
@@ -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;
@@ -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));
 
                     // 集落をグリッドに配置
@@ -571,6 +588,8 @@ namespace paxs {
                         gen,
                         environment
                     );
+                    // 青銅の持ち込み
+                    if (is_bronze) settlement.setBronze(SimulationConstants::getInstance()->bronze);
                     settlement.setPosition(live_position);
 
                     // 渡来人込みの地区 ID
@@ -662,6 +681,8 @@ namespace paxs {
                         if (is_farming) ++emigration_count; // 農耕カウント
                     }
                     settlement.addAgents(agents);
+                    // 青銅の持ち込み
+                    if (is_bronze) settlement.setBronze(SimulationConstants::getInstance()->bronze);
                 }
             }
 
diff --git a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp
index 304b3914f..78bb502b4 100644
--- a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp
+++ b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp
@@ -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;
 
@@ -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_; });
@@ -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;
 }