Skip to content

Commit

Permalink
Merge pull request #112 from AsPJT/feature-simulation-line
Browse files Browse the repository at this point in the history
シミュレーションに婚姻移動表示とグリッド表示機能を追加
  • Loading branch information
AsPJT authored Nov 23, 2024
2 parents c7c6107 + 3433ded commit 39edb81
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 17 deletions.
155 changes: 145 additions & 10 deletions Library/PAX_MAHOROBA/LocationPoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <PAX_SAPIENTICA/MurMur3.hpp>

#include <PAX_GRAPHICA/Circle.hpp>
#include <PAX_GRAPHICA/Line.hpp>
#include <PAX_GRAPHICA/String.hpp>
#include <PAX_GRAPHICA/Texture.hpp>
#include <PAX_GRAPHICA/Rect.hpp>
Expand Down Expand Up @@ -556,6 +557,8 @@ namespace paxs {
class AgentLocation {
private:
std::size_t select_draw = 1;
// 線を表示するか
bool is_line = false;
#ifdef PAXS_USING_SIV3D
// 選択肢を表示するフォント
const s3d::Font select_font{ 30, s3d::Typeface::Bold };
Expand Down Expand Up @@ -701,6 +704,7 @@ namespace paxs {

void draw(const double jdn,
std::unordered_map<SettlementGridsType, paxs::SettlementGrid>& agents,
const std::vector<GridType4>& marriage_pos_list,
const double map_view_width, const double map_view_height, const double map_view_center_x, const double map_view_center_y
)/*const Siv3D Key は非 const */ {

Expand All @@ -710,6 +714,8 @@ 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::KeyL.up()) is_line = (!is_line);
#endif

// 地名を描画
Expand All @@ -720,12 +726,8 @@ namespace paxs {
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)),
settlement.getPosition().x,settlement.getPosition().y), 10)),
1, 1, 10, 100,0,0,99999999,
//(agent.getGender()) ?
MurMur3::calcHash("agent1")
,0 /* 出典なし */
,1.0 // 拡大率
Expand All @@ -738,10 +740,7 @@ namespace paxs {
|| 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_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;

Expand Down Expand Up @@ -806,7 +805,97 @@ namespace paxs {
).draw(language_color);
}

}
}
}
#ifdef PAXS_USING_SIV3D
// グリッド線を描画
if (is_line) {
const auto area_width = SimulationConstants::getInstance()->getEndArea().x - SimulationConstants::getInstance()->getStartArea().x;
const auto area_height = SimulationConstants::getInstance()->getEndArea().y - SimulationConstants::getInstance()->getStartArea().y;

const paxs::MercatorDeg start_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(0, 0), 10));
const paxg::Vec2f draw_start_pos = paxg::Vec2f{
static_cast<float>((start_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<float>(double(paxg::Window::height()) - ((start_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};
const paxs::MercatorDeg end_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(area_width * 256, area_height * 256), 10));
const paxg::Vec2f draw_end_pos = paxg::Vec2f{
static_cast<float>((end_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<float>(double(paxg::Window::height()) - ((end_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};
const paxs::MercatorDeg tile_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(SimulationConstants::getInstance()->cell_group_length, SimulationConstants::getInstance()->cell_group_length), 10));
const paxg::Vec2f tile_pos = paxg::Vec2f{
static_cast<float>((tile_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())) - draw_start_pos.x(),
static_cast<float>(double(paxg::Window::height()) - ((tile_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) - draw_start_pos.y()
};

paxg::Line(
static_cast<float>(draw_start_pos.x()), static_cast<float>(draw_start_pos.y()),
static_cast<float>(draw_start_pos.x()), static_cast<float>(draw_end_pos.y())
).draw(5, paxg::Color(0, 0, 0));
paxg::Line(
static_cast<float>(draw_start_pos.x()), static_cast<float>(draw_start_pos.y()),
static_cast<float>(draw_end_pos.x()), static_cast<float>(draw_start_pos.y())
).draw(5, paxg::Color(0, 0, 0));
paxg::Line(
static_cast<float>(draw_end_pos.x()), static_cast<float>(draw_start_pos.y()),
static_cast<float>(draw_end_pos.x()), static_cast<float>(draw_end_pos.y())
).draw(5, paxg::Color(0, 0, 0));
paxg::Line(
static_cast<float>(draw_start_pos.x()), static_cast<float>(draw_end_pos.y()),
static_cast<float>(draw_end_pos.x()), static_cast<float>(draw_end_pos.y())
).draw(5, paxg::Color(0, 0, 0));

for (float i = draw_start_pos.x(); i < draw_end_pos.x(); i += tile_pos.x()) {
paxg::Line(
static_cast<float>(i), static_cast<float>(draw_start_pos.y()),
static_cast<float>(i), static_cast<float>(draw_end_pos.y())
).draw(0.5, paxg::Color(0, 0, 0));
}
for (float i = draw_start_pos.y(); i < draw_end_pos.y(); i += tile_pos.y()) {
paxg::Line(
static_cast<float>(draw_start_pos.x()), static_cast<float>(i),
static_cast<float>(draw_end_pos.x()), static_cast<float>(i)
).draw(0.5, paxg::Color(0, 0, 0));
}
}

// 移動線を描画
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) {

Expand Down Expand Up @@ -864,12 +953,58 @@ namespace paxs {
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);
}
}
#endif

}

}
}
// 移動線を描画
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));
}
}
}
#endif
}

};
Expand Down
2 changes: 1 addition & 1 deletion Library/PAX_MAHOROBA/MapViewer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ namespace paxs {
#ifdef PAXS_USING_SIMULATOR
if (visible[MurMur3::calcHash("Simulation")]) {
if (agent_location.get() != nullptr && simulator.get() != nullptr) {
agent_location->draw(koyomi_siv.jdn.cgetDay(), simulator->getSettlementGrids(), map_view.getWidth(), map_view.getHeight(), map_view.getCenterX(), map_view.getCenterY()
agent_location->draw(koyomi_siv.jdn.cgetDay(), simulator->getSettlementGrids(), simulator->getMarriagePosList(), map_view.getWidth(), map_view.getHeight(), map_view.getCenterX(), map_view.getCenterY()
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions Library/PAX_SAPIENTICA/Simulation/Data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <iostream>
#include <regex>
#include <stdexcept>
#include <unordered_map>
#include <map>

#include <PAX_SAPIENTICA/AppConfig.hpp>
#include <PAX_SAPIENTICA/File.hpp>
Expand Down Expand Up @@ -96,7 +96,7 @@ namespace paxs {

private:
std::string name; // データの名前
std::unordered_map<DataGridsType, DataType> data; // データ
std::map<DataGridsType, DataType> data; // データ
int default_z; // データのz値
double z_mag; // シミュレーションのz値からデータのz値に変換するときの倍率
int column_size; // シミュレーションの列数
Expand Down
9 changes: 8 additions & 1 deletion Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,12 @@ namespace paxs {

/// @brief Marriage.
/// @brief 婚姻
//template<typename Add_, typename Delete_>
void marriage(std::vector<Settlement*> close_settlements,
std::function<void(const paxs::SettlementAgent, const std::uint_least32_t, const Vector2)> add_agent,
std::function<void(const std::uint64_t, const std::uint_least32_t, const Vector2)> delete_agent
std::function<void(const std::uint64_t, const std::uint_least32_t, const Vector2)> delete_agent,
//Add_ add_agent, Delete_ delete_agent,
std::vector<GridType4>& marriage_pos_list
) noexcept {
// 結婚の条件を満たすエージェントを取得
std::vector<std::size_t> marriageable_female_index;
Expand Down Expand Up @@ -442,6 +445,8 @@ namespace paxs {

male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer(), female_.cgetLanguage());
agents.emplace_back(male_);

marriage_pos_list.emplace_back(GridType4{ close_settlements[j]->position.x, close_settlements[j]->position.y, position.x, position.y });
}
// 父方の場合
else {
Expand All @@ -455,6 +460,8 @@ namespace paxs {

male_settlement_position /= SimulationConstants::getInstance()->cell_group_length;
add_agent(female_, male_settlement_id, male_settlement_position);

marriage_pos_list.emplace_back(GridType4{ position.x, position.y, close_settlements[j]->position.x, close_settlements[j]->position.y });
}
is_found = true;
break;
Expand Down
12 changes: 9 additions & 3 deletions Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,9 @@ namespace paxs {
}

m_start_time = std::chrono::system_clock::now(); // 婚姻計測開始
marriage_pos_list.clear();

auto delete_agent = [this](const std::uint_least32_t agent_id, const std::uint_least32_t settlement_id, const Vector2 key) {
auto&& delete_agent = [this](const std::uint_least32_t agent_id, const std::uint_least32_t settlement_id, const Vector2 key) {
auto it = settlement_grids.find(key.to(SettlementGridsType{}));
if (it != settlement_grids.end()) {
it->second.deleteAgent(agent_id, settlement_id);
Expand All @@ -296,7 +297,7 @@ namespace paxs {
}
};

auto add_agent = [this](const paxs::SettlementAgent agent_, const std::uint_least32_t settlement_id, const Vector2 key) {
auto&& add_agent = [this](const paxs::SettlementAgent agent_, const std::uint_least32_t settlement_id, const Vector2 key) {
auto it = settlement_grids.find(key.to(SettlementGridsType{}));
if (it != settlement_grids.end()) {
it->second.addAgent(agent_, settlement_id);
Expand Down Expand Up @@ -328,7 +329,7 @@ namespace paxs {
}

for (auto& settlement : settlements) {
settlement.marriage(close_settlements, add_agent, delete_agent);
settlement.marriage(close_settlements, add_agent, delete_agent, marriage_pos_list);
}
}

Expand Down Expand Up @@ -363,6 +364,9 @@ namespace paxs {
processing_time = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() / 1000.0);
}

// 婚姻時に移動した位置一覧を取得する
const std::vector<GridType4>& getMarriagePosList() const { return marriage_pos_list; }

/// @brief Get the agent list.
/// @brief エージェントのリストを取得する
constexpr std::unordered_map<SettlementGridsType, SettlementGrid>&
Expand Down Expand Up @@ -426,6 +430,8 @@ namespace paxs {
std::ofstream snp_ofs;
std::ofstream language_ofs;
std::ofstream live_ofs;
// 婚姻時に移動前の位置と移動後の位置を記録
std::vector<GridType4> marriage_pos_list{};

/// @brief ()
/// @brief 集落をランダムに配置する前の初期化処理
Expand Down
5 changes: 5 additions & 0 deletions Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ namespace paxs {

constexpr std::array <Vector2<GridType>, 8> astar_adjacent_cell{ {Vector2<GridType>(-1, -1),Vector2<GridType>(1, -1),Vector2<GridType>(-1, 1),Vector2<GridType>(1, 1),Vector2<GridType>(0, -1),Vector2<GridType>(-1, 0),Vector2<GridType>(0, 1),Vector2<GridType>(1, 0)} };

// 始点と終点を管理(婚姻の前後の位置情報を保持する用)
struct GridType4 {
GridType sx{}, sy{}, ex{}, ey{};
};

struct SimulationConstants {
// インスタンスを取得
static SimulationConstants* getInstance() {
Expand Down

0 comments on commit 39edb81

Please sign in to comment.