mirror of
https://github.com/JHUAPL/kami.git
synced 2026-01-09 14:58:02 -05:00
The CLion linter is a beast
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
- :bug:`0` Cleaned up numerous issues found by CLion's linter
|
||||||
- :feature:`0` Added a new overview to the documents
|
- :feature:`0` Added a new overview to the documents
|
||||||
- :feature:`0` Added basic installation instructions
|
- :feature:`0` Added basic installation instructions
|
||||||
- :bug:`0` Retagged previous versions using pure Semantic Versioning
|
- :bug:`0` Retagged previous versions using pure Semantic Versioning
|
||||||
|
|||||||
@@ -23,25 +23,23 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "boltzmann1d.h"
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/grid1d.h>
|
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
#include <kami/multigrid1d.h>
|
#include <kami/multigrid1d.h>
|
||||||
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <spdlog/stopwatch.h>
|
#include <spdlog/stopwatch.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
#include <CLI/Config.hpp>
|
#include <CLI/Config.hpp>
|
||||||
#include <CLI/Formatter.hpp>
|
#include <CLI/Formatter.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
#include "boltzmann1d.h"
|
||||||
#include <memory>
|
|
||||||
#include <random>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace kami;
|
using namespace kami;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -53,14 +51,14 @@ shared_ptr<mt19937> rng = nullptr;
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<AgentID> : fmt::formatter<string> {
|
struct fmt::formatter<AgentID> : fmt::formatter<string> {
|
||||||
auto format(AgentID agent_id, format_context &ctx) {
|
[[maybe_unused]] static auto format(AgentID agent_id, format_context &ctx) {
|
||||||
return format_to(ctx.out(), "{}", agent_id.to_string());
|
return format_to(ctx.out(), "{}", agent_id.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<GridCoord1D> : fmt::formatter<string> {
|
struct fmt::formatter<GridCoord1D> : fmt::formatter<string> {
|
||||||
auto format(GridCoord1D coord, format_context &ctx) {
|
[[maybe_unused]] static auto format(const GridCoord1D& coord, format_context &ctx) {
|
||||||
return format_to(ctx.out(), "{}", coord.to_string());
|
return format_to(ctx.out(), "{}", coord.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -82,7 +80,7 @@ void MoneyAgent1D::move_agent() {
|
|||||||
console->trace("Entering move_agent");
|
console->trace("Entering move_agent");
|
||||||
auto agent_id = get_agent_id();
|
auto agent_id = get_agent_id();
|
||||||
auto move_list = _world->get_neighborhood(agent_id, false);
|
auto move_list = _world->get_neighborhood(agent_id, false);
|
||||||
std::uniform_int_distribution<int> dist(0, move_list.size() - 1);
|
std::uniform_int_distribution<int> dist(0, (int)move_list.size() - 1);
|
||||||
auto new_location = move_list[dist(*rng)];
|
auto new_location = move_list[dist(*rng)];
|
||||||
|
|
||||||
console->trace("Moving Agent {} to location {}", agent_id, new_location);
|
console->trace("Moving Agent {} to location {}", agent_id, new_location);
|
||||||
@@ -90,29 +88,23 @@ void MoneyAgent1D::move_agent() {
|
|||||||
console->trace("Exiting move_agent");
|
console->trace("Exiting move_agent");
|
||||||
}
|
}
|
||||||
|
|
||||||
int MoneyAgent1D::get_wealth() { return _agent_wealth; }
|
|
||||||
|
|
||||||
void MoneyAgent1D::set_wealth(int wealth) { _agent_wealth = wealth; }
|
|
||||||
|
|
||||||
void MoneyAgent1D::give_money() {
|
void MoneyAgent1D::give_money() {
|
||||||
AgentID agent_id = get_agent_id();
|
AgentID agent_id = get_agent_id();
|
||||||
GridCoord1D location = _world->get_location_by_agent(agent_id);
|
GridCoord1D location = _world->get_location_by_agent(agent_id);
|
||||||
vector<AgentID> *cell_mates = _world->get_location_contents(location);
|
vector<AgentID> *cell_mates = _world->get_location_contents(location);
|
||||||
|
|
||||||
if (cell_mates->size() > 1) {
|
if (cell_mates->size() > 1) {
|
||||||
std::uniform_int_distribution<int> dist(0, cell_mates->size() - 1);
|
std::uniform_int_distribution<int> dist(0, (int)cell_mates->size() - 1);
|
||||||
AgentID other_agent_id = cell_mates->at(dist(*rng));
|
AgentID other_agent_id = cell_mates->at(dist(*rng));
|
||||||
auto other_agent = _model->get_agent_by_id(other_agent_id);
|
auto other_agent = _model->get_agent_by_id(other_agent_id);
|
||||||
|
|
||||||
console->trace("Agent {} giving unit of wealth to agent {}", agent_id,
|
console->trace("Agent {} giving unit of wealth to agent {}", agent_id, other_agent_id);
|
||||||
other_agent_id);
|
|
||||||
other_agent->_agent_wealth += 1;
|
other_agent->_agent_wealth += 1;
|
||||||
_agent_wealth -= 1;
|
_agent_wealth -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BoltzmannWealthModel1D::BoltzmannWealthModel1D(unsigned int number_agents,
|
BoltzmannWealthModel1D::BoltzmannWealthModel1D(unsigned int number_agents, unsigned int length_x) {
|
||||||
unsigned int length_x) {
|
|
||||||
_world = new MultiGrid1D(length_x, true);
|
_world = new MultiGrid1D(length_x, true);
|
||||||
_sched = new RandomScheduler(this, rng);
|
_sched = new RandomScheduler(this, rng);
|
||||||
|
|
||||||
@@ -120,23 +112,20 @@ BoltzmannWealthModel1D::BoltzmannWealthModel1D(unsigned int number_agents,
|
|||||||
MoneyAgent1D::set_world(_world);
|
MoneyAgent1D::set_world(_world);
|
||||||
MoneyAgent1D::set_model(this);
|
MoneyAgent1D::set_model(this);
|
||||||
|
|
||||||
std::uniform_int_distribution<int> dist(0, length_x - 1);
|
std::uniform_int_distribution<int> dist(0, (int)length_x - 1);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < number_agents; i++) {
|
for (unsigned int i = 0; i < number_agents; i++) {
|
||||||
MoneyAgent1D *new_agent = new MoneyAgent1D();
|
auto *new_agent = new MoneyAgent1D();
|
||||||
|
|
||||||
_agent_list.insert(pair<AgentID, MoneyAgent1D *>(
|
_agent_list.insert(pair<AgentID, MoneyAgent1D *>(new_agent->get_agent_id(), new_agent));
|
||||||
new_agent->get_agent_id(), new_agent));
|
|
||||||
_sched->add_agent(new_agent->get_agent_id());
|
_sched->add_agent(new_agent->get_agent_id());
|
||||||
_world->add_agent(new_agent->get_agent_id(), GridCoord1D(dist(*rng)));
|
_world->add_agent(new_agent->get_agent_id(), GridCoord1D(dist(*rng)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BoltzmannWealthModel1D::~BoltzmannWealthModel1D() {
|
BoltzmannWealthModel1D::~BoltzmannWealthModel1D() {
|
||||||
for (auto agent_pair = _agent_list.begin(); agent_pair != _agent_list.end();
|
for (auto & agent_pair : _agent_list)
|
||||||
agent_pair++) {
|
delete agent_pair.second;
|
||||||
delete agent_pair->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _sched;
|
delete _sched;
|
||||||
delete _world;
|
delete _world;
|
||||||
@@ -161,29 +150,19 @@ int main(int argc, char **argv) {
|
|||||||
string ident = "boltzmann1d";
|
string ident = "boltzmann1d";
|
||||||
CLI::App app{ident};
|
CLI::App app{ident};
|
||||||
string log_level_option = "info";
|
string log_level_option = "info";
|
||||||
unsigned int x_size = 16, agent_count = x_size, max_steps = 100,
|
unsigned int x_size = 16, agent_count = x_size, max_steps = 100, initial_seed = 42;
|
||||||
initial_seed = 42;
|
|
||||||
|
|
||||||
app.add_option("-c", agent_count, "Set the number of agents")
|
app.add_option("-c", agent_count, "Set the number of agents")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::PositiveNumber);
|
app.add_option("-l", log_level_option, "Set the logging level")->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
||||||
app.add_option("-l", log_level_option, "Set the logging level")
|
app.add_option("-n", max_steps, "Set the number of steps to run the model")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
app.add_option("-s", initial_seed, "Set the initial seed")->check(CLI::Number);
|
||||||
app.add_option("-n", max_steps, "Set the number of steps to run the model")
|
app.add_option("-x", x_size, "Set the number of columns")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::PositiveNumber);
|
|
||||||
app.add_option("-s", initial_seed, "Set the initial seed")
|
|
||||||
->check(CLI::Number);
|
|
||||||
app.add_option("-x", x_size, "Set the number of colums")
|
|
||||||
->check(CLI::PositiveNumber);
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
console = spdlog::stdout_color_st(ident);
|
console = spdlog::stdout_color_st(ident);
|
||||||
console->set_level(spdlog::level::from_str(log_level_option));
|
console->set_level(spdlog::level::from_str(log_level_option));
|
||||||
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING,
|
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING, log_level_option);
|
||||||
log_level_option);
|
console->info("Starting Boltzmann Wealth Model with {} agents on a {}-unit grid for {} steps",agent_count, x_size, max_steps);
|
||||||
console->info(
|
|
||||||
"Starting Boltzmann Wealth Model with {} agents on a {}-unit grid for "
|
|
||||||
"{} steps",
|
|
||||||
agent_count, x_size, max_steps);
|
|
||||||
|
|
||||||
rng = make_shared<mt19937>(initial_seed);
|
rng = make_shared<mt19937>(initial_seed);
|
||||||
BoltzmannWealthModel1D model(agent_count, x_size);
|
BoltzmannWealthModel1D model(agent_count, x_size);
|
||||||
@@ -193,6 +172,5 @@ int main(int argc, char **argv) {
|
|||||||
console->trace("Initiating model step {}", i);
|
console->trace("Initiating model step {}", i);
|
||||||
model.step();
|
model.step();
|
||||||
}
|
}
|
||||||
console->info(
|
console->info("Boltzmann Wealth Model simulation complete, requiring {} seconds", sw);
|
||||||
"Boltzman Wealth Model simulation complete, requiring {} seconds", sw);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,17 +24,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef BOLTZMAN1D_H
|
#ifndef BOLTZMANN1D_H
|
||||||
#define BOLTZMAN1D_H
|
#define BOLTZMANN1D_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
#include <kami/multigrid1d.h>
|
#include <kami/multigrid1d.h>
|
||||||
#include <kami/random.h>
|
#include <kami/random.h>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
using namespace kami;
|
using namespace kami;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -43,7 +42,7 @@ using namespace std;
|
|||||||
* A sample agent for a one-dimensional Boltzmann wealth model
|
* A sample agent for a one-dimensional Boltzmann wealth model
|
||||||
*/
|
*/
|
||||||
class MoneyAgent1D : public Agent {
|
class MoneyAgent1D : public Agent {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create the agent
|
* Create the agent
|
||||||
*/
|
*/
|
||||||
@@ -52,7 +51,7 @@ class MoneyAgent1D : public Agent {
|
|||||||
/**
|
/**
|
||||||
* Execute a single time-step for the agent
|
* Execute a single time-step for the agent
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give the agent a reference copy of the domain it is expected to work in
|
* Give the agent a reference copy of the domain it is expected to work in
|
||||||
@@ -69,22 +68,12 @@ class MoneyAgent1D : public Agent {
|
|||||||
*/
|
*/
|
||||||
void move_agent();
|
void move_agent();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the wealth of the agent
|
|
||||||
*/
|
|
||||||
int get_wealth();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the wealth of the agent
|
|
||||||
*/
|
|
||||||
void set_wealth(int wealth);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give money to a random agent
|
* Give money to a random agent
|
||||||
*/
|
*/
|
||||||
void give_money();
|
void give_money();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static MultiGrid1D *_world;
|
static MultiGrid1D *_world;
|
||||||
static BoltzmannWealthModel1D *_model;
|
static BoltzmannWealthModel1D *_model;
|
||||||
int _step_counter;
|
int _step_counter;
|
||||||
@@ -95,16 +84,15 @@ class MoneyAgent1D : public Agent {
|
|||||||
* The one-dimensional Boltzmann wealth model
|
* The one-dimensional Boltzmann wealth model
|
||||||
*/
|
*/
|
||||||
class BoltzmannWealthModel1D : public Model {
|
class BoltzmannWealthModel1D : public Model {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create an instance of the one-dimensional Boltzman wealth model.
|
* Create an instance of the one-dimensional Boltzmann wealth model.
|
||||||
*
|
*
|
||||||
* @param[in] number_agents the number of agents to assign to the model.
|
* @param[in] number_agents the number of agents to assign to the model.
|
||||||
* @param[in] length_x the length of the one-dimensional world the agents
|
* @param[in] length_x the length of the one-dimensional world the agents
|
||||||
* occupy.
|
* occupy.
|
||||||
*/
|
*/
|
||||||
BoltzmannWealthModel1D(unsigned int number_agents = 10,
|
explicit BoltzmannWealthModel1D(unsigned int number_agents = 10, unsigned int length_x = 10);
|
||||||
unsigned int length_x = 10);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the instance
|
* Destroy the instance
|
||||||
@@ -114,27 +102,27 @@ class BoltzmannWealthModel1D : public Model {
|
|||||||
/**
|
/**
|
||||||
* Execute a single time-step for the model.
|
* Execute a single time-step for the model.
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a number of time-steps for the model.
|
* Execute a number of time-steps for the model.
|
||||||
*
|
*
|
||||||
* @param[in] n the number of steps to execute.
|
* @param[in] n the number of steps to execute.
|
||||||
*/
|
*/
|
||||||
void run(unsigned int n);
|
void run(unsigned int n) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the MoneyAgent instance associated with the given `AgentID`
|
* Get the MoneyAgent instance associated with the given `AgentID`
|
||||||
*
|
*
|
||||||
* @returns an pointer to the `MoneyAgent` that was requested.
|
* @returns an pointer to the `MoneyAgent` that was requested.
|
||||||
*/
|
*/
|
||||||
MoneyAgent1D *get_agent_by_id(AgentID agent_id) const;
|
[[nodiscard]] MoneyAgent1D *get_agent_by_id(AgentID agent_id) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<AgentID, MoneyAgent1D *> _agent_list;
|
map<AgentID, MoneyAgent1D *> _agent_list;
|
||||||
RandomScheduler *_sched;
|
RandomScheduler *_sched;
|
||||||
MultiGrid1D *_world;
|
MultiGrid1D *_world;
|
||||||
unsigned int _step_count;
|
unsigned int _step_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BOLTZMAN1D_H
|
#endif // BOLTZMANN1D_H
|
||||||
|
|||||||
@@ -23,23 +23,21 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/grid2d.h>
|
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
#include <kami/multigrid1d.h>
|
#include <kami/multigrid2d.h>
|
||||||
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <spdlog/stopwatch.h>
|
#include <spdlog/stopwatch.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
#include <CLI/Config.hpp>
|
#include <CLI/Config.hpp>
|
||||||
#include <CLI/Formatter.hpp>
|
#include <CLI/Formatter.hpp>
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <random>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "boltzmann2d.h"
|
#include "boltzmann2d.h"
|
||||||
|
|
||||||
@@ -53,14 +51,14 @@ shared_ptr<mt19937> rng = nullptr;
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<AgentID> : fmt::formatter<string> {
|
struct fmt::formatter<AgentID> : fmt::formatter<string> {
|
||||||
auto format(AgentID agent_id, format_context &ctx) {
|
[[maybe_unused]] static auto format(AgentID agent_id, format_context &ctx) {
|
||||||
return format_to(ctx.out(), "{}", agent_id.to_string());
|
return format_to(ctx.out(), "{}", agent_id.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<GridCoord2D> : fmt::formatter<string> {
|
struct fmt::formatter<GridCoord2D> : fmt::formatter<string> {
|
||||||
auto format(GridCoord2D coord, format_context &ctx) {
|
[[maybe_unused]] static auto format(const GridCoord2D& coord, format_context &ctx) {
|
||||||
return format_to(ctx.out(), "{}", coord.to_string());
|
return format_to(ctx.out(), "{}", coord.to_string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -82,7 +80,7 @@ void MoneyAgent2D::move_agent() {
|
|||||||
console->trace("Entering move_agent");
|
console->trace("Entering move_agent");
|
||||||
auto agent_id = get_agent_id();
|
auto agent_id = get_agent_id();
|
||||||
auto move_list = _world->get_neighborhood(agent_id, GridNeighborhoodType::Moore, false);
|
auto move_list = _world->get_neighborhood(agent_id, GridNeighborhoodType::Moore, false);
|
||||||
std::uniform_int_distribution<int> dist(0, move_list.size() - 1);
|
std::uniform_int_distribution<int> dist(0, (int) move_list.size() - 1);
|
||||||
auto new_location = move_list[dist(*rng)];
|
auto new_location = move_list[dist(*rng)];
|
||||||
|
|
||||||
console->trace("Moving Agent {} to location {}", agent_id, new_location);
|
console->trace("Moving Agent {} to location {}", agent_id, new_location);
|
||||||
@@ -90,31 +88,23 @@ void MoneyAgent2D::move_agent() {
|
|||||||
console->trace("Exiting move_agent");
|
console->trace("Exiting move_agent");
|
||||||
}
|
}
|
||||||
|
|
||||||
int MoneyAgent2D::get_wealth() { return _agent_wealth; }
|
|
||||||
|
|
||||||
void MoneyAgent2D::set_wealth(int newWealth) { _agent_wealth = newWealth; }
|
|
||||||
|
|
||||||
void MoneyAgent2D::give_money() {
|
void MoneyAgent2D::give_money() {
|
||||||
AgentID agent_id = get_agent_id();
|
AgentID agent_id = get_agent_id();
|
||||||
GridCoord2D location = _world->get_location_by_agent(agent_id);
|
GridCoord2D location = _world->get_location_by_agent(agent_id);
|
||||||
vector<AgentID> *cell_mates = _world->get_location_contents(location);
|
vector<AgentID> *cell_mates = _world->get_location_contents(location);
|
||||||
|
|
||||||
if (cell_mates->size() > 1) {
|
if (cell_mates->size() > 1) {
|
||||||
std::uniform_int_distribution<int> dist(0, cell_mates->size() - 1);
|
std::uniform_int_distribution<int> dist(0, (int)cell_mates->size() - 1);
|
||||||
AgentID other_agent_id = cell_mates->at(dist(*rng));
|
AgentID other_agent_id = cell_mates->at(dist(*rng));
|
||||||
auto other_agent = _model->get_agent_by_id(other_agent_id);
|
auto other_agent = _model->get_agent_by_id(other_agent_id);
|
||||||
|
|
||||||
console->trace("Agent {} giving unit of wealth to agent {}", agent_id,
|
console->trace("Agent {} giving unit of wealth to agent {}", agent_id, other_agent_id);
|
||||||
other_agent_id);
|
|
||||||
other_agent->_agent_wealth += 1;
|
other_agent->_agent_wealth += 1;
|
||||||
_agent_wealth -= 1;
|
_agent_wealth -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BoltzmannWealthModel2D::BoltzmannWealthModel2D(unsigned int number_agents,
|
BoltzmannWealthModel2D::BoltzmannWealthModel2D(unsigned int number_agents, unsigned int length_x, unsigned int length_y, unsigned int new_seed) {
|
||||||
unsigned int length_x,
|
|
||||||
unsigned int length_y,
|
|
||||||
unsigned int new_seed) {
|
|
||||||
rng = make_shared<mt19937>();
|
rng = make_shared<mt19937>();
|
||||||
rng->seed(new_seed);
|
rng->seed(new_seed);
|
||||||
|
|
||||||
@@ -127,25 +117,21 @@ BoltzmannWealthModel2D::BoltzmannWealthModel2D(unsigned int number_agents,
|
|||||||
MoneyAgent2D::set_world(_world);
|
MoneyAgent2D::set_world(_world);
|
||||||
MoneyAgent2D::set_model(this);
|
MoneyAgent2D::set_model(this);
|
||||||
|
|
||||||
std::uniform_int_distribution<int> dist_x(0, length_x - 1);
|
std::uniform_int_distribution<int> dist_x(0, (int)length_x - 1);
|
||||||
std::uniform_int_distribution<int> dist_y(0, length_y - 1);
|
std::uniform_int_distribution<int> dist_y(0, (int)length_y - 1);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < number_agents; i++) {
|
for (unsigned int i = 0; i < number_agents; i++) {
|
||||||
MoneyAgent2D *new_agent = new MoneyAgent2D();
|
auto *new_agent = new MoneyAgent2D();
|
||||||
|
|
||||||
_agent_list.insert(pair<AgentID, MoneyAgent2D *>(
|
_agent_list.insert(pair<AgentID, MoneyAgent2D *>(new_agent->get_agent_id(), new_agent));
|
||||||
new_agent->get_agent_id(), new_agent));
|
|
||||||
_sched->add_agent(new_agent->get_agent_id());
|
_sched->add_agent(new_agent->get_agent_id());
|
||||||
_world->add_agent(new_agent->get_agent_id(),
|
_world->add_agent(new_agent->get_agent_id(), GridCoord2D(dist_x(*rng), dist_x(*rng)));
|
||||||
GridCoord2D(dist_x(*rng), dist_x(*rng)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BoltzmannWealthModel2D::~BoltzmannWealthModel2D() {
|
BoltzmannWealthModel2D::~BoltzmannWealthModel2D() {
|
||||||
for (auto agent_pair = _agent_list.begin(); agent_pair != _agent_list.end();
|
for (auto & agent_pair : _agent_list)
|
||||||
agent_pair++) {
|
delete agent_pair.second;
|
||||||
delete agent_pair->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete _sched;
|
delete _sched;
|
||||||
delete _world;
|
delete _world;
|
||||||
@@ -169,31 +155,20 @@ int main(int argc, char **argv) {
|
|||||||
std::string ident = "boltzmann2d";
|
std::string ident = "boltzmann2d";
|
||||||
CLI::App app{ident};
|
CLI::App app{ident};
|
||||||
string log_level_option = "info";
|
string log_level_option = "info";
|
||||||
unsigned int x_size = 16, y_size = 16, agent_count = x_size * y_size,
|
unsigned int x_size = 16, y_size = 16, agent_count = x_size * y_size, max_steps = 100, initial_seed = 42;
|
||||||
max_steps = 100, initial_seed = 42;
|
|
||||||
|
|
||||||
app.add_option("-c", agent_count, "Set the number of agents")
|
app.add_option("-c", agent_count, "Set the number of agents")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::PositiveNumber);
|
app.add_option("-l", log_level_option, "Set the logging level")->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
||||||
app.add_option("-l", log_level_option, "Set the logging level")
|
app.add_option("-n", max_steps, "Set the number of steps to run the model")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
app.add_option("-s", initial_seed, "Set the initial seed")->check(CLI::Number);
|
||||||
app.add_option("-n", max_steps, "Set the number of steps to run the model")
|
app.add_option("-x", x_size, "Set the number of columns")->check(CLI::PositiveNumber);
|
||||||
->check(CLI::PositiveNumber);
|
app.add_option("-y", y_size, "Set the number of rows")->check(CLI::PositiveNumber);
|
||||||
app.add_option("-s", initial_seed, "Set the initial seed")
|
|
||||||
->check(CLI::Number);
|
|
||||||
app.add_option("-x", x_size, "Set the number of colums")
|
|
||||||
->check(CLI::PositiveNumber);
|
|
||||||
app.add_option("-y", y_size, "Set the number of rows")
|
|
||||||
->check(CLI::PositiveNumber);
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
console = spdlog::stdout_color_st(ident);
|
console = spdlog::stdout_color_st(ident);
|
||||||
console->set_level(spdlog::level::from_str(log_level_option));
|
console->set_level(spdlog::level::from_str(log_level_option));
|
||||||
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING,
|
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING, log_level_option);
|
||||||
log_level_option);
|
console->info("Starting Boltzmann Wealth Model with {} agents on a {}x{}-unit grid for {} steps", agent_count, x_size, y_size, max_steps);
|
||||||
console->info(
|
|
||||||
"Starting Boltzmann Wealth Model with {} agents on a {}x{}-unit grid "
|
|
||||||
"for {} steps",
|
|
||||||
agent_count, x_size, y_size, max_steps);
|
|
||||||
|
|
||||||
BoltzmannWealthModel2D model(agent_count, x_size, y_size, initial_seed);
|
BoltzmannWealthModel2D model(agent_count, x_size, y_size, initial_seed);
|
||||||
|
|
||||||
@@ -202,6 +177,5 @@ int main(int argc, char **argv) {
|
|||||||
console->trace("Initiating model step {}", i);
|
console->trace("Initiating model step {}", i);
|
||||||
model.step();
|
model.step();
|
||||||
}
|
}
|
||||||
console->info(
|
console->info("Boltzmann Wealth Model simulation complete, requiring {} seconds", sw);
|
||||||
"Boltzman Wealth Model simulation complete, requiring {} seconds", sw);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef BOLTZMAN2D_H
|
#ifndef BOLTZMANN2D_H
|
||||||
#define BOLTZMAN2D_H
|
#define BOLTZMANN2D_H
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
@@ -42,7 +42,7 @@ using namespace std;
|
|||||||
* A sample agent for a two-dimensional Boltzmann wealth model
|
* A sample agent for a two-dimensional Boltzmann wealth model
|
||||||
*/
|
*/
|
||||||
class MoneyAgent2D : public Agent {
|
class MoneyAgent2D : public Agent {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create the agent
|
* Create the agent
|
||||||
*/
|
*/
|
||||||
@@ -51,7 +51,7 @@ class MoneyAgent2D : public Agent {
|
|||||||
/**
|
/**
|
||||||
* Execute a single time-step for the agent
|
* Execute a single time-step for the agent
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give the agent a reference copy of the domain it is expected to work in
|
* Give the agent a reference copy of the domain it is expected to work in
|
||||||
@@ -68,22 +68,12 @@ class MoneyAgent2D : public Agent {
|
|||||||
*/
|
*/
|
||||||
void move_agent();
|
void move_agent();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the wealth of the agent
|
|
||||||
*/
|
|
||||||
int get_wealth();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the wealth of the agent
|
|
||||||
*/
|
|
||||||
void set_wealth(int wealth);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give money to a random agent
|
* Give money to a random agent
|
||||||
*/
|
*/
|
||||||
void give_money();
|
void give_money();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static MultiGrid2D *_world;
|
static MultiGrid2D *_world;
|
||||||
static BoltzmannWealthModel2D *_model;
|
static BoltzmannWealthModel2D *_model;
|
||||||
int _step_counter;
|
int _step_counter;
|
||||||
@@ -94,9 +84,9 @@ class MoneyAgent2D : public Agent {
|
|||||||
* The two-dimensional Boltzmann wealth model
|
* The two-dimensional Boltzmann wealth model
|
||||||
*/
|
*/
|
||||||
class BoltzmannWealthModel2D : public Model {
|
class BoltzmannWealthModel2D : public Model {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create an instance of the two-dimensional Boltzman wealth model.
|
* Create an instance of the two-dimensional Boltzmann wealth model.
|
||||||
*
|
*
|
||||||
* @param[in] number_agents the number of agents to assign to the model.
|
* @param[in] number_agents the number of agents to assign to the model.
|
||||||
* @param[in] length_x the length of the two-dimensional world the agents
|
* @param[in] length_x the length of the two-dimensional world the agents
|
||||||
@@ -106,10 +96,7 @@ class BoltzmannWealthModel2D : public Model {
|
|||||||
* @param[in] new_seed the initial seed used for the random number
|
* @param[in] new_seed the initial seed used for the random number
|
||||||
* generator.
|
* generator.
|
||||||
*/
|
*/
|
||||||
BoltzmannWealthModel2D(unsigned int number_agents = 10,
|
explicit BoltzmannWealthModel2D(unsigned int number_agents = 10, unsigned int length_x = 10, unsigned int length_y = 10, unsigned int new_seed = 42);
|
||||||
unsigned int length_x = 10,
|
|
||||||
unsigned int length_y = 10,
|
|
||||||
unsigned int new_seed = 42);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the instance
|
* Destroy the instance
|
||||||
@@ -119,32 +106,27 @@ class BoltzmannWealthModel2D : public Model {
|
|||||||
/**
|
/**
|
||||||
* Execute a single time-step for the model.
|
* Execute a single time-step for the model.
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a number of time-steps for the model.
|
* Execute a number of time-steps for the model.
|
||||||
*
|
*
|
||||||
* @param[in] n the number of steps to execute.
|
* @param[in] n the number of steps to execute.
|
||||||
*/
|
*/
|
||||||
void run(unsigned int n);
|
void run(unsigned int n) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the seed used to initialize the model.
|
|
||||||
*/
|
|
||||||
int get_seed() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the MoneyAgent2D instance associated with the given `AgentID`
|
* Get the MoneyAgent2D instance associated with the given `AgentID`
|
||||||
*
|
*
|
||||||
* @returns an pointer to the `MoneyAgent2D` that was requested.
|
* @returns an pointer to the `MoneyAgent2D` that was requested.
|
||||||
*/
|
*/
|
||||||
MoneyAgent2D *get_agent_by_id(AgentID agent_id) const;
|
[[nodiscard]] MoneyAgent2D *get_agent_by_id(AgentID agent_id) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
map<AgentID, MoneyAgent2D *> _agent_list;
|
map<AgentID, MoneyAgent2D *> _agent_list;
|
||||||
RandomScheduler *_sched;
|
RandomScheduler *_sched;
|
||||||
MultiGrid2D *_world;
|
MultiGrid2D *_world;
|
||||||
unsigned int _step_count;
|
unsigned int _step_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BOLTZMAN2D_H
|
#endif // BOLTZMANN2D_H
|
||||||
|
|||||||
@@ -27,11 +27,12 @@
|
|||||||
#ifndef KAMI_AGENT_H
|
#ifndef KAMI_AGENT_H
|
||||||
#define KAMI_AGENT_H
|
#define KAMI_AGENT_H
|
||||||
|
|
||||||
#include <kami/kami.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <kami/kami.h>
|
||||||
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,77 +44,77 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* @see Agent
|
* @see Agent
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT AgentID {
|
class LIBKAMI_EXPORT AgentID {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructs a new unique identifier.
|
* Constructs a new unique identifier.
|
||||||
*/
|
*/
|
||||||
AgentID() : _id(_id_next++){};
|
AgentID() : _id(_id_next++){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the identifier to a human-readable string.
|
* Convert the identifier to a human-readable string.
|
||||||
*
|
*
|
||||||
* @return a human-readable form of the `AgentID` as `std::string`.
|
* @return a human-readable form of the `AgentID` as `std::string`.
|
||||||
*/
|
*/
|
||||||
std::string to_string() const { return std::to_string(_id); }
|
[[nodiscard]] std::string to_string() const { return std::to_string(_id); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two `AgentID` instances are equal.
|
* Test if two `AgentID` instances are equal.
|
||||||
*
|
*
|
||||||
* @param lhs is the left-hand side of the equality test.
|
* @param lhs is the left-hand side of the equality test.
|
||||||
* @param rhs is the right-hand side of the equality test.
|
* @param rhs is the right-hand side of the equality test.
|
||||||
* @return true is they are equal and false if not.
|
* @return true is they are equal and false if not.
|
||||||
*/
|
*/
|
||||||
friend bool operator==(const AgentID &lhs, const AgentID &rhs);
|
friend bool operator==(const AgentID &lhs, const AgentID &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two `AgentID` instances are not equal.
|
* Test if two `AgentID` instances are not equal.
|
||||||
*
|
*
|
||||||
* @param lhs is the left-hand side of the equality test.
|
* @param lhs is the left-hand side of the equality test.
|
||||||
* @param rhs is the right-hand side of the equality test.
|
* @param rhs is the right-hand side of the equality test.
|
||||||
* @return true is they are not equal and false if they are.
|
* @return true is they are not equal and false if they are.
|
||||||
*/
|
*/
|
||||||
friend bool operator!=(const AgentID &lhs, const AgentID &rhs);
|
friend bool operator!=(const AgentID &lhs, const AgentID &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if one AgentID is less than another.
|
* Test if one AgentID is less than another.
|
||||||
*
|
*
|
||||||
* Due to the way AgentID instances are used internally,
|
* Due to the way AgentID instances are used internally,
|
||||||
* the AgentID must be orderable. The `<` operator provides a
|
* the AgentID must be orderable. The `<` operator provides a
|
||||||
* basic ordering sufficient for `std::map`.
|
* basic ordering sufficient for `std::map`.
|
||||||
*
|
*
|
||||||
* @param lhs is the left-hand side of the ordering test.
|
* @param lhs is the left-hand side of the ordering test.
|
||||||
* @param rhs is the right-hand side of the ordering test.
|
* @param rhs is the right-hand side of the ordering test.
|
||||||
* @return true if `lhs` is "less than" `rhs` as determined by the
|
* @return true if `lhs` is "less than" `rhs` as determined by the
|
||||||
* underlying implementation of the `AgentID`.
|
* underlying implementation of the `AgentID`.
|
||||||
*/
|
*/
|
||||||
friend bool operator<(const AgentID &lhs, const AgentID &rhs);
|
friend bool operator<(const AgentID &lhs, const AgentID &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output an AgentID to the specified output stream
|
* Output an AgentID to the specified output stream
|
||||||
*
|
*
|
||||||
* The form of the output will be the same as that produced by the
|
* The form of the output will be the same as that produced by the
|
||||||
* `to_string()` member function.
|
* `to_string()` member function.
|
||||||
*
|
*
|
||||||
* @param lhs is the stream to output the `AgentID` to
|
* @param lhs is the stream to output the `AgentID` to
|
||||||
* @param rhs is the `AgentID` to output
|
* @param rhs is the `AgentID` to output
|
||||||
* @return the output stream for reuse
|
* @return the output stream for reuse
|
||||||
*/
|
*/
|
||||||
friend std::ostream &operator<<(std::ostream &lhs, const AgentID &rhs);
|
friend std::ostream &operator<<(std::ostream &lhs, const AgentID &rhs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static long long _id_next = 1;
|
inline static long long _id_next = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier is a `long long`.
|
* The unique identifier is a `long long`.
|
||||||
*
|
*
|
||||||
* The unique identifier is an unsigned integer that increments
|
* The unique identifier is an unsigned integer that increments
|
||||||
* monotonically with each new `AgentID` instantiated. This is
|
* monotonically with each new `AgentID` instantiated. This is
|
||||||
* substantially faster than other potential identifiers, such
|
* substantially faster than other potential identifiers, such
|
||||||
* as MD5 hashes or UUID objects.
|
* as MD5 hashes or UUID objects.
|
||||||
*/
|
*/
|
||||||
long long _id;
|
long long _id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A superclass for all agents.
|
* A superclass for all agents.
|
||||||
@@ -124,58 +125,58 @@ class LIBKAMI_EXPORT AgentID {
|
|||||||
*
|
*
|
||||||
* @see `StagedAgent`
|
* @see `StagedAgent`
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Agent {
|
class LIBKAMI_EXPORT Agent {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Get the `Agent`'s `AgentID`.
|
* Get the `Agent`'s `AgentID`.
|
||||||
*
|
*
|
||||||
* @return the `AgentID`
|
* @return the `AgentID`
|
||||||
*/
|
*/
|
||||||
AgentID get_agent_id() const;
|
[[nodiscard]] AgentID get_agent_id() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a time-step for the agent
|
* Execute a time-step for the agent
|
||||||
*
|
*
|
||||||
* This function should step the agent instance. Any activities that the
|
* This function should step the agent instance. Any activities that the
|
||||||
* agent should perform as part of its time step should be in this function.
|
* agent should perform as part of its time step should be in this function.
|
||||||
*/
|
*/
|
||||||
virtual void step() = 0;
|
virtual void step() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare if two `Agent`s are the same `Agent`.
|
* Compare if two `Agent`s are the same `Agent`.
|
||||||
*
|
*
|
||||||
* @param lhs is the left-hand side of the equality test.
|
* @param lhs is the left-hand side of the equality test.
|
||||||
* @param rhs is the right-hand side of the equality test.
|
* @param rhs is the right-hand side of the equality test.
|
||||||
* @return true is they are equal and false if not.
|
* @return true is they are equal and false if not.
|
||||||
*
|
*
|
||||||
* @note This does not compare that two Agent instances are
|
* @note This does not compare that two Agent instances are
|
||||||
* identical. Accordingly, this can be used to compare two instances
|
* identical. Accordingly, this can be used to compare two instances
|
||||||
* of the same Agent at different points in its time stream.
|
* of the same Agent at different points in its time stream.
|
||||||
*
|
*
|
||||||
* Subclasses of Agent may chose to extend this operator to tighten
|
* Subclasses of Agent may chose to extend this operator to tighten
|
||||||
* the restrictioons on the comparison.
|
* the restrictions on the comparison.
|
||||||
*/
|
*/
|
||||||
friend bool operator==(const Agent &lhs, const Agent &rhs);
|
friend bool operator==(const Agent &lhs, const Agent &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare if two `Agent`s are not the same `Agent`.
|
* Compare if two `Agent`s are not the same `Agent`.
|
||||||
*
|
*
|
||||||
* @param lhs is the left-hand side of the equality test.
|
* @param lhs is the left-hand side of the equality test.
|
||||||
* @param rhs is the right-hand side of the equality test.
|
* @param rhs is the right-hand side of the equality test.
|
||||||
* @return true is they are not equal and false if they are.
|
* @return true is they are not equal and false if they are.
|
||||||
*
|
*
|
||||||
* @note This does not compare that two Agent instances are
|
* @note This does not compare that two Agent instances are
|
||||||
* identical. Accordingly, this can be used to compare two instances
|
* identical. Accordingly, this can be used to compare two instances
|
||||||
* of the same `Agent` at different points in its time stream.
|
* of the same `Agent` at different points in its time stream.
|
||||||
*
|
*
|
||||||
* Subclasses of `Agent` may chose to extend this operator to tighten
|
* Subclasses of `Agent` may chose to extend this operator to tighten
|
||||||
* the restrictioons on the comparison.
|
* the restrictions on the comparison.
|
||||||
*/
|
*/
|
||||||
friend bool operator!=(const Agent &lhs, const Agent &rhs);
|
friend bool operator!=(const Agent &lhs, const Agent &rhs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const AgentID _agent_id;
|
const AgentID _agent_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A superclass for all staged agents.
|
* A superclass for all staged agents.
|
||||||
@@ -189,17 +190,17 @@ class LIBKAMI_EXPORT Agent {
|
|||||||
*
|
*
|
||||||
* `StagedAgents` must implement both the `step()` and `advance()` functions.
|
* `StagedAgents` must implement both the `step()` and `advance()` functions.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT StagedAgent : public Agent {
|
class LIBKAMI_EXPORT StagedAgent : public Agent {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Post-step advance the agent
|
* Post-step advance the agent
|
||||||
*
|
*
|
||||||
* This method should be called after `step()`. Any updates or cleanups to
|
* This method should be called after `step()`. Any updates or cleanups to
|
||||||
* the agent that must happen for the `StagedAgent` to complete its step must
|
* the agent that must happen for the `StagedAgent` to complete its step must
|
||||||
* happen here.
|
* happen here.
|
||||||
*/
|
*/
|
||||||
virtual void advance() = 0;
|
virtual void advance() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,10 @@
|
|||||||
#ifndef KAMI_DOMAIN_H
|
#ifndef KAMI_DOMAIN_H
|
||||||
#define KAMI_DOMAIN_H
|
#define KAMI_DOMAIN_H
|
||||||
|
|
||||||
#include <kami/kami.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <kami/kami.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +38,7 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* Implementations of virtual environments are expected to subclass `Domain`.
|
* Implementations of virtual environments are expected to subclass `Domain`.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Domain {};
|
class LIBKAMI_EXPORT Domain {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a coordinate system for each `Domain`.
|
* Provides a coordinate system for each `Domain`.
|
||||||
@@ -52,27 +52,27 @@ class LIBKAMI_EXPORT Domain {};
|
|||||||
*
|
*
|
||||||
* @see GridCoord
|
* @see GridCoord
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Coord {
|
class LIBKAMI_EXPORT Coord {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Convert the coordinate to a human-readable string.
|
* Convert the coordinate to a human-readable string.
|
||||||
*
|
*
|
||||||
* @return a human-readable form of the `Coord` as `std::string`.
|
* @return a human-readable form of the `Coord` as `std::string`.
|
||||||
*/
|
*/
|
||||||
virtual std::string to_string() const = 0;
|
[[nodiscard]] virtual std::string to_string() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output a `Coord` to the specified output stream
|
* Output a `Coord` to the specified output stream
|
||||||
*
|
*
|
||||||
* The form of the output will be the same as that produced by the
|
* The form of the output will be the same as that produced by the
|
||||||
* `to_string()` member function.
|
* `to_string()` member function.
|
||||||
*
|
*
|
||||||
* @param lhs is the stream to output the `Coord` to
|
* @param lhs is the stream to output the `Coord` to
|
||||||
* @param rhs is the `Coord` to output
|
* @param rhs is the `Coord` to output
|
||||||
* @return the output stream for reuse
|
* @return the output stream for reuse
|
||||||
*/
|
*/
|
||||||
friend std::ostream &operator<<(std::ostream &lhs, const Coord &rhs);
|
friend std::ostream &operator<<(std::ostream &lhs, const Coord &rhs);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@
|
|||||||
#ifndef KAMI_GRID_H
|
#ifndef KAMI_GRID_H
|
||||||
#define KAMI_GRID_H
|
#define KAMI_GRID_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <kami/domain.h>
|
#include <kami/domain.h>
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,47 +42,47 @@ namespace kami {
|
|||||||
* distinction between those neighborhoods that include those cells touching on
|
* distinction between those neighborhoods that include those cells touching on
|
||||||
* the corners or diagonally and those neighborhoods that do not.
|
* the corners or diagonally and those neighborhoods that do not.
|
||||||
*/
|
*/
|
||||||
enum class GridNeighborhoodType {
|
enum class GridNeighborhoodType {
|
||||||
/**
|
/**
|
||||||
* @brief Moore neighborhood
|
* @brief Moore neighborhood
|
||||||
*
|
*
|
||||||
* @details Moore neighborhood types include diagonally-adjacent cells as
|
* @details Moore neighborhood types include diagonally-adjacent cells as
|
||||||
* neighbors.
|
* neighbors.
|
||||||
*/
|
*/
|
||||||
Moore,
|
Moore [[maybe_unused]],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Von Neumann neighborhood
|
* @brief Von Neumann neighborhood
|
||||||
*
|
*
|
||||||
* @details Von Neumann neighborhood types do not include
|
* @details Von Neumann neighborhood types do not include
|
||||||
* diagonally-adjacent cells as neighbors.
|
* diagonally-adjacent cells as neighbors.
|
||||||
*/
|
*/
|
||||||
VonNeumann
|
VonNeumann [[maybe_unused]]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Distance types for orthogonal grid domains
|
* @brief Distance types for orthogonal grid domains
|
||||||
*/
|
*/
|
||||||
enum class GridDistanceType {
|
enum class GridDistanceType {
|
||||||
/**
|
/**
|
||||||
* @brief Euclidean distance.
|
* @brief Euclidean distance.
|
||||||
*
|
*
|
||||||
* @details The Euclidean distance is the length of the line segment
|
* @details The Euclidean distance is the length of the line segment
|
||||||
* connecting two points. This is commonly called a "beeline" or
|
* connecting two points. This is commonly called a "beeline" or
|
||||||
* "as the crow flies."
|
* "as the crow flies."
|
||||||
*/
|
*/
|
||||||
Euclidean,
|
Euclidean [[maybe_unused]],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Manhattan distance.
|
* @brief Manhattan distance.
|
||||||
*
|
*
|
||||||
* @details The Manhattan distance is the sum of the absolute value of the
|
* @details The Manhattan distance is the sum of the absolute value of the
|
||||||
* differences of the elements. This is commonly called the
|
* differences of the elements. This is commonly called the
|
||||||
* "taxicab distance," "rectilinear distance," or many other [formal
|
* "taxicab distance," "rectilinear distance," or many other [formal
|
||||||
* names](https://en.wikipedia.org/wiki/Taxicab_geometry).
|
* names](https://en.wikipedia.org/wiki/Taxicab_geometry).
|
||||||
*/
|
*/
|
||||||
Manhattan
|
Manhattan [[maybe_unused]]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An abstract domain based on a gridded environment.
|
* @brief An abstract domain based on a gridded environment.
|
||||||
@@ -91,15 +91,15 @@ enum class GridDistanceType {
|
|||||||
* rectilinear grid where the cells are equal size and laid out in an ordered
|
* rectilinear grid where the cells are equal size and laid out in an ordered
|
||||||
* fashion.
|
* fashion.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT GridDomain : public Domain {};
|
class LIBKAMI_EXPORT GridDomain : public Domain {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An abstract for gridded coordinates.
|
* @brief An abstract for gridded coordinates.
|
||||||
*
|
*
|
||||||
* @details All gridded coordinates are expected to subclass `GridCoord`.
|
* @details All gridded coordinates are expected to subclass `GridCoord`.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT GridCoord : public Coord {};
|
class LIBKAMI_EXPORT GridCoord : public Coord {};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
#endif // KAMI_DOMAIN_H
|
#endif // KAMI_GRID_H
|
||||||
|
|||||||
@@ -27,223 +27,221 @@
|
|||||||
#ifndef KAMI_GRID1D_H
|
#ifndef KAMI_GRID1D_H
|
||||||
#define KAMI_GRID1D_H
|
#define KAMI_GRID1D_H
|
||||||
|
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/kami.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <kami/domain.h>
|
||||||
|
#include <kami/grid.h>
|
||||||
|
#include <kami/kami.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One-dimensional coordinates
|
* One-dimensional coordinates
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT GridCoord1D : public GridCoord {
|
class LIBKAMI_EXPORT GridCoord1D : public GridCoord {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for one-dimensional coordinates
|
* Constructor for one-dimensional coordinates
|
||||||
*/
|
*/
|
||||||
GridCoord1D(int x_coord) : _x_coord(x_coord){};
|
explicit GridCoord1D(int x_coord) : _x_coord(x_coord){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the `x` coordinate
|
* Return the `x` coordinate
|
||||||
*/
|
*/
|
||||||
int get_x_location(void) const;
|
[[nodiscard]] int get_x_location() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the coordinate to a human-readable string.
|
* Convert the coordinate to a human-readable string.
|
||||||
*
|
*
|
||||||
* @return a human-readable form of the `Coord` as `std::string`.
|
* @return a human-readable form of the `Coord` as `std::string`.
|
||||||
*/
|
*/
|
||||||
std::string to_string() const;
|
[[nodiscard]] std::string to_string() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two coordinates are equal
|
* Test if two coordinates are equal
|
||||||
*/
|
*/
|
||||||
friend bool operator==(const GridCoord1D &lhs, const GridCoord1D &rhs);
|
friend bool operator==(const GridCoord1D &lhs, const GridCoord1D &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two coordinates are not equal
|
* Test if two coordinates are not equal
|
||||||
*/
|
*/
|
||||||
friend bool operator!=(const GridCoord1D &lhs, const GridCoord1D &rhs);
|
friend bool operator!=(const GridCoord1D &lhs, const GridCoord1D &rhs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output a given coordinate to the specified stream
|
* Output a given coordinate to the specified stream
|
||||||
*/
|
*/
|
||||||
friend std::ostream &operator<<(std::ostream &lhs, const GridCoord1D &rhs);
|
friend std::ostream &operator<<(std::ostream &lhs, const GridCoord1D &rhs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _x_coord;
|
int _x_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A one-dimensional grid where each cell may contain agents
|
* A one-dimensional grid where each cell may contain agents
|
||||||
*
|
*
|
||||||
* The grid is linear and may wrap around in its only dimension.
|
* The grid is linear and may wrap around in its only dimension.
|
||||||
*
|
*
|
||||||
* @see `MultiGrid1D`
|
* @see `MultiGrid1D`
|
||||||
* @see `SoloGrid1D`
|
* @see `SoloGrid1D`
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Grid1D : public GridDomain {
|
class LIBKAMI_EXPORT Grid1D : public GridDomain {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid.
|
* @param[in] maximum_x the length of the grid.
|
||||||
* @param[in] wrap_x should the grid wrap around on itself.
|
* @param[in] wrap_x should the grid wrap around on itself.
|
||||||
*/
|
*/
|
||||||
Grid1D(unsigned int maximum_x, bool wrap_x = false);
|
explicit Grid1D(unsigned int maximum_x, bool wrap_x = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deconstructor
|
* Deconstructor
|
||||||
*/
|
*/
|
||||||
virtual ~Grid1D();
|
virtual ~Grid1D();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true.
|
* location, otherwise, true.
|
||||||
*/
|
*/
|
||||||
virtual bool add_agent(AgentID agent_id, GridCoord1D coord) = 0;
|
virtual bool add_agent(AgentID agent_id, GridCoord1D coord) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove agent from the grid.
|
* Remove agent from the grid.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to remove.
|
* @param[in] agent_id the `AgentID` of the agent to remove.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not removed, otherwise, true.
|
* @returns false if the agent is not removed, otherwise, true.
|
||||||
*/
|
*/
|
||||||
bool delete_agent(AgentID agent_id);
|
[[maybe_unused]] [[maybe_unused]] bool delete_agent(AgentID agent_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove agent from the grid at the specified location
|
* Remove agent from the grid at the specified location
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to remove.
|
* @param[in] agent_id the `AgentID` of the agent to remove.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not removed, otherwise, true.
|
* @returns false if the agent is not removed, otherwise, true.
|
||||||
*/
|
*/
|
||||||
virtual bool delete_agent(AgentID agent_id, GridCoord1D coord);
|
bool delete_agent(AgentID agent_id, const GridCoord1D &coord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move an agent to the specified location.
|
* Move an agent to the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to move.
|
* @param[in] agent_id the `AgentID` of the agent to move.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*/
|
*/
|
||||||
bool move_agent(AgentID agent_id, GridCoord1D coord);
|
bool move_agent(AgentID agent_id, GridCoord1D coord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire if the specified location is empty.
|
* Inquire if the specified location is empty.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return true if the location has no `Agent`s occupying it, false
|
* @return true if the location has no `Agent`s occupying it, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool is_location_empty(GridCoord1D coord) const;
|
[[nodiscard]] bool is_location_empty(const GridCoord1D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire if the specified location is valid within the grid.
|
* Inquire if the specified location is valid within the grid.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return true if the location specified is valid, false otherwise.
|
* @return true if the location specified is valid, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool is_location_valid(GridCoord1D coord) const;
|
[[nodiscard]] bool is_location_valid(const GridCoord1D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the location of the specified agent.
|
* Get the location of the specified agent.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent in question.
|
* @param[in] agent_id the `AgentID` of the agent in question.
|
||||||
*
|
*
|
||||||
* @return the location of the specified `Agent`
|
* @return the location of the specified `Agent`
|
||||||
*/
|
*/
|
||||||
GridCoord1D get_location_by_agent(AgentID agent_id) const;
|
[[nodiscard]] GridCoord1D get_location_by_agent(AgentID agent_id) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the contents of the specified location.
|
* Get the contents of the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return a pointer to a `vector` of `AgentID`s. The pointer is to the
|
* @return a pointer to a `vector` of `AgentID`s. The pointer is to the
|
||||||
* internal copy of the agent list at the location, therefore, any changes
|
* internal copy of the agent list at the location, therefore, any changes
|
||||||
* to that object will update the state of the gird. Further, the pointer
|
* to that object will update the state of the gird. Further, the pointer
|
||||||
* should not be deleted when no longer used.
|
* should not be deleted when no longer used.
|
||||||
*/
|
*/
|
||||||
std::vector<AgentID> *get_location_contents(GridCoord1D coord) const;
|
[[nodiscard]] std::vector<AgentID> *get_location_contents(const GridCoord1D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire to whether the grid wraps in the `x` dimension.
|
* Inquire to whether the grid wraps in the `x` dimension.
|
||||||
*
|
*
|
||||||
* @return true if the grid wraps, and false otherwise
|
* @return true if the grid wraps, and false otherwise
|
||||||
*/
|
*/
|
||||||
bool get_wrap_x(void) const;
|
[[maybe_unused]] [[maybe_unused]] [[nodiscard]] bool get_wrap_x() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the neighborhood of the specified Agent
|
* Return the neighborhood of the specified Agent
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent in question
|
* @param[in] agent_id the `AgentID` of the agent in question
|
||||||
* @param[in] include_center should the center-point, occupied by the agent,
|
* @param[in] include_center should the center-point, occupied by the agent,
|
||||||
* be in the list.
|
* be in the list.
|
||||||
*
|
*
|
||||||
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
||||||
* for all adjacent points.
|
* for all adjacent points.
|
||||||
*/
|
*/
|
||||||
std::vector<GridCoord1D> get_neighborhood(AgentID agent_id,
|
[[nodiscard]] std::vector<GridCoord1D> get_neighborhood(AgentID agent_id, bool include_center) const;
|
||||||
bool include_center) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the neighborhood of the specified location
|
* Return the neighborhood of the specified location
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the specified location.
|
* @param[in] coord the coordinates of the specified location.
|
||||||
* @param[in] include_center should the center-point, occupied by the agent,
|
* @param[in] include_center should the center-point, occupied by the agent,
|
||||||
* be in the list.
|
* be in the list.
|
||||||
*
|
*
|
||||||
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
||||||
* for all adjacent points.
|
* for all adjacent points.
|
||||||
*/
|
*/
|
||||||
std::vector<GridCoord1D> get_neighborhood(GridCoord1D coord,
|
[[nodiscard]] std::vector<GridCoord1D> get_neighborhood(const GridCoord1D& coord, bool include_center) const;
|
||||||
bool include_center) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the grid in the `x` dimension.
|
* Get the size of the grid in the `x` dimension.
|
||||||
*
|
*
|
||||||
* @return the length of the grid in the `x` dimension
|
* @return the length of the grid in the `x` dimension
|
||||||
*/
|
*/
|
||||||
unsigned int get_maximum_x(void) const;
|
[[maybe_unused]] [[nodiscard]] unsigned int get_maximum_x() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* A vector containing the `AgentID`s of all agents assgined to this
|
* A vector containing the `AgentID`s of all agents assigned to this
|
||||||
* grid.
|
* grid.
|
||||||
*/
|
*/
|
||||||
std::vector<AgentID> *_agent_grid;
|
std::vector<AgentID> *_agent_grid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map containing the grid location of each agent.
|
* A map containing the grid location of each agent.
|
||||||
*/
|
*/
|
||||||
std::map<AgentID, GridCoord1D> *_agent_index;
|
std::map<AgentID, GridCoord1D> *_agent_index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically adjust a coordinate location for wrapping.
|
* Automatically adjust a coordinate location for wrapping.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the specified location.
|
* @param[in] coord the coordinates of the specified location.
|
||||||
*
|
*
|
||||||
* @return the adjusted coordinate wrapped if appropriate.
|
* @return the adjusted coordinate wrapped if appropriate.
|
||||||
*/
|
*/
|
||||||
GridCoord1D coord_wrap(GridCoord1D coord) const;
|
[[nodiscard]] GridCoord1D coord_wrap(const GridCoord1D& coord) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int _maximum_x;
|
unsigned int _maximum_x;
|
||||||
bool _wrap_x;
|
bool _wrap_x;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -27,62 +27,62 @@
|
|||||||
#ifndef KAMI_GRID2D_H
|
#ifndef KAMI_GRID2D_H
|
||||||
#define KAMI_GRID2D_H
|
#define KAMI_GRID2D_H
|
||||||
|
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/kami.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <kami/domain.h>
|
||||||
|
#include <kami/grid.h>
|
||||||
|
#include <kami/kami.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Two-dimensional coordinates
|
* Two-dimensional coordinates
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT GridCoord2D : public GridCoord {
|
class LIBKAMI_EXPORT GridCoord2D : public GridCoord {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for two-dimensional coordinates
|
* Constructor for two-dimensional coordinates
|
||||||
*/
|
*/
|
||||||
GridCoord2D(int x_coord, int y_coord)
|
GridCoord2D(int x_coord, int y_coord)
|
||||||
: _x_coord(x_coord), _y_coord(y_coord){};
|
: _x_coord(x_coord), _y_coord(y_coord){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the coordinate in the first dimension or `x`.
|
* Get the coordinate in the first dimension or `x`.
|
||||||
*/
|
*/
|
||||||
int get_x_location(void) const;
|
[[nodiscard]] int get_x_location() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the coordinate in the second dimension or `y`.
|
* Get the coordinate in the second dimension or `y`.
|
||||||
*/
|
*/
|
||||||
int get_y_location(void) const;
|
[[nodiscard]] int get_y_location() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the coordinate to a human-readable string.
|
* Convert the coordinate to a human-readable string.
|
||||||
*
|
*
|
||||||
* @return a human-readable form of the `Coord` as `std::string`.
|
* @return a human-readable form of the `Coord` as `std::string`.
|
||||||
*/
|
*/
|
||||||
std::string to_string() const;
|
[[nodiscard]] std::string to_string() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two coordinates are equal
|
* Test if two coordinates are equal
|
||||||
*/
|
*/
|
||||||
friend bool operator==(const GridCoord2D &, const GridCoord2D &);
|
friend bool operator==(const GridCoord2D &, const GridCoord2D &);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if two coordinates are not equal
|
* Test if two coordinates are not equal
|
||||||
*/
|
*/
|
||||||
friend bool operator!=(const GridCoord2D &, const GridCoord2D &);
|
friend bool operator!=(const GridCoord2D &, const GridCoord2D &);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output a given coordinate to the specified stream
|
* Output a given coordinate to the specified stream
|
||||||
*/
|
*/
|
||||||
friend std::ostream &operator<<(std::ostream &, const GridCoord2D &);
|
friend std::ostream &operator<<(std::ostream &, const GridCoord2D &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _x_coord, _y_coord;
|
int _x_coord, _y_coord;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A two-dimensional grid where each cell may contain agents
|
* A two-dimensional grid where each cell may contain agents
|
||||||
@@ -92,191 +92,187 @@ class LIBKAMI_EXPORT GridCoord2D : public GridCoord {
|
|||||||
* @see `MultiGrid2D`
|
* @see `MultiGrid2D`
|
||||||
* @see `SoloGrid2D`
|
* @see `SoloGrid2D`
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Grid2D : public GridDomain {
|
class LIBKAMI_EXPORT Grid2D : public GridDomain {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid in the first dimension
|
* @param[in] maximum_x the length of the grid in the first dimension
|
||||||
* @param[in] maximum_y the length of the grid in the second dimension
|
* @param[in] maximum_y the length of the grid in the second dimension
|
||||||
* @param[in] wrap_x should the grid wrap around on itself in the first
|
* @param[in] wrap_x should the grid wrap around on itself in the first
|
||||||
* dimension
|
* dimension
|
||||||
* @param[in] wrap_y should the grid wrap around on itself in the second
|
* @param[in] wrap_y should the grid wrap around on itself in the second
|
||||||
* dimension
|
* dimension
|
||||||
*/
|
*/
|
||||||
Grid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x = false,
|
Grid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x = false,
|
||||||
bool wrap_y = false);
|
bool wrap_y = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deconstructor
|
* Deconstructor
|
||||||
*/
|
*/
|
||||||
virtual ~Grid2D();
|
virtual ~Grid2D();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true.
|
* location, otherwise, true.
|
||||||
*/
|
*/
|
||||||
virtual bool add_agent(AgentID agent_id, GridCoord2D coord) = 0;
|
virtual bool add_agent(AgentID agent_id, GridCoord2D coord) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove agent from the grid.
|
* Remove agent from the grid.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to remove.
|
* @param[in] agent_id the `AgentID` of the agent to remove.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not removed, otherwise, true.
|
* @returns false if the agent is not removed, otherwise, true.
|
||||||
*/
|
*/
|
||||||
bool delete_agent(AgentID agent_id);
|
[[maybe_unused]] bool delete_agent(AgentID agent_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove agent from the grid at the specified location
|
* Remove agent from the grid at the specified location
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to remove.
|
* @param[in] agent_id the `AgentID` of the agent to remove.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not removed, otherwise, true.
|
* @returns false if the agent is not removed, otherwise, true.
|
||||||
*/
|
*/
|
||||||
virtual bool delete_agent(AgentID agent_id, GridCoord2D coord);
|
bool delete_agent(AgentID agent_id, const GridCoord2D &coord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move an agent to the specified location.
|
* Move an agent to the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to move.
|
* @param[in] agent_id the `AgentID` of the agent to move.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*/
|
*/
|
||||||
bool move_agent(AgentID agent_id, GridCoord2D coord);
|
bool move_agent(AgentID agent_id, GridCoord2D coord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire if the specified location is empty.
|
* Inquire if the specified location is empty.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return true if the location has no `Agent`s occupying it, false
|
* @return true if the location has no `Agent`s occupying it, false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
bool is_location_empty(GridCoord2D coord) const;
|
[[nodiscard]] bool is_location_empty(const GridCoord2D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire if the specified location is valid within the grid.
|
* Inquire if the specified location is valid within the grid.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return true if the location specified is valid, false otherwise.
|
* @return true if the location specified is valid, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool is_location_valid(GridCoord2D coord) const;
|
[[nodiscard]] bool is_location_valid(const GridCoord2D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the location of the specified agent.
|
* Get the location of the specified agent.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent in question.
|
* @param[in] agent_id the `AgentID` of the agent in question.
|
||||||
*
|
*
|
||||||
* @return the location of the specified `Agent`
|
* @return the location of the specified `Agent`
|
||||||
*/
|
*/
|
||||||
GridCoord2D get_location_by_agent(AgentID agent_id) const;
|
[[nodiscard]] GridCoord2D get_location_by_agent(AgentID agent_id) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the contents of the specified location.
|
* Get the contents of the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the query.
|
* @param[in] coord the coordinates of the query.
|
||||||
*
|
*
|
||||||
* @return a pointer to a `vector` of `AgentID`s. The pointer is to the
|
* @return a pointer to a `vector` of `AgentID`s. The pointer is to the
|
||||||
* internal copy of the agent list at the location, therefore, any changes
|
* internal copy of the agent list at the location, therefore, any changes
|
||||||
* to that object will update the state of the gird. Further, the pointer
|
* to that object will update the state of the gird. Further, the pointer
|
||||||
* should not be deleted when no longer used.
|
* should not be deleted when no longer used.
|
||||||
*/
|
*/
|
||||||
std::vector<AgentID> *get_location_contents(GridCoord2D coord) const;
|
[[nodiscard]] std::vector<AgentID> *get_location_contents(const GridCoord2D& coord) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire to whether the grid wraps in the `x` dimension.
|
* Inquire to whether the grid wraps in the `x` dimension.
|
||||||
*
|
*
|
||||||
* @return true if the grid wraps, and false otherwise
|
* @return true if the grid wraps, and false otherwise
|
||||||
*/
|
*/
|
||||||
bool get_wrap_x(void) const;
|
[[maybe_unused]] [[nodiscard]] bool get_wrap_x() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inquire to whether the grid wraps in the `y` dimension.
|
* Inquire to whether the grid wraps in the `y` dimension.
|
||||||
*
|
*
|
||||||
* @return true if the grid wraps, and false otherwise
|
* @return true if the grid wraps, and false otherwise
|
||||||
*/
|
*/
|
||||||
bool get_wrap_y(void) const;
|
[[maybe_unused]] [[nodiscard]] bool get_wrap_y() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the neighborhood of the specified Agent
|
* Return the neighborhood of the specified Agent
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent in question.
|
* @param[in] agent_id the `AgentID` of the agent in question.
|
||||||
* @param[in] neighborhood_type the neighborhood type.
|
* @param[in] neighborhood_type the neighborhood type.
|
||||||
* @param[in] include_center should the center-point, occupied by the agent,
|
* @param[in] include_center should the center-point, occupied by the agent,
|
||||||
* be in the list.
|
* be in the list.
|
||||||
*
|
*
|
||||||
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
||||||
* for all adjacent points.
|
* for all adjacent points.
|
||||||
*
|
*
|
||||||
* @see `NeighborhoodType`
|
* @see `NeighborhoodType`
|
||||||
*/
|
*/
|
||||||
std::vector<GridCoord2D> get_neighborhood(
|
[[nodiscard]] std::vector<GridCoord2D> get_neighborhood(AgentID agent_id, GridNeighborhoodType neighborhood_type, bool include_center) const;
|
||||||
AgentID agent_id, GridNeighborhoodType neighborhood_type,
|
|
||||||
bool include_center) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the neighborhood of the specified location
|
* Return the neighborhood of the specified location
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the specified location.
|
* @param[in] coord the coordinates of the specified location.
|
||||||
* @param[in] neighborhood_type the neighborhood type.
|
* @param[in] neighborhood_type the neighborhood type.
|
||||||
* @param[in] include_center should the center-point, occupied by the agent,
|
* @param[in] include_center should the center-point, occupied by the agent,
|
||||||
* be in the list.
|
* be in the list.
|
||||||
*
|
*
|
||||||
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
* @return a vector of `GridCoord1D` that includes all of the coordinates
|
||||||
* for all adjacent points.
|
* for all adjacent points.
|
||||||
*
|
*
|
||||||
* @see `NeighborhoodType`
|
* @see `NeighborhoodType`
|
||||||
*/
|
*/
|
||||||
std::vector<GridCoord2D> get_neighborhood(
|
[[nodiscard]] std::vector<GridCoord2D> get_neighborhood(const GridCoord2D& coord, GridNeighborhoodType neighborhood_type, bool include_center) const;
|
||||||
GridCoord2D coord, GridNeighborhoodType neighborhood_type,
|
|
||||||
bool include_center) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the grid in the `x` dimension.
|
* Get the size of the grid in the `x` dimension.
|
||||||
*
|
*
|
||||||
* @return the length of the grid in the `x` dimension
|
* @return the length of the grid in the `x` dimension
|
||||||
*/
|
*/
|
||||||
unsigned int get_maximum_x(void) const;
|
[[maybe_unused]] [[nodiscard]] unsigned int get_maximum_x() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the grid in the `y` dimension.
|
* Get the size of the grid in the `y` dimension.
|
||||||
*
|
*
|
||||||
* @return the length of the grid in the `xy dimension
|
* @return the length of the grid in the `xy dimension
|
||||||
*/
|
*/
|
||||||
unsigned int get_maximum_y(void) const;
|
[[maybe_unused]] [[nodiscard]] unsigned int get_maximum_y() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* A vector containing the `AgentID`s of all agents assgined to this
|
* A vector containing the `AgentID`s of all agents assigned to this
|
||||||
* grid.
|
* grid.
|
||||||
*/
|
*/
|
||||||
std::vector<AgentID> **_agent_grid;
|
std::vector<AgentID> **_agent_grid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map containing the grid location of each agent.
|
* A map containing the grid location of each agent.
|
||||||
*/
|
*/
|
||||||
std::map<AgentID, GridCoord2D> *_agent_index;
|
std::map<AgentID, GridCoord2D> *_agent_index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically adjust a coordinate location for wrapping.
|
* Automatically adjust a coordinate location for wrapping.
|
||||||
*
|
*
|
||||||
* @param[in] coord the coordinates of the specified location.
|
* @param[in] coord the coordinates of the specified location.
|
||||||
*
|
*
|
||||||
* @return the adjusted coordinate wrapped if appropriate.
|
* @return the adjusted coordinate wrapped if appropriate.
|
||||||
*/
|
*/
|
||||||
GridCoord2D coord_wrap(GridCoord2D coord) const;
|
[[nodiscard]] GridCoord2D coord_wrap(const GridCoord2D& coord) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int _maximum_x, _maximum_y;
|
unsigned int _maximum_x, _maximum_y;
|
||||||
bool _wrap_x, _wrap_y;
|
bool _wrap_x, _wrap_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -35,34 +35,34 @@ namespace kami {
|
|||||||
/**
|
/**
|
||||||
* An abstract for generic models
|
* An abstract for generic models
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Model {
|
class LIBKAMI_EXPORT Model {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Get a reference to an `Agent` by `AgentID`
|
* Get a reference to an `Agent` by `AgentID`
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` to search for.
|
* @param[in] agent_id the `AgentID` to search for.
|
||||||
*
|
*
|
||||||
* @return a reference to the desired `Agent` or `nullptr` if not found.
|
* @return a reference to the desired `Agent` or `nullptr` if not found.
|
||||||
*/
|
*/
|
||||||
virtual Agent *get_agent_by_id(AgentID agent_id) const = 0;
|
[[nodiscard]] virtual Agent *get_agent_by_id(AgentID agent_id) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a fixed number of time-steps for the model.
|
* Execute a fixed number of time-steps for the model.
|
||||||
*
|
*
|
||||||
* This function should execute a fixed number of time-steps for the model.
|
* This function should execute a fixed number of time-steps for the model.
|
||||||
*
|
*
|
||||||
* @param[in] n the number of time steps to execute.
|
* @param[in] n the number of time steps to execute.
|
||||||
*/
|
*/
|
||||||
virtual void run(unsigned int n) = 0;
|
[[maybe_unused]] virtual void run(unsigned int n) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a single time-step for the model.
|
* Execute a single time-step for the model.
|
||||||
*
|
*
|
||||||
* This function should step the model instance. Any activities that the
|
* This function should step the model instance. Any activities that the
|
||||||
* model should perform as part of its time step should be in this function.
|
* model should perform as part of its time step should be in this function.
|
||||||
*/
|
*/
|
||||||
virtual void step() = 0;
|
virtual void step() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -40,28 +40,28 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* @details The grid is linear and may wrap around in its only dimension.
|
* @details The grid is linear and may wrap around in its only dimension.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT MultiGrid1D : public Grid1D {
|
class LIBKAMI_EXPORT MultiGrid1D : public Grid1D {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid.
|
* @param[in] maximum_x the length of the grid.
|
||||||
* @param[in] wrap_x should the grid wrap around on itself.
|
* @param[in] wrap_x should the grid wrap around on itself.
|
||||||
*/
|
*/
|
||||||
MultiGrid1D(unsigned int maximum_x, bool wrap_x)
|
MultiGrid1D(unsigned int maximum_x, bool wrap_x)
|
||||||
: Grid1D(maximum_x, wrap_x) {}
|
: Grid1D(maximum_x, wrap_x) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true
|
* location, otherwise, true
|
||||||
*/
|
*/
|
||||||
bool add_agent(AgentID agent_id, GridCoord1D coord);
|
bool add_agent(AgentID agent_id, GridCoord1D coord) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -43,32 +43,32 @@ namespace kami {
|
|||||||
* @see `Grid2D`
|
* @see `Grid2D`
|
||||||
* @see `SoloGrid2D`
|
* @see `SoloGrid2D`
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT MultiGrid2D : public Grid2D {
|
class LIBKAMI_EXPORT MultiGrid2D : public Grid2D {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid in the first dimension
|
* @param[in] maximum_x the length of the grid in the first dimension
|
||||||
* @param[in] maximum_y the length of the grid in the second dimension
|
* @param[in] maximum_y the length of the grid in the second dimension
|
||||||
* @param[in] wrap_x should the grid wrap around on itself in the first
|
* @param[in] wrap_x should the grid wrap around on itself in the first
|
||||||
* dimension
|
* dimension
|
||||||
* @param[in] wrap_y should the grid wrap around on itself in the second
|
* @param[in] wrap_y should the grid wrap around on itself in the second
|
||||||
* dimension
|
* dimension
|
||||||
*/
|
*/
|
||||||
MultiGrid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x,
|
MultiGrid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x, bool wrap_y)
|
||||||
bool wrap_y);
|
: Grid2D(maximum_x, maximum_y, wrap_x, wrap_y) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true
|
* location, otherwise, true
|
||||||
*/
|
*/
|
||||||
bool add_agent(AgentID agent_id, GridCoord2D coord);
|
bool add_agent(AgentID agent_id, GridCoord2D coord) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -47,62 +47,50 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* @note First create a Model for the scheduler to live in.
|
* @note First create a Model for the scheduler to live in.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT RandomScheduler : public SequentialScheduler {
|
class LIBKAMI_EXPORT RandomScheduler : public SequentialScheduler {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor.
|
* @brief Constructor.
|
||||||
*
|
*
|
||||||
* @details The `model` parameter is used by the scheduler to get
|
* @details The `model` parameter is used by the scheduler to get
|
||||||
* access to an `Agent`. The `Model` is presumed to maintain a master
|
* access to an `Agent`. The `Model` is presumed to maintain a master
|
||||||
* list of all `Agent`s in the `Model` and the `Model` can be queried for
|
* list of all `Agent`s in the `Model` and the `Model` can be queried for
|
||||||
* a reference to any particular `Agent` at `step()` time.
|
* a reference to any particular `Agent` at `step()` time.
|
||||||
*
|
*
|
||||||
* @param model [in] A reference to the model the scheduler is timing.
|
* @param model [in] A reference to the model the scheduler is timing.
|
||||||
*/
|
* @param rng [in] A uniform random number generator of type
|
||||||
RandomScheduler(Model *model);
|
* `std::mt19937`, used as the source of randomness.
|
||||||
|
*/
|
||||||
|
RandomScheduler(Model *model, std::shared_ptr<std::mt19937> rng);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor.
|
* @brief Execute a single time step.
|
||||||
*
|
*
|
||||||
* @details The `model` parameter is used by the scheduler to get
|
* @details This method will randomize the list of Agents in the scheduler's
|
||||||
* access to an `Agent`. The `Model` is presumed to maintain a master
|
* internal queue and then execute the `Agent::step()` method for every
|
||||||
* list of all `Agent`s in the `Model` and the `Model` can be queried for
|
* Agent assigned to this scheduler in the randomized order.
|
||||||
* a reference to any particular `Agent` at `step()` time.
|
*/
|
||||||
*
|
void step() override;
|
||||||
* @param model [in] A reference to the model the scheduler is timing.
|
|
||||||
* @param rng [in] A uniform random number generator of type
|
|
||||||
* `std::mt19937`, used as the source of randomness.
|
|
||||||
*/
|
|
||||||
RandomScheduler(Model *model, std::shared_ptr<std::mt19937> rng);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a single time step.
|
* Set the random number generator used to randomize the order of agent
|
||||||
*
|
* stepping.
|
||||||
* @details This method will randomize the list of Agents in the scheduler's
|
*
|
||||||
* internal queue and then execute the `Agent::step()` method for every
|
* @param rng [in] A uniform random number generator of type `std::mt19937`,
|
||||||
* Agent assigned to this scheduler in the randomized order.
|
* used as the source of randomness.
|
||||||
*/
|
*/
|
||||||
void step();
|
void set_rng(std::shared_ptr<std::mt19937> rng);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the random number generator used to randomize the order of agent
|
* Get a reference to the random number generator used to randomize
|
||||||
* stepping.
|
* the order of agent stepping.
|
||||||
*
|
*/
|
||||||
* @param rng [in] A uniform random number generator of type `std::mt19937`,
|
[[maybe_unused]] std::shared_ptr<std::mt19937> get_rng();
|
||||||
* used as the source of randomness.
|
|
||||||
*/
|
|
||||||
void set_rng(std::shared_ptr<std::mt19937> rng);
|
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* Get a reference to the random number generator used to randomize
|
std::shared_ptr<std::mt19937> _rng;
|
||||||
* the order of agent stepping.
|
};
|
||||||
*/
|
|
||||||
std::shared_ptr<std::mt19937> get_rng();
|
|
||||||
|
|
||||||
private:
|
} // namespace kami
|
||||||
std::shared_ptr<std::mt19937> _rng;
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace kami
|
|
||||||
|
|
||||||
#endif // KAMI_RANDOM_H
|
#endif // KAMI_RANDOM_H
|
||||||
|
|||||||
@@ -39,29 +39,29 @@ namespace kami {
|
|||||||
* scheduler will have a collection of agents assigned to it and will execute
|
* scheduler will have a collection of agents assigned to it and will execute
|
||||||
* the step function for each agent based on the type of scheduling implemented.
|
* the step function for each agent based on the type of scheduling implemented.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT Scheduler {
|
class LIBKAMI_EXPORT Scheduler {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Add an Agent to the Scheduler.
|
* Add an Agent to the Scheduler.
|
||||||
*
|
*
|
||||||
* @param agent_id The AgentID of the agent to add.
|
* @param agent_id The AgentID of the agent to add.
|
||||||
*/
|
*/
|
||||||
virtual void add_agent(AgentID agent_id) = 0;
|
virtual void add_agent(AgentID agent_id) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an Agent from the Scheduler.
|
* Remove an Agent from the Scheduler.
|
||||||
*
|
*
|
||||||
* @param agent_id The AgentID of the agent to remove.
|
* @param agent_id The AgentID of the agent to remove.
|
||||||
*/
|
*/
|
||||||
virtual void delete_agent(AgentID agent_id) = 0;
|
[[maybe_unused]] virtual void delete_agent(AgentID agent_id) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Step the Scheduler.
|
* Step the Scheduler.
|
||||||
*
|
*
|
||||||
* A generic step function that executes a single time step.
|
* A generic step function that executes a single time step.
|
||||||
*/
|
*/
|
||||||
virtual void step() = 0;
|
virtual void step() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,14 @@
|
|||||||
#ifndef KAMI_SEQUENTIAL_H
|
#ifndef KAMI_SEQUENTIAL_H
|
||||||
#define KAMI_SEQUENTIAL_H
|
#define KAMI_SEQUENTIAL_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <kami/KAMI_EXPORT.h>
|
#include <kami/KAMI_EXPORT.h>
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/model.h>
|
#include <kami/model.h>
|
||||||
#include <kami/scheduler.h>
|
#include <kami/scheduler.h>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,62 +47,62 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* \pre First create a Model for the scheduler to live in.
|
* \pre First create a Model for the scheduler to live in.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT SequentialScheduler : public Scheduler {
|
class LIBKAMI_EXPORT SequentialScheduler : public Scheduler {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor.
|
* @brief Constructor.
|
||||||
*
|
*
|
||||||
* @details The Model parameter is used by the scheduler to get
|
* @details The Model parameter is used by the scheduler to get
|
||||||
* access to an Agent. The Model is presumed to maintain a master
|
* access to an Agent. The Model is presumed to maintain a master
|
||||||
* list of all Agents in the Model and the Model can be queried for
|
* list of all Agents in the Model and the Model can be queried for
|
||||||
* a reference to any particular Agent at `step()` time.
|
* a reference to any particular Agent at `step()` time.
|
||||||
*/
|
*/
|
||||||
SequentialScheduler(Model *model);
|
explicit SequentialScheduler(Model *model);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add an agent to the scheduler.
|
* @brief Add an agent to the scheduler.
|
||||||
*
|
*
|
||||||
* @details The scheduler maintains a list of all AgentIDs currently
|
* @details The scheduler maintains a list of all AgentIDs currently
|
||||||
* assigned. This function adds a new Agent to the list.
|
* assigned. This function adds a new Agent to the list.
|
||||||
*/
|
*/
|
||||||
void add_agent(AgentID agent_id);
|
void add_agent(AgentID agent_id) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove an agent from the scheduler.
|
* @brief Remove an agent from the scheduler.
|
||||||
*
|
*
|
||||||
* @details The scheduler maintains a list of all AgentIDs currently
|
* @details The scheduler maintains a list of all AgentIDs currently
|
||||||
* assigned. This function removes an Agent from the list.
|
* assigned. This function removes an Agent from the list.
|
||||||
*/
|
*/
|
||||||
void delete_agent(AgentID agent_id);
|
void delete_agent(AgentID agent_id) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Execute a single time step.
|
* @brief Execute a single time step.
|
||||||
*
|
*
|
||||||
* @details This method will step through the list of Agents in the
|
* @details This method will step through the list of Agents in the
|
||||||
* scheduler's internal queue and then execute the `Agent::step()`
|
* scheduler's internal queue and then execute the `Agent::step()`
|
||||||
* method for every Agent assigned to this scheduler in the order
|
* method for every Agent assigned to this scheduler in the order
|
||||||
* assigned.
|
* assigned.
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* A vector containing the `AgentID`s of all agents assgined to this
|
* A vector containing the `AgentID`s of all agents assigned to this
|
||||||
* scheduler
|
* scheduler
|
||||||
*/
|
*/
|
||||||
std::vector<AgentID> _agent_list;
|
std::vector<AgentID> _agent_list;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pointer to the `Model` this scehduler belongs to
|
* A pointer to the `Model` this scheduler belongs to
|
||||||
*/
|
*/
|
||||||
Model *_model;
|
Model *_model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counter to increment on each step
|
* Counter to increment on each step
|
||||||
*/
|
*/
|
||||||
int _step_counter;
|
int _step_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
#endif // KAMI_SEQUENTIAL_H
|
#endif // KAMI_SEQUENTIAL_H
|
||||||
|
|||||||
@@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
#include <kami/KAMI_EXPORT.h>
|
#include <kami/KAMI_EXPORT.h>
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid1d.h>
|
#include <kami/grid1d.h>
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
|
|
||||||
@@ -41,28 +39,28 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* @details The grid is linear and may wrap around in its only dimension.
|
* @details The grid is linear and may wrap around in its only dimension.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT SoloGrid1D : public Grid1D {
|
class LIBKAMI_EXPORT SoloGrid1D : public Grid1D {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid.
|
* @param[in] maximum_x the length of the grid.
|
||||||
* @param[in] wrap_x should the grid wrap around on itself.
|
* @param[in] wrap_x should the grid wrap around on itself.
|
||||||
*/
|
*/
|
||||||
SoloGrid1D(unsigned int maximum_x, bool wrap_x)
|
SoloGrid1D(unsigned int maximum_x, bool wrap_x)
|
||||||
: Grid1D(maximum_x, wrap_x) {}
|
: Grid1D(maximum_x, wrap_x) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true
|
* location, otherwise, true
|
||||||
*/
|
*/
|
||||||
bool add_agent(AgentID agent_id, GridCoord1D coord);
|
bool add_agent(AgentID agent_id, GridCoord1D coord) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,11 @@
|
|||||||
#ifndef KAMI_SOLOGRID2D_H
|
#ifndef KAMI_SOLOGRID2D_H
|
||||||
#define KAMI_SOLOGRID2D_H
|
#define KAMI_SOLOGRID2D_H
|
||||||
|
|
||||||
|
#include <kami/KAMI_EXPORT.h>
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid2d.h>
|
#include <kami/grid2d.h>
|
||||||
#include <kami/kami.h>
|
#include <kami/kami.h>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,30 +42,30 @@ namespace kami {
|
|||||||
* @see `MultiGrid2D`
|
* @see `MultiGrid2D`
|
||||||
* @see `Grid2D`
|
* @see `Grid2D`
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT SoloGrid2D : public Grid2D {
|
class LIBKAMI_EXPORT SoloGrid2D : public Grid2D {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] maximum_x the length of the grid in the first dimension
|
* @param[in] maximum_x the length of the grid in the first dimension
|
||||||
* @param[in] maximum_y the length of the grid in the second dimension
|
* @param[in] maximum_y the length of the grid in the second dimension
|
||||||
* @param[in] wrap_x should the grid wrap around on itself in the first dimension
|
* @param[in] wrap_x should the grid wrap around on itself in the first dimension
|
||||||
* @param[in] wrap_y should the grid wrap around on itself in the second dimension
|
* @param[in] wrap_y should the grid wrap around on itself in the second dimension
|
||||||
*/
|
*/
|
||||||
SoloGrid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x,
|
SoloGrid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x, bool wrap_y)
|
||||||
bool wrap_y);
|
: Grid2D(maximum_x, maximum_y, wrap_x, wrap_y) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place agent on the grid at the specified location.
|
* Place agent on the grid at the specified location.
|
||||||
*
|
*
|
||||||
* @param[in] agent_id the `AgentID` of the agent to add.
|
* @param[in] agent_id the `AgentID` of the agent to add.
|
||||||
* @param[in] coord the coordinates of the agent.
|
* @param[in] coord the coordinates of the agent.
|
||||||
*
|
*
|
||||||
* @returns false if the agent is not placed at the specified
|
* @returns false if the agent is not placed at the specified
|
||||||
* location, otherwise, true
|
* location, otherwise, true
|
||||||
*/
|
*/
|
||||||
bool add_agent(AgentID agent_id, GridCoord2D coord);
|
bool add_agent(AgentID agent_id, GridCoord2D coord) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
|
|||||||
@@ -46,54 +46,54 @@ namespace kami {
|
|||||||
*
|
*
|
||||||
* @note First create a Model for the scheduler to live in.
|
* @note First create a Model for the scheduler to live in.
|
||||||
*/
|
*/
|
||||||
class LIBKAMI_EXPORT StagedScheduler : public Scheduler {
|
class LIBKAMI_EXPORT StagedScheduler : public Scheduler {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* The Model parameter is used by the scheduler to get access to an Agent.
|
* The Model parameter is used by the scheduler to get access to an Agent.
|
||||||
* The Model is presumed to maintain a master list of all Agents in the
|
* The Model is presumed to maintain a master list of all Agents in the
|
||||||
* Model and the Model can be queried for a reference to any particular
|
* Model and the Model can be queried for a reference to any particular
|
||||||
* Agent at `step()` time.
|
* Agent at `step()` time.
|
||||||
*/
|
*/
|
||||||
StagedScheduler(Model *);
|
explicit StagedScheduler(Model *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A deconstructor.
|
* A deconstructor.
|
||||||
*/
|
*/
|
||||||
virtual ~StagedScheduler();
|
~StagedScheduler() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an agent to the scheduler.
|
* Add an agent to the scheduler.
|
||||||
*
|
*
|
||||||
* The scheduler maintains a list of all AgentIDs currently assigned. This
|
* The scheduler maintains a list of all AgentIDs currently assigned. This
|
||||||
* function adds a new Agent to the list.
|
* function adds a new Agent to the list.
|
||||||
*/
|
*/
|
||||||
void add_agent(AgentID agent_id);
|
void add_agent(AgentID agent_id) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an agent from the scheduler.
|
* Remove an agent from the scheduler.
|
||||||
*
|
*
|
||||||
* The scheduler maintains a list of all AgentIDs currently assigned. This
|
* The scheduler maintains a list of all AgentIDs currently assigned. This
|
||||||
* function removes an Agent from the list.
|
* function removes an Agent from the list.
|
||||||
*/
|
*/
|
||||||
void delete_agent(AgentID agent_id);
|
void delete_agent(AgentID agent_id) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a single time step.
|
* Execute a single time step.
|
||||||
*
|
*
|
||||||
* This method will step through the list of Agents in the scheduler's
|
* This method will step through the list of Agents in the scheduler's
|
||||||
* internal queue and execute the `Agent::step()` method for each `Agent`
|
* internal queue and execute the `Agent::step()` method for each `Agent`
|
||||||
* in the same order. Finally, it will execute the `Agent::advance()`
|
* in the same order. Finally, it will execute the `Agent::advance()`
|
||||||
* method for each Agent in the same order.
|
* method for each Agent in the same order.
|
||||||
*/
|
*/
|
||||||
void step();
|
void step() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<AgentID> _agent_list;
|
std::vector<AgentID> _agent_list;
|
||||||
Model *_model;
|
Model *_model;
|
||||||
int _step_counter;
|
int _step_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace kami
|
} // namespace kami
|
||||||
|
|
||||||
#endif // KAMI_STAGED_H
|
#endif // KAMI_STAGED_H
|
||||||
|
|||||||
@@ -30,28 +30,28 @@
|
|||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
bool operator==(const AgentID &lhs, const AgentID &rhs) {
|
bool operator==(const AgentID &lhs, const AgentID &rhs) {
|
||||||
return lhs._id == rhs._id;
|
return lhs._id == rhs._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const AgentID &lhs, const AgentID &rhs) {
|
bool operator!=(const AgentID &lhs, const AgentID &rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const AgentID &lhs, const AgentID &rhs) {
|
bool operator<(const AgentID &lhs, const AgentID &rhs) {
|
||||||
return lhs._id < rhs._id;
|
return lhs._id < rhs._id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &lhs, const AgentID &rhs) {
|
std::ostream &operator<<(std::ostream &lhs, const AgentID &rhs) {
|
||||||
return lhs << rhs.to_string();
|
return lhs << rhs.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentID Agent::get_agent_id() const { return this->_agent_id; }
|
AgentID Agent::get_agent_id() const { return this->_agent_id; }
|
||||||
|
|
||||||
bool operator==(const Agent &lhs, const Agent &rhs) {
|
bool operator==(const Agent &lhs, const Agent &rhs) {
|
||||||
return lhs._agent_id == rhs._agent_id;
|
return lhs._agent_id == rhs._agent_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Agent &lhs, const Agent &rhs) { return !(lhs == rhs); }
|
bool operator!=(const Agent &lhs, const Agent &rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &lhs, const Coord &rhs) {
|
std::ostream &operator<<(std::ostream &lhs, const Coord &rhs) {
|
||||||
return lhs << rhs.to_string();
|
return lhs << rhs.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -25,135 +25,132 @@
|
|||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
#include <kami/domain.h>
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid1d.h>
|
#include <kami/grid1d.h>
|
||||||
#include <kami/kami.h>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
int GridCoord1D::get_x_location() const { return _x_coord; }
|
int GridCoord1D::get_x_location() const { return _x_coord; }
|
||||||
|
|
||||||
std::string GridCoord1D::to_string() const {
|
std::string GridCoord1D::to_string() const {
|
||||||
return std::string("(" + std::to_string(_x_coord) + ")");
|
return std::string("(" + std::to_string(_x_coord) + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const GridCoord1D &lhs, const GridCoord1D &rhs) {
|
bool operator==(const GridCoord1D &lhs, const GridCoord1D &rhs) {
|
||||||
return (lhs._x_coord == rhs._x_coord);
|
return (lhs._x_coord == rhs._x_coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const GridCoord1D &lhs, const GridCoord1D &rhs) {
|
bool operator!=(const GridCoord1D &lhs, const GridCoord1D &rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &lhs, const GridCoord1D &rhs) {
|
std::ostream &operator<<(std::ostream &lhs, const GridCoord1D &rhs) {
|
||||||
return lhs << rhs.to_string();
|
return lhs << rhs.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid1D::Grid1D(unsigned int maximum_x, bool wrap_x) {
|
Grid1D::Grid1D(unsigned int maximum_x, bool wrap_x) {
|
||||||
_agent_grid = new std::vector<AgentID>[maximum_x];
|
_agent_grid = new std::vector<AgentID>[maximum_x];
|
||||||
_agent_index = new std::map<AgentID, GridCoord1D>;
|
_agent_index = new std::map<AgentID, GridCoord1D>;
|
||||||
|
|
||||||
_maximum_x = maximum_x;
|
|
||||||
_wrap_x = wrap_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid1D::~Grid1D(void) {
|
_maximum_x = maximum_x;
|
||||||
delete _agent_index;
|
_wrap_x = wrap_x;
|
||||||
delete[] _agent_grid;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid1D::delete_agent(AgentID agent_id) {
|
Grid1D::~Grid1D() {
|
||||||
GridCoord1D coord = get_location_by_agent(agent_id);
|
delete _agent_index;
|
||||||
|
delete[] _agent_grid;
|
||||||
|
}
|
||||||
|
|
||||||
return delete_agent(agent_id, coord);
|
[[maybe_unused]] bool Grid1D::delete_agent(AgentID agent_id) {
|
||||||
}
|
GridCoord1D coord = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
bool Grid1D::is_location_valid(GridCoord1D coord) const {
|
return delete_agent(agent_id, coord);
|
||||||
auto x = coord.get_x_location();
|
}
|
||||||
return (x >= 0 && x < static_cast<int>(_maximum_x));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid1D::is_location_empty(GridCoord1D coord) const {
|
bool Grid1D::is_location_valid(const GridCoord1D& coord) const {
|
||||||
auto x = coord.get_x_location();
|
auto x = coord.get_x_location();
|
||||||
|
return (x >= 0 && x < static_cast<int>(_maximum_x));
|
||||||
|
}
|
||||||
|
|
||||||
return _agent_grid[x].size() == 0;
|
bool Grid1D::is_location_empty(const GridCoord1D &coord) const {
|
||||||
}
|
auto x = coord.get_x_location();
|
||||||
|
|
||||||
bool Grid1D::delete_agent(AgentID agent_id, GridCoord1D coord) {
|
return _agent_grid[x].empty();
|
||||||
auto agent_list = _agent_grid[static_cast<int>(coord.get_x_location())];
|
}
|
||||||
|
|
||||||
for (auto test_agent_id = agent_list.begin();
|
bool Grid1D::delete_agent(AgentID agent_id, const GridCoord1D &coord) {
|
||||||
test_agent_id < agent_list.end(); test_agent_id++) {
|
auto agent_list = _agent_grid[static_cast<int>(coord.get_x_location())];
|
||||||
if (*test_agent_id == agent_id) {
|
|
||||||
agent_list.erase(test_agent_id);
|
for (auto test_agent_id = agent_list.begin();
|
||||||
_agent_index->erase(agent_id);
|
test_agent_id < agent_list.end(); test_agent_id++) {
|
||||||
return true;
|
if (*test_agent_id == agent_id) {
|
||||||
|
agent_list.erase(test_agent_id);
|
||||||
|
_agent_index->erase(agent_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
bool Grid1D::move_agent(AgentID agent_id, GridCoord1D coord) {
|
||||||
}
|
GridCoord1D coord_current = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
bool Grid1D::move_agent(AgentID agent_id, GridCoord1D coord) {
|
if (delete_agent(agent_id, coord_current))
|
||||||
GridCoord1D coord_current = get_location_by_agent(agent_id);
|
return add_agent(agent_id, std::move(coord));
|
||||||
|
return false;
|
||||||
if (delete_agent(agent_id, coord_current) == true)
|
|
||||||
return add_agent(agent_id, coord);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<GridCoord1D> Grid1D::get_neighborhood(AgentID agent_id,
|
|
||||||
bool include_center) const {
|
|
||||||
GridCoord1D coord = get_location_by_agent(agent_id);
|
|
||||||
|
|
||||||
return get_neighborhood(coord, include_center);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<GridCoord1D> Grid1D::get_neighborhood(GridCoord1D coord,
|
|
||||||
bool include_center) const {
|
|
||||||
std::vector<GridCoord1D> neighborhood;
|
|
||||||
auto x = coord.get_x_location();
|
|
||||||
|
|
||||||
// We assume our starting position is valid
|
|
||||||
if (include_center == true) neighborhood.push_back(coord);
|
|
||||||
|
|
||||||
// E, W
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord1D(x + 1));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord1D(x - 1));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return neighborhood;
|
std::vector<GridCoord1D> Grid1D::get_neighborhood(AgentID agent_id, bool include_center) const {
|
||||||
}
|
GridCoord1D coord = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
std::vector<AgentID> *Grid1D::get_location_contents(GridCoord1D coord) const {
|
return get_neighborhood(coord, include_center);
|
||||||
if (is_location_valid(coord)) return &_agent_grid[coord.get_x_location()];
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid1D::get_wrap_x(void) const { return _wrap_x; }
|
std::vector<GridCoord1D> Grid1D::get_neighborhood(const GridCoord1D& coord, bool include_center) const {
|
||||||
|
std::vector<GridCoord1D> neighborhood;
|
||||||
|
auto x = coord.get_x_location();
|
||||||
|
|
||||||
unsigned int Grid1D::get_maximum_x(void) const { return _maximum_x; }
|
// We assume our starting position is valid
|
||||||
|
if (include_center) neighborhood.push_back(coord);
|
||||||
|
|
||||||
GridCoord1D Grid1D::get_location_by_agent(AgentID agent_id) const {
|
// E, W
|
||||||
return _agent_index->at(agent_id);
|
{
|
||||||
}
|
auto new_location = coord_wrap(GridCoord1D(x + 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto new_location = coord_wrap(GridCoord1D(x - 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
|
||||||
GridCoord1D Grid1D::coord_wrap(GridCoord1D coord) const {
|
return neighborhood;
|
||||||
auto x = coord.get_x_location();
|
}
|
||||||
|
|
||||||
if (_wrap_x == true)
|
std::vector<AgentID> *Grid1D::get_location_contents(const GridCoord1D& coord) const {
|
||||||
x = (x + static_cast<int>(_maximum_x)) % static_cast<int>(_maximum_x);
|
if (is_location_valid(coord)) return &_agent_grid[coord.get_x_location()];
|
||||||
return GridCoord1D(x);
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] bool Grid1D::get_wrap_x() const { return _wrap_x; }
|
||||||
|
|
||||||
|
[[maybe_unused]] unsigned int Grid1D::get_maximum_x() const { return _maximum_x; }
|
||||||
|
|
||||||
|
GridCoord1D Grid1D::get_location_by_agent(AgentID agent_id) const {
|
||||||
|
return _agent_index->at(agent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridCoord1D Grid1D::coord_wrap(const GridCoord1D& coord) const {
|
||||||
|
auto x = coord.get_x_location();
|
||||||
|
|
||||||
|
if(_wrap_x)
|
||||||
|
x = (x + static_cast<int>(_maximum_x)) % static_cast<int>(_maximum_x);
|
||||||
|
return GridCoord1D(x);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -23,202 +23,198 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
#include <kami/domain.h>
|
||||||
#include <kami/grid.h>
|
#include <kami/grid.h>
|
||||||
#include <kami/grid2d.h>
|
#include <kami/grid2d.h>
|
||||||
#include <kami/kami.h>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
int GridCoord2D::get_x_location(void) const {
|
int GridCoord2D::get_x_location() const {
|
||||||
return _x_coord;
|
return _x_coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GridCoord2D::get_y_location(void) const {
|
int GridCoord2D::get_y_location() const {
|
||||||
return _y_coord;
|
return _y_coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GridCoord2D::to_string() const {
|
std::string GridCoord2D::to_string() const {
|
||||||
return std::string("(" + std::to_string(_x_coord) + ", " +
|
return std::string("(" + std::to_string(_x_coord) + ", " +
|
||||||
std::to_string(_y_coord) + ")");
|
std::to_string(_y_coord) + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const GridCoord2D &lhs, const GridCoord2D &rhs) {
|
bool operator==(const GridCoord2D &lhs, const GridCoord2D &rhs) {
|
||||||
return (lhs._x_coord == rhs._x_coord && lhs._y_coord == rhs._y_coord);
|
return (lhs._x_coord == rhs._x_coord && lhs._y_coord == rhs._y_coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const GridCoord2D &lhs, const GridCoord2D &rhs) {
|
bool operator!=(const GridCoord2D &lhs, const GridCoord2D &rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &lhs, const GridCoord2D &rhs) {
|
std::ostream &operator<<(std::ostream &lhs, const GridCoord2D &rhs) {
|
||||||
return lhs << rhs.to_string();
|
return lhs << rhs.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid2D::Grid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x,
|
Grid2D::Grid2D(unsigned int maximum_x, unsigned int maximum_y, bool wrap_x,
|
||||||
bool wrap_y) {
|
bool wrap_y) {
|
||||||
_maximum_x = maximum_x;
|
_maximum_x = maximum_x;
|
||||||
_maximum_y = maximum_y;
|
_maximum_y = maximum_y;
|
||||||
_wrap_x = wrap_x;
|
_wrap_x = wrap_x;
|
||||||
_wrap_y = wrap_y;
|
_wrap_y = wrap_y;
|
||||||
|
|
||||||
_agent_grid = new std::vector<AgentID> *[_maximum_x];
|
_agent_grid = new std::vector<AgentID> *[_maximum_x];
|
||||||
for (auto i = 0; i < _maximum_x; i++)
|
for (auto i = 0; i < _maximum_x; i++)
|
||||||
_agent_grid[i] = new std::vector<AgentID>[_maximum_y];
|
_agent_grid[i] = new std::vector<AgentID>[_maximum_y];
|
||||||
|
|
||||||
_agent_index = new std::map<AgentID, GridCoord2D>;
|
_agent_index = new std::map<AgentID, GridCoord2D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid2D::~Grid2D(void) {
|
Grid2D::~Grid2D() {
|
||||||
delete _agent_index;
|
delete _agent_index;
|
||||||
|
|
||||||
for (auto i = 0; i < _maximum_x; i++) delete[] _agent_grid[i];
|
for (auto i = 0; i < _maximum_x; i++) delete[] _agent_grid[i];
|
||||||
delete[] _agent_grid;
|
delete[] _agent_grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Grid2D::delete_agent(AgentID agent_id) {
|
[[maybe_unused]] bool Grid2D::delete_agent(AgentID agent_id) {
|
||||||
auto location = get_location_by_agent(agent_id);
|
auto coord = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
return delete_agent(agent_id, location);
|
return delete_agent(agent_id, coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Grid2D::delete_agent(AgentID agent_id, GridCoord2D location) {
|
bool Grid2D::delete_agent(AgentID agent_id, const GridCoord2D &coord) {
|
||||||
auto agent_list = _agent_grid[static_cast<int>(location.get_x_location())]
|
auto agent_list = _agent_grid[static_cast<int>(coord.get_x_location())][static_cast<int>(coord.get_y_location())];
|
||||||
[static_cast<int>(location.get_y_location())];
|
|
||||||
for (auto test_agent_id = agent_list.begin();
|
for (auto test_agent_id = agent_list.begin();
|
||||||
test_agent_id < agent_list.end(); test_agent_id++) {
|
test_agent_id < agent_list.end(); test_agent_id++) {
|
||||||
if (*test_agent_id == agent_id) {
|
if (*test_agent_id == agent_id) {
|
||||||
agent_list.erase(test_agent_id);
|
agent_list.erase(test_agent_id);
|
||||||
_agent_index->erase(agent_id);
|
_agent_index->erase(agent_id);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
bool Grid2D::is_location_valid(const GridCoord2D& coord) const {
|
||||||
}
|
auto x = coord.get_x_location();
|
||||||
|
auto y = coord.get_y_location();
|
||||||
|
|
||||||
bool Grid2D::is_location_valid(GridCoord2D location) const {
|
return (x >= 0 && x < static_cast<int>(_maximum_x) && y >= 0 &&
|
||||||
auto x = location.get_x_location();
|
y < static_cast<int>(_maximum_y));
|
||||||
auto y = location.get_y_location();
|
|
||||||
|
|
||||||
return (x >= 0 && x < static_cast<int>(_maximum_x) && y >= 0 &&
|
|
||||||
y < static_cast<int>(_maximum_y));
|
|
||||||
}
|
|
||||||
|
|
||||||
GridCoord2D Grid2D::get_location_by_agent(AgentID agent_id) const {
|
|
||||||
return _agent_index->at(agent_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid2D::move_agent(AgentID agent_id, GridCoord2D coord) {
|
|
||||||
GridCoord2D current_location = get_location_by_agent(agent_id);
|
|
||||||
|
|
||||||
if (delete_agent(agent_id, current_location) == true)
|
|
||||||
return add_agent(agent_id, coord);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid2D::get_wrap_x(void) const { return _wrap_x; }
|
|
||||||
bool Grid2D::get_wrap_y(void) const { return _wrap_y; }
|
|
||||||
|
|
||||||
std::vector<GridCoord2D> Grid2D::get_neighborhood(
|
|
||||||
AgentID agent_id, GridNeighborhoodType neighborhood_type,
|
|
||||||
bool includeCenter) const {
|
|
||||||
GridCoord2D location = get_location_by_agent(agent_id);
|
|
||||||
|
|
||||||
return get_neighborhood(location, neighborhood_type, includeCenter);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<GridCoord2D> Grid2D::get_neighborhood(
|
|
||||||
GridCoord2D location, GridNeighborhoodType neighborhood_type,
|
|
||||||
bool include_center) const {
|
|
||||||
std::vector<GridCoord2D> neighborhood;
|
|
||||||
auto x = location.get_x_location();
|
|
||||||
auto y = location.get_y_location();
|
|
||||||
|
|
||||||
// We assume our starting position is valid
|
|
||||||
if (include_center) neighborhood.push_back(location);
|
|
||||||
|
|
||||||
// N, E, S, W
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord2D(x, y - 1));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord2D(x, y + 1));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord2D(x + 1, y));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto new_location = coord_wrap(GridCoord2D(x - 1, y));
|
|
||||||
if (is_location_valid(new_location))
|
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighborhood_type == GridNeighborhoodType::Moore) {
|
GridCoord2D Grid2D::get_location_by_agent(AgentID agent_id) const {
|
||||||
// NE, SE, SW, NW
|
return _agent_index->at(agent_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Grid2D::move_agent(AgentID agent_id, GridCoord2D coord) {
|
||||||
|
GridCoord2D current_location = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
|
if (delete_agent(agent_id, current_location))
|
||||||
|
return add_agent(agent_id, std::move(coord));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] bool Grid2D::get_wrap_x() const { return _wrap_x; }
|
||||||
|
[[maybe_unused]] bool Grid2D::get_wrap_y() const { return _wrap_y; }
|
||||||
|
|
||||||
|
std::vector<GridCoord2D> Grid2D::get_neighborhood(
|
||||||
|
AgentID agent_id, GridNeighborhoodType neighborhood_type,
|
||||||
|
bool includeCenter) const {
|
||||||
|
GridCoord2D location = get_location_by_agent(agent_id);
|
||||||
|
|
||||||
|
return get_neighborhood(location, neighborhood_type, includeCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GridCoord2D> Grid2D::get_neighborhood(const GridCoord2D& location, GridNeighborhoodType neighborhood_type, bool include_center) const {
|
||||||
|
std::vector<GridCoord2D> neighborhood;
|
||||||
|
auto x = location.get_x_location();
|
||||||
|
auto y = location.get_y_location();
|
||||||
|
|
||||||
|
// We assume our starting position is valid
|
||||||
|
if (include_center) neighborhood.push_back(location);
|
||||||
|
|
||||||
|
// N, E, S, W
|
||||||
{
|
{
|
||||||
auto new_location = coord_wrap(GridCoord2D(x + 1, y - 1));
|
auto new_location = coord_wrap(GridCoord2D(x, y - 1));
|
||||||
if (is_location_valid(new_location))
|
if (is_location_valid(new_location))
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto new_location = coord_wrap(GridCoord2D(x + 1, y + 1));
|
auto new_location = coord_wrap(GridCoord2D(x, y + 1));
|
||||||
if (is_location_valid(new_location))
|
if (is_location_valid(new_location))
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto new_location = coord_wrap(GridCoord2D(x - 1, y + 1));
|
auto new_location = coord_wrap(GridCoord2D(x + 1, y));
|
||||||
if (is_location_valid(new_location))
|
if (is_location_valid(new_location))
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto new_location = coord_wrap(GridCoord2D(x - 1, y - 1));
|
auto new_location = coord_wrap(GridCoord2D(x - 1, y));
|
||||||
if (is_location_valid(new_location))
|
if (is_location_valid(new_location))
|
||||||
neighborhood.push_back(coord_wrap(new_location));
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (neighborhood_type == GridNeighborhoodType::Moore) {
|
||||||
|
// NE, SE, SW, NW
|
||||||
|
{
|
||||||
|
auto new_location = coord_wrap(GridCoord2D(x + 1, y - 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto new_location = coord_wrap(GridCoord2D(x + 1, y + 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto new_location = coord_wrap(GridCoord2D(x - 1, y + 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto new_location = coord_wrap(GridCoord2D(x - 1, y - 1));
|
||||||
|
if (is_location_valid(new_location))
|
||||||
|
neighborhood.push_back(coord_wrap(new_location));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighborhood;
|
||||||
}
|
}
|
||||||
|
|
||||||
return neighborhood;
|
std::vector<AgentID> *Grid2D::get_location_contents(const GridCoord2D& coord) const {
|
||||||
}
|
if (is_location_valid(coord) && !is_location_empty(coord))
|
||||||
|
return &_agent_grid[coord.get_x_location()][coord.get_y_location()];
|
||||||
|
|
||||||
std::vector<AgentID> *Grid2D::get_location_contents(
|
return nullptr;
|
||||||
GridCoord2D location) const {
|
|
||||||
if (is_location_valid(location) && !is_location_empty(location)) {
|
|
||||||
return &_agent_grid[location.get_x_location()]
|
|
||||||
[location.get_y_location()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
[[maybe_unused]] unsigned int Grid2D::get_maximum_x() const { return _maximum_x; }
|
||||||
}
|
[[maybe_unused]] unsigned int Grid2D::get_maximum_y() const { return _maximum_y; }
|
||||||
|
|
||||||
unsigned int Grid2D::get_maximum_x(void) const { return _maximum_x; }
|
GridCoord2D Grid2D::coord_wrap(const GridCoord2D& coord) const {
|
||||||
unsigned int Grid2D::get_maximum_y(void) const { return _maximum_y; }
|
auto x = coord.get_x_location();
|
||||||
|
auto y = coord.get_y_location();
|
||||||
|
|
||||||
GridCoord2D Grid2D::coord_wrap(GridCoord2D location) const {
|
if (_wrap_x)
|
||||||
auto x = location.get_x_location();
|
x = (x + static_cast<int>(_maximum_x)) % static_cast<int>(_maximum_x);
|
||||||
auto y = location.get_y_location();
|
if (_wrap_x)
|
||||||
|
y = (y + static_cast<int>(_maximum_y)) % static_cast<int>(_maximum_y);
|
||||||
|
return {x, y};
|
||||||
|
}
|
||||||
|
|
||||||
if (_wrap_x)
|
bool Grid2D::is_location_empty(const GridCoord2D& coord) const {
|
||||||
x = (x + static_cast<int>(_maximum_x)) % static_cast<int>(_maximum_x);
|
auto x = coord.get_x_location();
|
||||||
if (_wrap_x)
|
auto y = coord.get_y_location();
|
||||||
y = (y + static_cast<int>(_maximum_y)) % static_cast<int>(_maximum_y);
|
|
||||||
return GridCoord2D(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Grid2D::is_location_empty(GridCoord2D location) const {
|
return _agent_grid[x][y].empty();
|
||||||
auto x = location.get_x_location();
|
}
|
||||||
auto y = location.get_y_location();
|
|
||||||
|
|
||||||
return _agent_grid[x][y].size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -25,21 +25,19 @@
|
|||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
#include <kami/domain.h>
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid1d.h>
|
#include <kami/grid1d.h>
|
||||||
#include <kami/kami.h>
|
|
||||||
#include <kami/multigrid1d.h>
|
#include <kami/multigrid1d.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
bool MultiGrid1D::add_agent(AgentID agent_id, GridCoord1D coord) {
|
bool MultiGrid1D::add_agent(AgentID agent_id, GridCoord1D coord) {
|
||||||
if (is_location_valid(coord)) {
|
if (is_location_valid(coord)) {
|
||||||
_agent_index->insert(std::pair<AgentID, GridCoord1D>(agent_id, coord));
|
_agent_index->insert(std::pair<AgentID, GridCoord1D>(agent_id, coord));
|
||||||
_agent_grid[coord.get_x_location()].push_back(agent_id);
|
_agent_grid[coord.get_x_location()].push_back(agent_id);
|
||||||
return (true);
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -25,26 +25,20 @@
|
|||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
#include <kami/domain.h>
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid2d.h>
|
#include <kami/grid2d.h>
|
||||||
#include <kami/kami.h>
|
|
||||||
#include <kami/multigrid2d.h>
|
#include <kami/multigrid2d.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
MultiGrid2D::MultiGrid2D(unsigned int maximum_x, unsigned int maximum_y,
|
bool MultiGrid2D::add_agent(AgentID agent_id, GridCoord2D coord) {
|
||||||
bool wrap_x, bool wrap_y)
|
if (is_location_valid(coord)) {
|
||||||
: Grid2D(maximum_x, maximum_y, wrap_x, wrap_y) {}
|
_agent_index->insert(std::pair<AgentID, GridCoord2D>(agent_id, coord));
|
||||||
|
_agent_grid[coord.get_x_location()][coord.get_y_location()].push_back(
|
||||||
|
agent_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MultiGrid2D::add_agent(AgentID agent_id, GridCoord2D coord) {
|
return false;
|
||||||
if (is_location_valid(coord)) {
|
|
||||||
_agent_index->insert(std::pair<AgentID, GridCoord2D>(agent_id, coord));
|
|
||||||
_agent_grid[coord.get_x_location()][coord.get_y_location()].push_back(
|
|
||||||
agent_id);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -23,35 +23,29 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kami/agent.h>
|
|
||||||
#include <kami/model.h>
|
|
||||||
#include <kami/random.h>
|
|
||||||
#include <kami/scheduler.h>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <iostream>
|
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <kami/model.h>
|
||||||
|
#include <kami/random.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
RandomScheduler::RandomScheduler(Model *model) : SequentialScheduler(model) {}
|
RandomScheduler::RandomScheduler(Model *model, std::shared_ptr<std::mt19937> rng)
|
||||||
|
: SequentialScheduler(model) {
|
||||||
|
this->set_rng(std::move(rng));
|
||||||
|
}
|
||||||
|
|
||||||
RandomScheduler::RandomScheduler(Model *model,
|
void RandomScheduler::step() {
|
||||||
std::shared_ptr<std::mt19937> rng)
|
shuffle(_agent_list.begin(), _agent_list.end(), *_rng);
|
||||||
: SequentialScheduler(model) {
|
this->SequentialScheduler::step();
|
||||||
this->set_rng(rng);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void RandomScheduler::step() {
|
void RandomScheduler::set_rng(std::shared_ptr<std::mt19937> rng) {
|
||||||
shuffle(_agent_list.begin(), _agent_list.end(), *_rng);
|
this->_rng = std::move(rng);
|
||||||
this->SequentialScheduler::step();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void RandomScheduler::set_rng(std::shared_ptr<std::mt19937> rng) {
|
[[maybe_unused]] std::shared_ptr<std::mt19937> RandomScheduler::get_rng() { return (_rng); }
|
||||||
this->_rng = rng;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<std::mt19937> RandomScheduler::get_rng() { return (_rng); }
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -23,42 +23,37 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/model.h>
|
#include <kami/model.h>
|
||||||
#include <kami/scheduler.h>
|
|
||||||
#include <kami/sequential.h>
|
#include <kami/sequential.h>
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
SequentialScheduler::SequentialScheduler(Model *model) {
|
SequentialScheduler::SequentialScheduler(Model *model) {
|
||||||
_step_counter = 0;
|
_step_counter = 0;
|
||||||
_model = model;
|
_model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequentialScheduler::add_agent(AgentID agent_id) {
|
void SequentialScheduler::add_agent(AgentID agent_id) {
|
||||||
_agent_list.push_back(agent_id);
|
_agent_list.push_back(agent_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequentialScheduler::delete_agent(AgentID agent_id) {
|
void SequentialScheduler::delete_agent(AgentID agent_id) {
|
||||||
for (auto agent_list_iter = _agent_list.begin();
|
for (auto agent_list_iter = _agent_list.begin(); agent_list_iter < _agent_list.end(); agent_list_iter++)
|
||||||
agent_list_iter < _agent_list.end(); agent_list_iter++)
|
if (*agent_list_iter == agent_id) _agent_list.erase(agent_list_iter);
|
||||||
if (*agent_list_iter == agent_id) _agent_list.erase(agent_list_iter);
|
// ERROR HERE
|
||||||
return;
|
}
|
||||||
|
|
||||||
// ERROR HERE
|
void SequentialScheduler::step() {
|
||||||
}
|
_step_counter++;
|
||||||
|
|
||||||
void SequentialScheduler::step() {
|
for (auto agent_list_iter = _agent_list.begin();
|
||||||
_step_counter++;
|
agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
||||||
|
Agent *agent = _model->get_agent_by_id(*agent_list_iter);
|
||||||
for (auto agent_list_iter = _agent_list.begin();
|
if (agent != nullptr) agent->step();
|
||||||
agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
}
|
||||||
Agent *agent = _model->get_agent_by_id(*agent_list_iter);
|
|
||||||
if (agent != nullptr) agent->step();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -24,22 +24,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid1d.h>
|
|
||||||
#include <kami/kami.h>
|
|
||||||
#include <kami/sologrid1d.h>
|
#include <kami/sologrid1d.h>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
bool SoloGrid1D::add_agent(AgentID agent_id, GridCoord1D coord) {
|
bool SoloGrid1D::add_agent(AgentID agent_id, GridCoord1D coord) {
|
||||||
if (is_location_valid(coord) & is_location_empty(coord)) {
|
if (is_location_valid(coord) & is_location_empty(coord)) {
|
||||||
_agent_index->insert(std::pair<AgentID, GridCoord1D>(agent_id, coord));
|
_agent_index->insert(std::pair<AgentID, GridCoord1D>(agent_id, coord));
|
||||||
_agent_grid[coord.get_x_location()].push_back(agent_id);
|
_agent_grid[coord.get_x_location()].push_back(agent_id);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -24,29 +24,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/domain.h>
|
|
||||||
#include <kami/grid.h>
|
|
||||||
#include <kami/grid2d.h>
|
|
||||||
#include <kami/kami.h>
|
|
||||||
#include <kami/sologrid2d.h>
|
#include <kami/sologrid2d.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
SoloGrid2D::SoloGrid2D(unsigned int maximum_x, unsigned int maximum_y,
|
bool SoloGrid2D::add_agent(AgentID agent_id, GridCoord2D coord) {
|
||||||
bool wrap_x, bool wrap_y)
|
if (is_location_valid(coord) & is_location_empty(coord)) {
|
||||||
: Grid2D(maximum_x, maximum_y, wrap_x, wrap_y) {}
|
_agent_index->insert(std::pair<AgentID, GridCoord2D>(agent_id, coord));
|
||||||
|
_agent_grid[coord.get_x_location()][coord.get_y_location()].push_back(agent_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool SoloGrid2D::add_agent(AgentID agent_id, GridCoord2D coord) {
|
return false;
|
||||||
if (is_location_valid(coord) & is_location_empty(coord)) {
|
|
||||||
_agent_index->insert(std::pair<AgentID, GridCoord2D>(agent_id, coord));
|
|
||||||
_agent_grid[coord.get_x_location()][coord.get_y_location()].push_back(
|
|
||||||
agent_id);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -23,55 +23,40 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/model.h>
|
#include <kami/model.h>
|
||||||
#include <kami/scheduler.h>
|
|
||||||
#include <kami/sequential.h>
|
|
||||||
#include <kami/staged.h>
|
#include <kami/staged.h>
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace kami {
|
namespace kami {
|
||||||
|
|
||||||
StagedScheduler::StagedScheduler(Model *model) {
|
StagedScheduler::StagedScheduler(Model *model) {
|
||||||
_step_counter = 0;
|
_step_counter = 0;
|
||||||
_model = model;
|
_model = model;
|
||||||
}
|
|
||||||
|
|
||||||
StagedScheduler::~StagedScheduler() {}
|
|
||||||
|
|
||||||
void StagedScheduler::add_agent(AgentID agent_id) {
|
|
||||||
_agent_list.push_back(agent_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StagedScheduler::delete_agent(AgentID agent_id) {
|
|
||||||
for (auto agent_list_iter = _agent_list.begin();
|
|
||||||
agent_list_iter < _agent_list.end(); agent_list_iter++)
|
|
||||||
if (*agent_list_iter == agent_id) _agent_list.erase(agent_list_iter);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StagedScheduler::step() {
|
|
||||||
_step_counter++;
|
|
||||||
|
|
||||||
for (auto agent_list_iter = _agent_list.begin();
|
|
||||||
agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
|
||||||
StagedAgent *agent = dynamic_cast<StagedAgent *>(
|
|
||||||
_model->get_agent_by_id(*agent_list_iter));
|
|
||||||
if (agent != nullptr) agent->step();
|
|
||||||
// ERROR HERE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto agent_list_iter = _agent_list.begin();
|
void StagedScheduler::add_agent(AgentID agent_id) {
|
||||||
agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
_agent_list.push_back(agent_id);
|
||||||
StagedAgent *agent = dynamic_cast<StagedAgent *>(
|
|
||||||
_model->get_agent_by_id(*agent_list_iter));
|
|
||||||
if (agent != nullptr) agent->advance();
|
|
||||||
// ERROR HERE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
void StagedScheduler::delete_agent(AgentID agent_id) {
|
||||||
}
|
for (auto agent_list_iter = _agent_list.begin(); agent_list_iter < _agent_list.end(); agent_list_iter++)
|
||||||
|
if (*agent_list_iter == agent_id) _agent_list.erase(agent_list_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StagedScheduler::step() {
|
||||||
|
_step_counter++;
|
||||||
|
|
||||||
|
for (auto agent_list_iter = _agent_list.begin(); agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
||||||
|
auto *agent = dynamic_cast<StagedAgent *>(_model->get_agent_by_id(*agent_list_iter));
|
||||||
|
if (agent != nullptr) agent->step();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto agent_list_iter = _agent_list.begin(); agent_list_iter < _agent_list.end(); agent_list_iter++) {
|
||||||
|
auto *agent = dynamic_cast<StagedAgent *>(_model->get_agent_by_id(*agent_list_iter));
|
||||||
|
if (agent != nullptr) agent->advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace kami
|
} // namespace kami
|
||||||
|
|||||||
@@ -23,21 +23,23 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/config.h>
|
#include <kami/config.h>
|
||||||
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
#include <CLI/Config.hpp>
|
#include <CLI/Config.hpp>
|
||||||
#include <CLI/Formatter.hpp>
|
#include <CLI/Formatter.hpp>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace kami;
|
using namespace kami;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class TestAgent : public Agent {
|
class TestAgent : public Agent {
|
||||||
void step(){};
|
void step() override {};
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
@@ -46,15 +48,12 @@ int main(int argc, char **argv) {
|
|||||||
auto console = spdlog::stdout_color_st(ident);
|
auto console = spdlog::stdout_color_st(ident);
|
||||||
string logLevelOption = "info";
|
string logLevelOption = "info";
|
||||||
|
|
||||||
app.add_option("-l", logLevelOption, "Set the logging level")
|
app.add_option("-l", logLevelOption, "Set the logging level")->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
||||||
->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
console->set_level(spdlog::level::from_str(logLevelOption));
|
console->set_level(spdlog::level::from_str(logLevelOption));
|
||||||
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING,
|
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING, logLevelOption);
|
||||||
logLevelOption);
|
|
||||||
|
|
||||||
TestAgent test_agent;
|
TestAgent test_agent;
|
||||||
console->debug("Successfully created Agent with ID {}",
|
console->debug("Successfully created Agent with ID {}", test_agent.get_agent_id().to_string());
|
||||||
test_agent.get_agent_id().to_string());
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,15 +23,17 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <kami/agent.h>
|
#include <kami/agent.h>
|
||||||
#include <kami/config.h>
|
#include <kami/config.h>
|
||||||
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include <CLI/App.hpp>
|
#include <CLI/App.hpp>
|
||||||
#include <CLI/Config.hpp>
|
#include <CLI/Config.hpp>
|
||||||
#include <CLI/Formatter.hpp>
|
#include <CLI/Formatter.hpp>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
using namespace kami;
|
using namespace kami;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -42,15 +44,12 @@ int main(int argc, char **argv) {
|
|||||||
auto console = spdlog::stdout_color_st(ident);
|
auto console = spdlog::stdout_color_st(ident);
|
||||||
string logLevelOption = "info";
|
string logLevelOption = "info";
|
||||||
|
|
||||||
app.add_option("-l", logLevelOption, "Set the logging level")
|
app.add_option("-l", logLevelOption, "Set the logging level")->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
||||||
->check(CLI::IsMember(SPDLOG_LEVEL_NAMES));
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
console->set_level(spdlog::level::from_str(logLevelOption));
|
console->set_level(spdlog::level::from_str(logLevelOption));
|
||||||
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING,
|
console->info("Compiled with Kami/{}, log level {}", KAMI_VERSION_STRING, logLevelOption);
|
||||||
logLevelOption);
|
|
||||||
|
|
||||||
AgentID testAgentID;
|
AgentID testAgentID;
|
||||||
console->debug("Successfully created AgentID with ID {}",
|
console->debug("Successfully created AgentID with ID {}", testAgentID.to_string());
|
||||||
testAgentID.to_string());
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user