Initial code findings
This commit is contained in:
17
src/ant.cpp
17
src/ant.cpp
@ -1,10 +1,6 @@
|
|||||||
#include "ant.hpp"
|
#include "ant.hpp"
|
||||||
#include "pheromone_map.hpp"
|
|
||||||
#include <cmath>
|
|
||||||
#include <iostream>
|
|
||||||
#include <numbers>
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
|
// TODO: Should every ant have its own random generators? Why not initialize with coordinates and put the random numbers in there (from main)
|
||||||
Ant::Ant(PheromoneMap& pheromones, double x, double y)
|
Ant::Ant(PheromoneMap& pheromones, double x, double y)
|
||||||
: WorldObject(x, y, 3, sf::Color::Black), pheromones(pheromones) {
|
: WorldObject(x, y, 3, sf::Color::Black), pheromones(pheromones) {
|
||||||
std::random_device rd; // obtain a random number from hardware
|
std::random_device rd; // obtain a random number from hardware
|
||||||
@ -14,7 +10,7 @@ Ant::Ant(PheromoneMap& pheromones, double x, double y)
|
|||||||
direction = degree_distribution(gen);
|
direction = degree_distribution(gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ant::Ant(PheromoneMap& pheromones, unsigned short direction)
|
Ant::Ant(PheromoneMap& pheromones, unsigned int direction)
|
||||||
: WorldObject(0, 0, 3, sf::Color::Black), direction(direction),
|
: WorldObject(0, 0, 3, sf::Color::Black), direction(direction),
|
||||||
pheromones(pheromones) {
|
pheromones(pheromones) {
|
||||||
std::random_device device; // obtain a random number from hardware
|
std::random_device device; // obtain a random number from hardware
|
||||||
@ -46,6 +42,7 @@ Ant::Ant(PheromoneMap& pheromones)
|
|||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Unnecessary, only used for food/base
|
||||||
void Ant::addToUmwelt(const std::shared_ptr<WorldObject>& object) {
|
void Ant::addToUmwelt(const std::shared_ptr<WorldObject>& object) {
|
||||||
umwelt.push_back(object);
|
umwelt.push_back(object);
|
||||||
}
|
}
|
||||||
@ -78,8 +75,10 @@ void Ant::move() {
|
|||||||
attractor = NONE;
|
attractor = NONE;
|
||||||
}
|
}
|
||||||
for (const Pheromone& pheromone : pheromones.getInVision(*this, attractor, view_distance)) {
|
for (const Pheromone& pheromone : pheromones.getInVision(*this, attractor, view_distance)) {
|
||||||
|
// TODO: What is this supposed to do?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Should this random generator be created on every move?
|
||||||
std::random_device device; // obtain a random number from hardware
|
std::random_device device; // obtain a random number from hardware
|
||||||
std::mt19937 generator(device()); // seed the generator
|
std::mt19937 generator(device()); // seed the generator
|
||||||
|
|
||||||
@ -87,7 +86,8 @@ void Ant::move() {
|
|||||||
std::uniform_real_distribution<> degree_distribution(-std::numbers::pi,
|
std::uniform_real_distribution<> degree_distribution(-std::numbers::pi,
|
||||||
std::numbers::pi);
|
std::numbers::pi);
|
||||||
|
|
||||||
direction += degree_distribution(generator) * (1 / determination);
|
direction += degree_distribution(generator) * (1 / determination); // Normalize with determination to smooth movement
|
||||||
|
// TODO: Use modulo
|
||||||
if (direction > 2 * std::numbers::pi) {
|
if (direction > 2 * std::numbers::pi) {
|
||||||
direction -= 2 * std::numbers::pi;
|
direction -= 2 * std::numbers::pi;
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ void Ant::updatePheromones() {
|
|||||||
dropPheromone();
|
dropPheromone();
|
||||||
next_pheromone_drop = pheromone_interval + 1;
|
next_pheromone_drop = pheromone_interval + 1;
|
||||||
}
|
}
|
||||||
next_pheromone_drop = std::max(0, next_pheromone_drop - 1);
|
next_pheromone_drop = std::max(0U, next_pheromone_drop - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
PheroType Ant::getPheromoneType() const {
|
PheroType Ant::getPheromoneType() const {
|
||||||
@ -121,6 +121,7 @@ void Ant::dropPheromone() {
|
|||||||
pheromones.place(x, y, pheromone_type);
|
pheromones.place(x, y, pheromone_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This is weird
|
||||||
void Ant::updateUmwelt() {
|
void Ant::updateUmwelt() {
|
||||||
for (std::shared_ptr<WorldObject> const& obj : umwelt) {
|
for (std::shared_ptr<WorldObject> const& obj : umwelt) {
|
||||||
if (obj->collides(*this)) {
|
if (obj->collides(*this)) {
|
||||||
|
28
src/ant.hpp
28
src/ant.hpp
@ -1,37 +1,43 @@
|
|||||||
#ifndef H_ANT
|
#ifndef H_ANT
|
||||||
#define H_ANT
|
#define H_ANT
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "colony.hpp"
|
#include "colony.hpp"
|
||||||
#include "food.hpp"
|
#include "food.hpp"
|
||||||
#include "pheromone_map.hpp"
|
#include "pheromone_map.hpp"
|
||||||
#include "world_object.hpp"
|
#include "world_object.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <numbers>
|
||||||
|
#include <random>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
const double speed = 1;
|
const double speed = 1;
|
||||||
const double determination = 25; // straightness of the path, (0, 1]
|
const double determination = 25; // straightness of the path
|
||||||
const unsigned short pheromone_interval = 5; // updates between drops
|
const unsigned int pheromone_interval = 5; // how many updates between drops
|
||||||
|
|
||||||
const unsigned short view_angle = 45; // angle degrees to each side
|
const unsigned int view_angle = 45; // angle degrees to each side
|
||||||
const unsigned short view_distance = 25;
|
const unsigned int view_distance = 25; // more like smell distance
|
||||||
|
|
||||||
class Ant : public WorldObject {
|
class Ant : public WorldObject {
|
||||||
double direction; // in radians
|
double direction; // in radians
|
||||||
|
|
||||||
|
// TODO: Should this be here or just global?
|
||||||
PheromoneMap& pheromones;
|
PheromoneMap& pheromones;
|
||||||
unsigned short next_pheromone_drop = 0;
|
unsigned int next_pheromone_drop = 0;
|
||||||
PheroType pheromone_type = NONE; // FOOD, HOME, NONE
|
PheroType pheromone_type = NONE; // FOOD, HOME, NONE
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// TODO: Why is this stored here? I guess it can be removed
|
||||||
std::vector<std::shared_ptr<WorldObject>> umwelt;
|
std::vector<std::shared_ptr<WorldObject>> umwelt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ant(PheromoneMap& pheromones, double x, double y);
|
Ant(PheromoneMap& pheromones, double x, double y);
|
||||||
Ant(PheromoneMap& pheromones, unsigned short direction);
|
Ant(PheromoneMap& pheromones, unsigned int direction);
|
||||||
explicit Ant(PheromoneMap& pheromones);
|
explicit Ant(PheromoneMap& pheromones);
|
||||||
|
|
||||||
|
// TODO: Regarding umwelt
|
||||||
void addToUmwelt(const std::shared_ptr<WorldObject>& object);
|
void addToUmwelt(const std::shared_ptr<WorldObject>& object);
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
@ -41,6 +47,8 @@ public:
|
|||||||
void updateAppearance();
|
void updateAppearance();
|
||||||
void updatePheromones();
|
void updatePheromones();
|
||||||
void dropPheromone(); // red
|
void dropPheromone(); // red
|
||||||
|
|
||||||
|
// TODO: Regarding umwelt
|
||||||
void updateUmwelt();
|
void updateUmwelt();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ public:
|
|||||||
Colony(double x, double y);
|
Colony(double x, double y);
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
PheroType getPheromoneType() const override;
|
PheroType getPheromoneType() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ public:
|
|||||||
Food(double x, double y);
|
Food(double x, double y);
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
PheroType getPheromoneType() const override;
|
PheroType getPheromoneType() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
15
src/main.cpp
15
src/main.cpp
@ -11,11 +11,11 @@
|
|||||||
#include "pheromone.hpp"
|
#include "pheromone.hpp"
|
||||||
#include "pheromone_map.hpp"
|
#include "pheromone_map.hpp"
|
||||||
|
|
||||||
const unsigned short HEIGHT = 500;
|
const unsigned int HEIGHT = 500;
|
||||||
const unsigned short WIDTH = 500;
|
const unsigned int WIDTH = 500;
|
||||||
const unsigned short FPS = 60;
|
const unsigned int FPS = 60;
|
||||||
|
|
||||||
const unsigned short ANTCOUNT = 100;
|
const unsigned int ANTCOUNT = 100;
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
sf::ContextSettings settings;
|
sf::ContextSettings settings;
|
||||||
@ -24,8 +24,8 @@ int main(int argc, char* argv[]) {
|
|||||||
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Ants", sf::Style::Close, settings);
|
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Ants", sf::Style::Close, settings);
|
||||||
window.setFramerateLimit(FPS); // Limit FPS
|
window.setFramerateLimit(FPS); // Limit FPS
|
||||||
|
|
||||||
float t = 0.0; // Verstrichene Zeit in ms
|
double t = 0.0; // Verstrichene Zeit in ms
|
||||||
float dt = 1.0 / FPS; // Schrittweite in ms
|
double dt = 1.0 / FPS; // Schrittweite in ms
|
||||||
|
|
||||||
PheromoneMap pheromones;
|
PheromoneMap pheromones;
|
||||||
std::vector<std::unique_ptr<Ant>> ants; // Use pointer bc we can't instatiate abstract classes
|
std::vector<std::unique_ptr<Ant>> ants; // Use pointer bc we can't instatiate abstract classes
|
||||||
@ -42,8 +42,9 @@ int main(int argc, char* argv[]) {
|
|||||||
ant->addToUmwelt(foodA);
|
ant->addToUmwelt(foodA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main event loop
|
|
||||||
while (window.isOpen()) {
|
while (window.isOpen()) {
|
||||||
|
// Main event loop
|
||||||
|
|
||||||
sf::Event event {};
|
sf::Event event {};
|
||||||
|
|
||||||
while (window.pollEvent(event)) {
|
while (window.pollEvent(event)) {
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "pheromone.hpp"
|
#include "pheromone.hpp"
|
||||||
#include "world_object.hpp"
|
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
|
|
||||||
Pheromone::Pheromone(double x, double y, PheroType type)
|
Pheromone::Pheromone(double x, double y, PheroType type)
|
||||||
: WorldObject(x, y, 2, sf::Color::Transparent) {
|
: WorldObject(x, y, 2, sf::Color::Transparent) {
|
||||||
@ -28,7 +26,7 @@ PheroType Pheromone::getPheromoneType() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Pheromone::update() {
|
void Pheromone::update() {
|
||||||
intensity = std::max(0, intensity - decay);
|
intensity = std::max(0U, intensity - decay);
|
||||||
appearance.setFillColor(sf::Color(
|
appearance.setFillColor(sf::Color(
|
||||||
appearance.getFillColor().r,
|
appearance.getFillColor().r,
|
||||||
appearance.getFillColor().g,
|
appearance.getFillColor().g,
|
||||||
|
@ -8,13 +8,14 @@
|
|||||||
#include "world_object.hpp"
|
#include "world_object.hpp"
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
const unsigned short decay = 1;
|
// TODO: Use percentage
|
||||||
|
const unsigned int decay = 1;
|
||||||
|
|
||||||
class Pheromone : public WorldObject {
|
class Pheromone : public WorldObject {
|
||||||
public:
|
public:
|
||||||
unsigned short intensity = 255;
|
// TODO: Use 1.0 to 0.0 double
|
||||||
|
unsigned int intensity = 255;
|
||||||
|
|
||||||
public:
|
|
||||||
Pheromone(double x, double y, PheroType type);
|
Pheromone(double x, double y, PheroType type);
|
||||||
|
|
||||||
PheroType getPheromoneType() const override;
|
PheroType getPheromoneType() const override;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#include "pheromone_map.hpp"
|
#include "pheromone_map.hpp"
|
||||||
#include "ant.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void PheromoneMap::place(double x, double y, PheroType type) {
|
void PheromoneMap::place(double x, double y, PheroType type) {
|
||||||
pheromones.emplace_back(x, y, type);
|
pheromones.emplace_back(x, y, type);
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#ifndef __PHEROMONES_H_
|
#ifndef __PHEROMONES_H_
|
||||||
#define __PHEROMONES_H_
|
#define __PHEROMONES_H_
|
||||||
|
|
||||||
|
#include "ant.hpp"
|
||||||
#include "pheromone.hpp"
|
#include "pheromone.hpp"
|
||||||
|
#include <iostream>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -9,12 +11,12 @@ class Ant;
|
|||||||
|
|
||||||
class PheromoneMap {
|
class PheromoneMap {
|
||||||
public:
|
public:
|
||||||
|
// TODO: Use fixed size matrix (and only int locations) for this, currently it's just slow
|
||||||
std::vector<Pheromone> pheromones;
|
std::vector<Pheromone> pheromones;
|
||||||
|
|
||||||
public:
|
// TODO: Move this to ant
|
||||||
void place(double x, double y, PheroType type);
|
|
||||||
std::vector<Pheromone> getInVision(const Ant& ant, PheroType type, unsigned short radius);
|
std::vector<Pheromone> getInVision(const Ant& ant, PheroType type, unsigned short radius);
|
||||||
|
void place(double x, double y, PheroType type);
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "world_object.hpp"
|
#include "world_object.hpp"
|
||||||
|
|
||||||
WorldObject::WorldObject(double x, double y, unsigned short radius, sf::Color color)
|
WorldObject::WorldObject(double x, double y, unsigned int radius, sf::Color color)
|
||||||
: x(x), y(y), radius(radius) {
|
: x(x), y(y), radius(radius) {
|
||||||
appearance = sf::CircleShape(radius);
|
appearance = sf::CircleShape(radius);
|
||||||
appearance.setFillColor(color);
|
appearance.setFillColor(color);
|
||||||
|
@ -4,9 +4,11 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
extern const unsigned short WIDTH;
|
// TODO: Move definitions to header and use constexpr/macro
|
||||||
extern const unsigned short HEIGHT;
|
extern const unsigned int WIDTH;
|
||||||
|
extern const unsigned int HEIGHT;
|
||||||
|
|
||||||
|
// TODO: Just use FOOD
|
||||||
enum PheroType {
|
enum PheroType {
|
||||||
FOOD,
|
FOOD,
|
||||||
HOME,
|
HOME,
|
||||||
@ -16,24 +18,21 @@ enum PheroType {
|
|||||||
class WorldObject {
|
class WorldObject {
|
||||||
protected:
|
protected:
|
||||||
double x, y;
|
double x, y;
|
||||||
const unsigned short radius;
|
const unsigned int radius;
|
||||||
|
|
||||||
|
WorldObject(double x, double y, unsigned int radius, sf::Color color);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sf::CircleShape appearance;
|
sf::CircleShape appearance;
|
||||||
|
|
||||||
protected:
|
bool isOffScreen() const;
|
||||||
WorldObject(double x, double y, unsigned short radius, sf::Color color);
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool isOffScreen() const; // virtual: late-binding, no static linkage
|
|
||||||
bool collides(const WorldObject& other) const;
|
bool collides(const WorldObject& other) const;
|
||||||
|
|
||||||
double distance(const WorldObject& other) const;
|
double distance(const WorldObject& other) const;
|
||||||
|
|
||||||
double angle(const WorldObject& other) const;
|
double angle(const WorldObject& other) const;
|
||||||
|
|
||||||
virtual void update() = 0; // pure virtual: has to be overridden
|
// TODO: Switch to only food pheromones
|
||||||
virtual PheroType getPheromoneType() const = 0;
|
virtual PheroType getPheromoneType() const = 0;
|
||||||
|
virtual void update() = 0; // pure virtual: has to be overridden
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __OBJECT_H_
|
#endif // __OBJECT_H_
|
||||||
|
Reference in New Issue
Block a user