File AgentFactory.hpp
File List > Agents > AgentFactory.hpp
Go to the documentation of this file
#pragma once
#include "../core/AgentBase.hpp"
#include "AStarAgent.hpp"
#include "PacingAgent.hpp"
#include "PathAgent.hpp"
#include "TrackingAgent.hpp"
#include "AgentLibary.hpp"
#include "../core/Entity.hpp"
#include "../core/WorldBase.hpp"
namespace walle {
// Forward-declare since it's easier to understand how AddXAgent works
// when the structs are defined nearby
struct PacingAgentData;
struct PathAgentData;
struct AStarAgentData;
struct TrackingAgentData;
class AgentFactory {
private:
cse491::WorldBase &world;
public:
AgentFactory() = delete;
explicit AgentFactory(cse491::WorldBase &world) : world(world) {}
AStarAgent &AddAStarAgent(const AStarAgentData &agent_data);
cse491::PacingAgent &AddPacingAgent(const PacingAgentData &agent_data);
TrackingAgent &AddTrackingAgent(const TrackingAgentData &agent_data);
PathAgent &AddPathAgent(const PathAgentData &agent_data);
}; // class AgentFactory
struct BaseAgentData {
std::string name;
cse491::GridPosition position;
char symbol = '*';
};
struct PacingAgentData : public BaseAgentData {
bool vertical = false;
};
cse491::PacingAgent &AgentFactory::AddPacingAgent(const PacingAgentData &agent_data) {
auto &entity = world.AddAgent<cse491::PacingAgent>(agent_data.name).SetPosition(agent_data.position).SetProperty(
"symbol",
agent_data.symbol);
auto &agent = DownCastAgent<cse491::PacingAgent>(entity);
agent.SetVertical(agent_data.vertical);
return agent;
}
struct PathAgentData : public BaseAgentData {
int index;
std::string string_path;
std::vector<cse491::GridPosition> vector_path;
};
PathAgent &AgentFactory::AddPathAgent(const PathAgentData &agent_data) {
auto &entity = world.AddAgent<walle::PathAgent>(agent_data.name).SetPosition(agent_data.position).SetProperty(
"symbol",
agent_data.symbol);
auto &agent = DownCastAgent<walle::PathAgent>(entity);
if (!agent_data.string_path.empty()) {
agent.SetProperty<std::basic_string_view<char>>("path",
agent_data.string_path); // TODO add another option to provide grid point
} else {
agent.SetPath(agent_data.vector_path);
}
agent.Initialize();
return agent;
}
struct AStarAgentData : public BaseAgentData {
int recalculate_after_x_turns = 5;
cse491::GridPosition goal_pos;
};
AStarAgent &AgentFactory::AddAStarAgent(const AStarAgentData &agent_data) {
auto &entity = world.AddAgent<walle::AStarAgent>(agent_data.name).SetPosition(agent_data.position).SetProperty(
"symbol",
agent_data.symbol);
auto &agent = DownCastAgent<walle::AStarAgent>(entity);
agent.SetGoalPosition(agent_data.goal_pos);
agent.SetRecalculate(agent_data.recalculate_after_x_turns);
return agent;
}
struct TrackingAgentData : public BaseAgentData {
std::vector<cse491::GridPosition> vector_path;
std::string string_path;
cse491::Entity *target;
int tracking_distance = 5;
cse491::GridPosition start_pos;
std::shared_ptr<Alerter> alerter = nullptr;
TrackingAgentData() = default;
TrackingAgentData(std::string name,
cse491::GridPosition curr_pos,
char symbol,
std::string path,
cse491::Entity * target,
int tracking_dist,
cse491::GridPosition start_pos,
std::shared_ptr<Alerter> alerter)
: BaseAgentData({std::move(name), curr_pos, symbol}),
vector_path(StrToOffsets(path)),
string_path(std::move(path)),
target(target),
tracking_distance(tracking_dist),
start_pos(start_pos),
alerter(alerter) {}
};
TrackingAgent &AgentFactory::AddTrackingAgent(const TrackingAgentData &agent_data) {
auto &entity = world.AddAgent<walle::TrackingAgent>(agent_data.name).SetPosition(agent_data.position).SetProperty(
"symbol",
agent_data.symbol);
auto &agent = DownCastAgent<TrackingAgent>(entity);
if (!agent_data.string_path.empty()) {
agent.SetProperty<std::basic_string_view<char>>("path", agent_data.string_path);
} else {
agent.SetPath(agent_data.vector_path);
}
agent.SetTarget(agent_data.target);
agent.SetTrackingDistance(agent_data.tracking_distance);
agent.SetStartPosition(agent_data.start_pos);
if (agent_data.alerter != nullptr) {
agent.SetProperty("alerter", agent_data.alerter);
}
agent.Initialize();
return agent;
}
} // namespace walle