diff options
-rw-r--r-- | Artist.cpp | 28 | ||||
-rw-r--r-- | Artist.h | 18 | ||||
-rw-r--r-- | BlueTileBehavior.cpp | 6 | ||||
-rw-r--r-- | BlueTileBehavior.h | 4 | ||||
-rw-r--r-- | Canvas.cpp | 39 | ||||
-rw-r--r-- | Canvas.h | 9 | ||||
-rw-r--r-- | GrayTileBehavior.cpp | 6 | ||||
-rw-r--r-- | GrayTileBehavior.h | 4 | ||||
-rw-r--r-- | Museum.cpp | 6 | ||||
-rw-r--r-- | Museum.h | 2 | ||||
-rw-r--r-- | NullTileBehavior.cpp | 8 | ||||
-rw-r--r-- | NullTileBehavior.h | 4 | ||||
-rw-r--r-- | People.cpp | 8 | ||||
-rw-r--r-- | People.h | 5 | ||||
-rw-r--r-- | RedTileBehavior.cpp | 6 | ||||
-rw-r--r-- | RedTileBehavior.h | 4 | ||||
-rw-r--r-- | Tile.cpp | 17 | ||||
-rw-r--r-- | Tile.h | 13 | ||||
-rw-r--r-- | TileBehaviorStrategy.cpp | 4 | ||||
-rw-r--r-- | TileBehaviorStrategy.h | 10 | ||||
-rw-r--r-- | YellowTileBehavior.cpp | 35 | ||||
-rw-r--r-- | YellowTileBehavior.h | 6 | ||||
-rw-r--r-- | input/test.csv | 4 |
23 files changed, 177 insertions, 69 deletions
@@ -1,25 +1,39 @@ +#include <cstdlib> + #include "Artist.h" #include "Museum.h" -void Artist::update(Museum & m) { - this->update_edge_collision(m); - this->update_movement(m); +Artist::Artist(Museum & museum, ArtistData data) : museum(museum) { + this->data = data; + this->data.vx /= 50; + this->data.vy /= 50; +} + +void Artist::update() { + this->update_edge_collision(); + this->update_movement(); } -void Artist::update_edge_collision(Museum & museum) { +void Artist::update_edge_collision() { float next_x = this->data.x + this->data.vx; float next_y = this->data.y + this->data.vy; // +0.5 is for own size (the assignment explicitly defines the x,y position // of artists as the top-left corner) - if ((next_x + 0.5) > museum.canvas.data.columns || next_x < 0) + if ((next_x + 0.5) > this->museum.canvas.data.columns || next_x < 0) this->data.vx *= -1; - if ((next_y + 0.5) > museum.canvas.data.rows || next_y < 0) + if ((next_y + 0.5) > this->museum.canvas.data.rows || next_y < 0) this->data.vy *= -1; } -void Artist::update_movement(Museum & museum) { +void Artist::update_movement() { + float last_x = this->data.x; + float last_y = this->data.y; + this->data.x += this->data.vx; this->data.y += this->data.vy; + + if (abs(int(last_x) - int(this->data.x)) > 0) this->step = true; + if (abs(int(last_y) - int(this->data.y)) > 0) this->step = true; } @@ -7,15 +7,23 @@ class Museum; class Artist { public: - void update(Museum & m); + Artist(Museum &, ArtistData data); + +public: + void update(); private: - void update_movement(Museum & m); - void update_edge_collision(Museum & m); + void update_movement(); + void update_edge_collision(); public: - ArtistData data; - Color color; + ArtistData data = { 0 }; + Color color = { 0 }; + + bool step = false; + +private: + Museum & museum; }; diff --git a/BlueTileBehavior.cpp b/BlueTileBehavior.cpp index 95a78ec..ca714a4 100644 --- a/BlueTileBehavior.cpp +++ b/BlueTileBehavior.cpp @@ -6,12 +6,12 @@ using namespace std; BlueTileBehavior BlueTileBehavior::instance {"B"}; -void BlueTileBehavior::run(Tile &) { - printf("TODO: %s\n", __PRETTY_FUNCTION__); +void BlueTileBehavior::update(Tile &) { } -unique_ptr<TileBehaviorStrategy> BlueTileBehavior::clone() { +unique_ptr<TileBehaviorStrategy> BlueTileBehavior::clone(Museum & museum) { auto instance = new BlueTileBehavior(); + instance->museum = &museum; return unique_ptr<TileBehaviorStrategy>(instance); } diff --git a/BlueTileBehavior.h b/BlueTileBehavior.h index 98a8c86..e021116 100644 --- a/BlueTileBehavior.h +++ b/BlueTileBehavior.h @@ -4,8 +4,8 @@ class BlueTileBehavior : public TileBehaviorStrategy { public: - virtual void run(Tile &); - virtual std::unique_ptr<TileBehaviorStrategy> clone(); + virtual void update(Tile &); + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); private: using TileBehaviorStrategy::TileBehaviorStrategy; @@ -3,18 +3,23 @@ #include "Canvas.h" #include "util.h" +#include "Museum.h" using namespace std; +Canvas::Canvas(Museum & museum) : museum(museum) { } + Tile & Canvas::get_tile(unsigned x, unsigned y) { return *this->tiles[this->pos_to_index(x, y)]; } -void Canvas::set_tile(unsigned x, unsigned y, TileData t) { +void Canvas::set_tile(unsigned x, unsigned y, TileData data) { size_t index = this->pos_to_index(x, y); if (this->tiles[index] != nullptr) delete this->tiles[index]; - this->tiles[index] = new Tile(t); + this->tiles[index] = new Tile(this->museum, data); + this->tiles[index]->x = x; + this->tiles[index]->y = y; } size_t Canvas::pos_to_index(unsigned x, unsigned y) { @@ -22,15 +27,20 @@ size_t Canvas::pos_to_index(unsigned x, unsigned y) { return index; } -void Canvas::update(Museum & museum) { +void Canvas::update() { + this->update_steps(); + this->update_tiles(); } void Canvas::set_data(CanvasData data) { this->data = data; this->tiles.resize(this->data.rows * this->data.columns); - for (size_t i = 0; i < this->tiles.size(); i++) { - if (this->tiles[i] != nullptr) continue; - this->tiles[i] = new Tile(); + for (size_t y = 0; y < this->data.rows; y++) { + for (size_t x = 0; x < this->data.columns; x++) { + if (this->tiles[this->pos_to_index(x, y)] != nullptr) + continue; + this->set_tile(x, y, {}); + } } } @@ -64,3 +74,20 @@ string Canvas::to_string(bool truecolor) { return out; } +void Canvas::update_steps() { + for (size_t i = 0; i < this->museum.people.artists_size(); i++) { + Artist & artist = this->museum.people.get_artist(i); + if (artist.step == false) continue; + artist.step = false; + + this->get_tile(artist.data.x, artist.data.y).step(); + } +} + +void Canvas::update_tiles() { + for (Tile * tile : this->tiles) { + if (tile == nullptr) continue; + tile->update(); + } +} + @@ -10,7 +10,7 @@ class Museum; class Canvas { public: - Canvas() = default; + Canvas(Museum &); virtual ~Canvas(); std::string to_string(bool truecolor = false); @@ -20,11 +20,16 @@ public: public: CanvasData data; - void update(Museum & m); + void update(); void set_data(CanvasData data); private: + void update_steps(); + void update_tiles(); + +private: std::vector<Tile *> tiles; + Museum & museum; private: size_t pos_to_index(unsigned x, unsigned y); diff --git a/GrayTileBehavior.cpp b/GrayTileBehavior.cpp index af054d5..b12f51d 100644 --- a/GrayTileBehavior.cpp +++ b/GrayTileBehavior.cpp @@ -6,12 +6,12 @@ using namespace std; GrayTileBehavior GrayTileBehavior::instance {"G"}; -void GrayTileBehavior::run(Tile &) { - printf("TODO: %s\n", __PRETTY_FUNCTION__); +void GrayTileBehavior::update(Tile &) { } -unique_ptr<TileBehaviorStrategy> GrayTileBehavior::clone() { +unique_ptr<TileBehaviorStrategy> GrayTileBehavior::clone(Museum & museum) { auto instance = new GrayTileBehavior(); + instance->museum = &museum; return unique_ptr<TileBehaviorStrategy>(instance); } diff --git a/GrayTileBehavior.h b/GrayTileBehavior.h index 9ea4d96..ceba350 100644 --- a/GrayTileBehavior.h +++ b/GrayTileBehavior.h @@ -4,8 +4,8 @@ class GrayTileBehavior : public TileBehaviorStrategy { public: - virtual void run(Tile &); - virtual std::unique_ptr<TileBehaviorStrategy> clone(); + virtual void update(Tile &); + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); private: using TileBehaviorStrategy::TileBehaviorStrategy; @@ -2,7 +2,7 @@ using namespace std; -Museum::Museum() { +Museum::Museum() : people(*this), canvas(*this) { this->worker = new std::thread(&Museum::work, this); } @@ -16,8 +16,8 @@ Museum::~Museum() { } void Museum::update() { - this->people.update(*this); - this->canvas.update(*this); + this->people.update(); + this->canvas.update(); } void Museum::work() { @@ -25,7 +25,7 @@ private: bool paused = false; private: - static constexpr std::chrono::milliseconds tick_interval = 10ms; + static constexpr std::chrono::milliseconds tick_interval = 15ms; bool working = true; std::thread * worker = nullptr; void work(); diff --git a/NullTileBehavior.cpp b/NullTileBehavior.cpp index 542b67c..64bf622 100644 --- a/NullTileBehavior.cpp +++ b/NullTileBehavior.cpp @@ -6,13 +6,11 @@ using namespace std; NullTileBehavior NullTileBehavior::instance {""}; -void NullTileBehavior::run(Tile &) { +void NullTileBehavior::update(Tile &) { } -} - -unique_ptr<TileBehaviorStrategy> NullTileBehavior::clone() { +unique_ptr<TileBehaviorStrategy> NullTileBehavior::clone(Museum & museum) { auto instance = new NullTileBehavior(); + instance->museum = &museum; return unique_ptr<TileBehaviorStrategy>(instance); } - diff --git a/NullTileBehavior.h b/NullTileBehavior.h index 6b68a4a..f47770e 100644 --- a/NullTileBehavior.h +++ b/NullTileBehavior.h @@ -4,8 +4,8 @@ class NullTileBehavior : public TileBehaviorStrategy { public: - virtual void run(Tile &); - virtual std::unique_ptr<TileBehaviorStrategy> clone(); + virtual void update(Tile &); + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); private: using TileBehaviorStrategy::TileBehaviorStrategy; @@ -4,6 +4,8 @@ using namespace std; +People::People(Museum & museum) : museum(museum) {} + People::~People() { for (Artist * artist : this->artists) { if (artist == nullptr) continue; @@ -13,7 +15,7 @@ People::~People() { } void People::add_artist(ArtistData data) { - this->artists.push_back(new Artist(data)); + this->artists.push_back(new Artist(this->museum, data)); } size_t People::artists_size() { @@ -38,10 +40,10 @@ string People::to_string() { return out; } -void People::update(Museum & museum) { +void People::update() { for (Artist * artist : this->artists) { if (artist == nullptr) continue; - artist->update(museum); + artist->update(); } } @@ -10,7 +10,7 @@ class Museum; class People { public: - People() = default; + People(Museum &); virtual ~People(); std::string to_string(); @@ -20,9 +20,10 @@ public: Artist & get_artist(size_t index); size_t artists_size(); - void update(Museum & m); + void update(); private: std::vector<Artist *> artists; + Museum & museum; }; diff --git a/RedTileBehavior.cpp b/RedTileBehavior.cpp index e295b4b..b0d09c2 100644 --- a/RedTileBehavior.cpp +++ b/RedTileBehavior.cpp @@ -6,12 +6,12 @@ using namespace std; RedTileBehavior RedTileBehavior::instance {"R"}; -void RedTileBehavior::run(Tile &) { - printf("TODO: %s\n", __PRETTY_FUNCTION__); +void RedTileBehavior::update(Tile &) { } -unique_ptr<TileBehaviorStrategy> RedTileBehavior::clone() { +unique_ptr<TileBehaviorStrategy> RedTileBehavior::clone(Museum & museum) { auto instance = new RedTileBehavior(); + instance->museum = &museum; return unique_ptr<TileBehaviorStrategy>(instance); } diff --git a/RedTileBehavior.h b/RedTileBehavior.h index 7b686b8..946e6ff 100644 --- a/RedTileBehavior.h +++ b/RedTileBehavior.h @@ -4,8 +4,8 @@ class RedTileBehavior : public TileBehaviorStrategy { public: - virtual void run(Tile &); - virtual std::unique_ptr<TileBehaviorStrategy> clone(); + virtual void update(Tile &); + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); private: using TileBehaviorStrategy::TileBehaviorStrategy; @@ -4,18 +4,21 @@ #include "TileAppearance.h" #include "TileBehavior.h" -Tile::Tile() { - this->data = {}; - this->update(); +Tile::Tile(Museum & museum, TileData data) : museum(museum) { + this->set_data(data); } -Tile::Tile(TileData data) { +void Tile::set_data(TileData data) { this->data = data; - this->update(); + this->color = TileAppearance::get_color(this->data.type); + this->behavior = TileBehavior::get_strategy(this->data.type).clone(this->museum); } void Tile::update() { - this->color = TileAppearance::get_color(this->data.type); - this->behavior = TileBehavior::get_strategy(this->data.type).clone(); + this->behavior->update(*this); +} + +void Tile::step() { + this->behavior->step(); } @@ -6,17 +6,26 @@ #include "Color.h" #include "TileBehaviorStrategy.h" +class Museum; + class Tile { public: - Tile(); - Tile(TileData data); + Tile(Museum & museum, TileData data); public: TileData data; Color color; std::unique_ptr<TileBehaviorStrategy> behavior = nullptr; + unsigned int x = 0; + unsigned int y = 0; + public: + void set_data(TileData data); void update(); + void step(); + +private: + Museum & museum; }; diff --git a/TileBehaviorStrategy.cpp b/TileBehaviorStrategy.cpp index 9e829cc..bf0b3b3 100644 --- a/TileBehaviorStrategy.cpp +++ b/TileBehaviorStrategy.cpp @@ -5,3 +5,7 @@ TileBehaviorStrategy::TileBehaviorStrategy(const std::string type) { TileBehavior::register_strategy(type, this); } +void TileBehaviorStrategy::step() { + this->steps++; +} + diff --git a/TileBehaviorStrategy.h b/TileBehaviorStrategy.h index a2c90e3..01ecd98 100644 --- a/TileBehaviorStrategy.h +++ b/TileBehaviorStrategy.h @@ -4,14 +4,20 @@ #include <memory> class Tile; +class Museum; class TileBehaviorStrategy { public: - virtual void run(Tile &) = 0; - virtual std::unique_ptr<TileBehaviorStrategy> clone() = 0; + virtual void step(); + virtual void update(Tile &) = 0; + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum & m) = 0; protected: TileBehaviorStrategy(const std::string type); TileBehaviorStrategy() = default; + +protected: + unsigned int steps = 0; + Museum * museum = nullptr; }; diff --git a/YellowTileBehavior.cpp b/YellowTileBehavior.cpp index 2999229..4e0b7f1 100644 --- a/YellowTileBehavior.cpp +++ b/YellowTileBehavior.cpp @@ -1,17 +1,46 @@ #include <memory> +#include <random> #include "YellowTileBehavior.h" +#include "Tile.h" +#include "Museum.h" +using std::uniform_int_distribution; +using std::uniform_real_distribution; +using std::random_device; +using std::mt19937; using namespace std; YellowTileBehavior YellowTileBehavior::instance {"Y"}; -void YellowTileBehavior::run(Tile &) { - printf("TODO: %s\n", __PRETTY_FUNCTION__); +random_device dev{}; +mt19937 rng(dev()); +uniform_int_distribution<int> random_bool(0, 1); +uniform_real_distribution<float> random_float(-1, 1); + +void YellowTileBehavior::update(Tile & tile) { + this->steps_total += this->steps; + for (unsigned int i = 0; i < this->steps; i++) { + ArtistData new_data = { + .x = static_cast<float>(tile.x), + .y = static_cast<float>(tile.y), + }; + float velocity = random_float(rng); + random_bool(rng) ? new_data.vx = velocity : new_data.vy = velocity; + this->museum->people.add_artist(new_data); + } + this->steps = 0; + + if (this->steps_total >= 2) { + TileData new_data = tile.data; + new_data.type = "G"; + tile.set_data(new_data); + } } -unique_ptr<TileBehaviorStrategy> YellowTileBehavior::clone() { +unique_ptr<TileBehaviorStrategy> YellowTileBehavior::clone(Museum & museum) { auto instance = new YellowTileBehavior(); + instance->museum = &museum; return unique_ptr<TileBehaviorStrategy>(instance); } diff --git a/YellowTileBehavior.h b/YellowTileBehavior.h index 7a457a4..015a244 100644 --- a/YellowTileBehavior.h +++ b/YellowTileBehavior.h @@ -4,12 +4,14 @@ class YellowTileBehavior : public TileBehaviorStrategy { public: - virtual void run(Tile &); - virtual std::unique_ptr<TileBehaviorStrategy> clone(); + virtual void update(Tile &); + virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); private: using TileBehaviorStrategy::TileBehaviorStrategy; static YellowTileBehavior instance; YellowTileBehavior() = default; + + unsigned int steps_total = 0; }; diff --git a/input/test.csv b/input/test.csv index d7d5ae3..0fc4c62 100644 --- a/input/test.csv +++ b/input/test.csv @@ -1,3 +1,3 @@ x,y,vx,vy -0.5,0.5,0.05,0.0 -0.5,0.5,0.0,0.05 +0.5,0.5,0.5,0.0 +0.5,0.5,0.0,0.5 |