redo pheromones

This commit is contained in:
churl
2021-04-12 01:35:42 +02:00
parent 8d704ec1fc
commit edbcaa0a6e
10 changed files with 75 additions and 79 deletions

View File

@ -1,12 +1,12 @@
#include "ant.hpp" #include "ant.hpp"
#include "pheromones.hpp" #include "pheromone_map.hpp"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <numbers> #include <numbers>
#include <random> #include <random>
Ant::Ant(Pheromones& pheromones, double x, double y) Ant::Ant(PheromoneMap& pheromones, double x, double y)
: WorldObject(x, y, 2, 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
std::mt19937 gen(rd()); // seed the generator std::mt19937 gen(rd()); // seed the generator
@ -14,8 +14,8 @@ Ant::Ant(Pheromones& pheromones, double x, double y)
direction = degree_distribution(gen); direction = degree_distribution(gen);
} }
Ant::Ant(Pheromones& pheromones, unsigned short direction) Ant::Ant(PheromoneMap& pheromones, unsigned short direction)
: WorldObject(0, 0, 2, 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
std::mt19937 generator(device()); // seed the generator std::mt19937 generator(device()); // seed the generator
@ -29,8 +29,8 @@ Ant::Ant(Pheromones& pheromones, unsigned short direction)
updateAppearance(); updateAppearance();
} }
Ant::Ant(Pheromones& pheromones) Ant::Ant(PheromoneMap& pheromones)
: WorldObject(0, 0, 2, sf::Color::Black), pheromones(pheromones) { : WorldObject(0, 0, 3, sf::Color::Black), pheromones(pheromones) {
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
@ -46,7 +46,7 @@ Ant::Ant(Pheromones& pheromones)
updateAppearance(); updateAppearance();
} }
void Ant::addToUmwelt(std::shared_ptr<WorldObject> object) { void Ant::addToUmwelt(const std::shared_ptr<WorldObject>& object) {
umwelt.push_back(object); umwelt.push_back(object);
} }
@ -69,11 +69,16 @@ void Ant::update() {
} }
void Ant::move() { void Ant::move() {
// TODO: Leftoff, add ant-vision lol PheroType attractor;
for (int i = x; i < WIDTH * HEIGHT; ++i) { if (pheromone_type == HOME) {
if (true) { attractor = FOOD;
} else if (pheromone_type == FOOD) {
attractor = HOME;
} else {
attractor = NONE;
} }
for (const Pheromone& pheromone : pheromones.getInVision(*this, attractor, view_distance)) {
} }
std::random_device device; // obtain a random number from hardware std::random_device device; // obtain a random number from hardware
@ -104,13 +109,13 @@ void Ant::updatePheromones() {
next_pheromone_drop = std::max(0, next_pheromone_drop - 1); next_pheromone_drop = std::max(0, next_pheromone_drop - 1);
} }
sf::Color Ant::getPheromoneType() const { PheroType Ant::getPheromoneType() const {
return sf::Color::Transparent; return NONE;
} }
void Ant::dropPheromone() { void Ant::dropPheromone() {
if (isOffScreen()) { if (isOffScreen()) {
std::cout << "Ant can't drop Pheromones offscreen!" << std::endl; std::cout << "Ant can't drop PheromoneMap offscreen!" << std::endl;
return; return;
} }

View File

@ -6,7 +6,7 @@
#include <memory> #include <memory>
#include "world_object.hpp" #include "world_object.hpp"
#include "pheromones.hpp" #include "pheromone_map.hpp"
#include "colony.hpp" #include "colony.hpp"
#include "food.hpp" #include "food.hpp"
@ -21,22 +21,22 @@ class Ant : public WorldObject
{ {
double direction; // in radians double direction; // in radians
Pheromones& pheromones; PheromoneMap& pheromones;
unsigned short next_pheromone_drop = 0; unsigned short next_pheromone_drop = 0;
sf::Color pheromone_type = sf::Color::Transparent; // ANT, HOME, FOOD PheroType pheromone_type = NONE; // FOOD, HOME, NONE
public: public:
std::vector<std::shared_ptr<WorldObject>> umwelt; std::vector<std::shared_ptr<WorldObject>> umwelt;
public: public:
Ant(Pheromones& pheromones, double x, double y); Ant(PheromoneMap& pheromones, double x, double y);
Ant(Pheromones& pheromones, unsigned short direction); Ant(PheromoneMap& pheromones, unsigned short direction);
explicit Ant(Pheromones& pheromones); explicit Ant(PheromoneMap& pheromones);
void addToUmwelt(std::shared_ptr<WorldObject> object); void addToUmwelt(const std::shared_ptr<WorldObject>& object);
void update() override; void update() override;
sf::Color getPheromoneType() const override; PheroType getPheromoneType() const override;
void move(); void move();
void updateAppearance(); void updateAppearance();

View File

@ -4,6 +4,6 @@ Colony::Colony(double x, double y) : WorldObject(x, y, 25, sf::Color::Red) {}
void Colony::update() {} void Colony::update() {}
sf::Color Colony::getPheromoneType() const { PheroType Colony::getPheromoneType() const {
return sf::Color::Red; return HOME;
} }

View File

@ -12,7 +12,7 @@ public:
void update() override; void update() override;
sf::Color getPheromoneType() const override; PheroType getPheromoneType() const override;
}; };
#endif // __COLONY_H_ #endif // __COLONY_H_

View File

@ -4,6 +4,6 @@ Food::Food(double x, double y) : WorldObject(x, y, 15, sf::Color::Green) {}
void Food::update() {} void Food::update() {}
sf::Color Food::getPheromoneType() const { PheroType Food::getPheromoneType() const {
return sf::Color::Green; return FOOD;
} }

View File

@ -12,7 +12,7 @@ public:
void update() override; void update() override;
sf::Color getPheromoneType() const override; PheroType getPheromoneType() const override;
}; };
#endif // __FOOD_H_ #endif // __FOOD_H_

View File

@ -5,21 +5,21 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include "pheromones.hpp" #include "pheromone_map.hpp"
#include "world_object.hpp"
#include "ant.hpp" #include "ant.hpp"
#include "colony.hpp" #include "colony.hpp"
#include "food.hpp" #include "food.hpp"
#include "pheromone.hpp"
const unsigned short HEIGHT = 500; const unsigned short HEIGHT = 500;
const unsigned short WIDTH = 500; const unsigned short WIDTH = 500;
const unsigned short FPS = 60; const unsigned short FPS = 60;
const unsigned short ANTCOUNT = 500; const unsigned short ANTCOUNT = 100;
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
sf::ContextSettings settings; sf::ContextSettings settings;
// settings.antialiasingLevel = 8; settings.antialiasingLevel = 8;
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
@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
float t = 0.0; // Verstrichene Zeit in ms float t = 0.0; // Verstrichene Zeit in ms
float dt = 1.0 / FPS; // Schrittweite in ms float dt = 1.0 / FPS; // Schrittweite in ms
Pheromones 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
ants.reserve(ANTCOUNT); ants.reserve(ANTCOUNT);
@ -43,7 +43,7 @@ int main(int argc, char* argv[]) {
} }
while (window.isOpen()) { while (window.isOpen()) {
sf::Event event; sf::Event event{};
while (window.pollEvent(event)) { while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) { if (event.type == sf::Event::Closed) {
@ -53,14 +53,19 @@ int main(int argc, char* argv[]) {
// Update // Update
t += dt; t += dt;
pheromones.update();
for (std::unique_ptr<Ant> const& obj: ants) { for (std::unique_ptr<Ant> const& obj: ants) {
obj->update(); obj->update();
} }
pheromones.update(); for (Pheromone& pheromone : pheromones.pheromones) {
pheromone.update();
}
// Render // Render
window.clear(sf::Color::White); window.clear(sf::Color::White);
window.draw(pheromones.map); for (Pheromone& pheromone : pheromones.pheromones) {
window.draw(pheromone.appearance);
}
for (std::unique_ptr<Ant> const& obj: ants) { for (std::unique_ptr<Ant> const& obj: ants) {
window.draw(obj->appearance); window.draw(obj->appearance);
} }

View File

@ -1,41 +1,28 @@
#include <iostream>
#include "pheromone_map.hpp" #include "pheromone_map.hpp"
#include "ant.hpp"
extern const unsigned short WIDTH; void PheromoneMap::place(double x, double y, PheroType type) {
extern const unsigned short HEIGHT; pheromones.emplace_back(x, y, type);
PheromoneMap::PheromoneMap() {
for (unsigned short y = 0; y < HEIGHT; ++y) {
for (unsigned short x = 0; x < WIDTH; ++x) {
map[y * WIDTH + x].position.x = x;
map[y * WIDTH + x].position.y = y;
map[y * WIDTH + x].color = sf::Color(0, 0, 0, 0);
}
}
} }
void PheromoneMap::place(unsigned short x, unsigned short y, sf::Color col) { std::vector<Pheromone> PheromoneMap::getInVision(const Ant& ant, PheroType type, unsigned short radius) {
map[y * WIDTH + x].color = col; std::vector<Pheromone> umwelt;
// Have to check for off-limit-pixels for (const Pheromone& pheromone : pheromones) {
map[std::min(WIDTH * HEIGHT - 1, (y + 1) * WIDTH + x)].color = col; if (pheromone.getPheromoneType() == type
map[std::max(0, (y - 1) * WIDTH + x)].color = col; && pheromone.distance(ant) <= radius) {
map[std::min(WIDTH * HEIGHT - 1, y * WIDTH + (x + 1))].color = col; umwelt.push_back(pheromone);
map[std::max(0, y * WIDTH + (x - 1))].color = col; }
} }
sf::Color PheromoneMap::get(unsigned short x, unsigned short y) const { return umwelt;
// TODO: range-checks
return map[y * WIDTH + x].color;
} }
void PheromoneMap::update() { void PheromoneMap::update() {
for (int i = 0; i < WIDTH * HEIGHT; ++i) { for (size_t i = 0; i < pheromones.size(); ++i) {
map[i].color -= sf::Color(decay, decay, decay, decay); if (pheromones[i].appearance.getFillColor().a == 0) {
} // pheromones.erase(pheromones.begin() + i);
for (int x = 0; x < WIDTH; ++x) { }
map[(HEIGHT / 2) * WIDTH + x].color = sf::Color::Black;
}
for (int y = 0; y < HEIGHT; ++y) {
map[y * WIDTH + (WIDTH / 2)].color = sf::Color::Black;
} }
} }

View File

@ -5,21 +5,16 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include "pheromone.hpp" #include "pheromone.hpp"
extern const unsigned short WIDTH; class Ant;
extern const unsigned short HEIGHT;
const unsigned short decay = 1;
class PheromoneMap class PheromoneMap
{ {
public: public:
std::vector<Pheromone std::vector<Pheromone> pheromones;
public: public:
PheromoneMap(); void place(double x, double y, PheroType type);
std::vector<Pheromone> getInVision(const Ant& ant, PheroType type, unsigned short radius);
void place(unsigned short x, unsigned short y, sf::Color col);
sf::Color get(unsigned short x, unsigned short y) const;
void update(); void update();
}; };

View File

@ -1,5 +1,5 @@
#ifndef __OBJECT_H_ #ifndef __WORLD_OBJECT_H_
#define __OBJECT_H_ #define __WORLD_OBJECT_H_
#include <cmath> #include <cmath>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
@ -7,6 +7,10 @@
extern const unsigned short WIDTH; extern const unsigned short WIDTH;
extern const unsigned short HEIGHT; extern const unsigned short HEIGHT;
enum PheroType {
FOOD, HOME, NONE
};
class WorldObject class WorldObject
{ {
protected: protected:
@ -28,7 +32,7 @@ public:
double angle(const WorldObject& other) const; double angle(const WorldObject& other) const;
virtual void update() = 0; // pure virtual: has to be overridden virtual void update() = 0; // pure virtual: has to be overridden
virtual sf::Color getPheromoneType() const = 0; virtual PheroType getPheromoneType() const = 0;
}; };
#endif // __OBJECT_H_ #endif // __OBJECT_H_