diff options
author | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-13 19:06:52 +0200 |
---|---|---|
committer | Loek Le Blansch <loek@pipeframe.xyz> | 2024-10-13 19:06:52 +0200 |
commit | 5ab49aa46b6f1a9cd5196165009d2ee08b6b7a87 (patch) | |
tree | bbc3967b299ee2b272efcd83e3c0c4ed82ce7de6 | |
parent | feaf272efad381414c6ee76c0cd4bf929e8087ae (diff) |
implement all tile behaviors
-rw-r--r-- | Artist.cpp | 4 | ||||
-rw-r--r-- | BlueTileBehavior.cpp | 29 | ||||
-rw-r--r-- | BlueTileBehavior.h | 6 | ||||
-rw-r--r-- | Canvas.cpp | 2 | ||||
-rw-r--r-- | Canvas.h | 2 | ||||
-rw-r--r-- | GrayTileBehavior.cpp | 8 | ||||
-rw-r--r-- | LocalFile.cpp | 2 | ||||
-rw-r--r-- | People.cpp | 8 | ||||
-rw-r--r-- | People.h | 1 | ||||
-rw-r--r-- | RedTileBehavior.cpp | 14 | ||||
-rw-r--r-- | RedTileBehavior.h | 1 | ||||
-rw-r--r-- | Tile.cpp | 16 | ||||
-rw-r--r-- | Tile.h | 7 | ||||
-rw-r--r-- | TileBehaviorStrategy.cpp | 4 | ||||
-rw-r--r-- | TileBehaviorStrategy.h | 5 | ||||
-rw-r--r-- | YellowTileBehavior.cpp | 17 | ||||
-rw-r--r-- | YellowTileBehavior.h | 2 | ||||
-rw-r--r-- | main.cpp | 4 |
18 files changed, 104 insertions, 28 deletions
@@ -5,8 +5,8 @@ Artist::Artist(Museum & museum, ArtistData data) : museum(museum) { this->data = data; - this->data.vx /= 50; - this->data.vy /= 50; + this->data.vx /= 5; + this->data.vy /= 5; } void Artist::update() { diff --git a/BlueTileBehavior.cpp b/BlueTileBehavior.cpp index ca714a4..fbca527 100644 --- a/BlueTileBehavior.cpp +++ b/BlueTileBehavior.cpp @@ -1,12 +1,39 @@ #include <memory> #include "BlueTileBehavior.h" +#include "Artist.h" +#include "Tile.h" +#include "TileData.h" using namespace std; BlueTileBehavior BlueTileBehavior::instance {"B"}; -void BlueTileBehavior::update(Tile &) { +void BlueTileBehavior::step(Artist & artist) { + this->interactions++; + if (this->interactions > 1) return; + + if (artist.data.vx == 0) dx = 1; + if (artist.data.vy == 0) dy = 1; +} + +void BlueTileBehavior::update_neighbor(Tile * tile) { + if (tile == nullptr) return; + + TileData new_data = tile->data; + new_data.type = "B"; + tile->set_data(new_data); +} + +void BlueTileBehavior::update(Tile & tile) { + if (this->interactions < 1) return; + + this->update_neighbor(tile.get_neighbor(this->dx, this->dy)); + this->update_neighbor(tile.get_neighbor(-this->dx, -this->dy)); + + TileData new_data = tile.data; + new_data.type = "Y"; + tile.set_data(new_data); } unique_ptr<TileBehaviorStrategy> BlueTileBehavior::clone(Museum & museum) { diff --git a/BlueTileBehavior.h b/BlueTileBehavior.h index e021116..16566c1 100644 --- a/BlueTileBehavior.h +++ b/BlueTileBehavior.h @@ -4,6 +4,7 @@ class BlueTileBehavior : public TileBehaviorStrategy { public: + virtual void step(Artist &); virtual void update(Tile &); virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); @@ -11,5 +12,10 @@ private: using TileBehaviorStrategy::TileBehaviorStrategy; static BlueTileBehavior instance; BlueTileBehavior() = default; + +private: + virtual void update_neighbor(Tile *); + int dx = 0; + int dy = 0; }; @@ -80,7 +80,7 @@ void Canvas::update_steps() { if (artist.step == false) continue; artist.step = false; - this->get_tile(artist.data.x, artist.data.y).step(); + this->get_tile(artist.data.x, artist.data.y).step(artist); } } @@ -19,7 +19,7 @@ public: virtual void set_tile(unsigned x, unsigned y, TileData data); public: - CanvasData data; + CanvasData data = { 0 }; void update(); void set_data(CanvasData data); diff --git a/GrayTileBehavior.cpp b/GrayTileBehavior.cpp index b12f51d..31acb33 100644 --- a/GrayTileBehavior.cpp +++ b/GrayTileBehavior.cpp @@ -1,12 +1,18 @@ #include <memory> #include "GrayTileBehavior.h" +#include "Tile.h" +#include "TileData.h" using namespace std; GrayTileBehavior GrayTileBehavior::instance {"G"}; -void GrayTileBehavior::update(Tile &) { +void GrayTileBehavior::update(Tile & tile) { + if (this->interactions < 3) return; + TileData new_data = tile.data; + new_data.type = "R"; + tile.set_data(new_data); } unique_ptr<TileBehaviorStrategy> GrayTileBehavior::clone(Museum & museum) { diff --git a/LocalFile.cpp b/LocalFile.cpp index bdc25ab..d5bad67 100644 --- a/LocalFile.cpp +++ b/LocalFile.cpp @@ -13,7 +13,7 @@ void LocalFile::open(const std::string url) { this->file = new std::ifstream(path, std::ios::in); if (this->file->fail() || !this->file->is_open()) - throw Exception("Cannot open file://%s\n", path.c_str()); + throw Exception("cannot open file://%s\n", path.c_str()); } void LocalFile::close() { @@ -1,3 +1,5 @@ +#include <algorithm> + #include "People.h" #include "Exception.h" #include "util.h" @@ -18,6 +20,12 @@ void People::add_artist(ArtistData data) { this->artists.push_back(new Artist(this->museum, data)); } +void People::remove_artist(Artist & target) { + auto it = find(this->artists.begin(), this->artists.end(), &target); + if (it == this->artists.end()) return; + this->artists.erase(it); +} + size_t People::artists_size() { return this->artists.size(); } @@ -16,6 +16,7 @@ public: public: void add_artist(ArtistData data); + void remove_artist(Artist & artist); Artist & get_artist(size_t index); size_t artists_size(); diff --git a/RedTileBehavior.cpp b/RedTileBehavior.cpp index b0d09c2..245b886 100644 --- a/RedTileBehavior.cpp +++ b/RedTileBehavior.cpp @@ -1,12 +1,24 @@ #include <memory> #include "RedTileBehavior.h" +#include "Tile.h" +#include "TileData.h" +#include "Museum.h" using namespace std; RedTileBehavior RedTileBehavior::instance {"R"}; -void RedTileBehavior::update(Tile &) { +void RedTileBehavior::step(Artist & artist) { + this->interactions++; + this->museum->people.remove_artist(artist); +} + +void RedTileBehavior::update(Tile & tile) { + if (this->interactions == 0) return; + TileData new_data = tile.data; + new_data.type = "B"; + tile.set_data(new_data); } unique_ptr<TileBehaviorStrategy> RedTileBehavior::clone(Museum & museum) { diff --git a/RedTileBehavior.h b/RedTileBehavior.h index 946e6ff..a2c530e 100644 --- a/RedTileBehavior.h +++ b/RedTileBehavior.h @@ -4,6 +4,7 @@ class RedTileBehavior : public TileBehaviorStrategy { public: + virtual void step(Artist &); virtual void update(Tile &); virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum &); @@ -3,6 +3,7 @@ #include "Tile.h" #include "TileAppearance.h" #include "TileBehavior.h" +#include "Museum.h" Tile::Tile(Museum & museum, TileData data) : museum(museum) { this->set_data(data); @@ -18,7 +19,18 @@ void Tile::update() { this->behavior->update(*this); } -void Tile::step() { - this->behavior->step(); +void Tile::step(Artist & artist) { + this->behavior->step(artist); +} + +Tile * Tile::get_neighbor(int dx, int dy) { + Canvas & canvas = this->museum.canvas; + int x = this->x + dx; + int y = this->y + dy; + if (x < 0) return nullptr; + if (x > canvas.data.columns) return nullptr; + if (y < 0) return nullptr; + if (y > canvas.data.columns) return nullptr; + return &canvas.get_tile(x, y); } @@ -13,8 +13,8 @@ public: Tile(Museum & museum, TileData data); public: - TileData data; - Color color; + TileData data = { 0 }; + Color color = { 0 }; std::unique_ptr<TileBehaviorStrategy> behavior = nullptr; unsigned int x = 0; @@ -23,7 +23,8 @@ public: public: void set_data(TileData data); void update(); - void step(); + void step(Artist &); + Tile * get_neighbor(int dx, int dy); private: Museum & museum; diff --git a/TileBehaviorStrategy.cpp b/TileBehaviorStrategy.cpp index bf0b3b3..ab551f1 100644 --- a/TileBehaviorStrategy.cpp +++ b/TileBehaviorStrategy.cpp @@ -5,7 +5,7 @@ TileBehaviorStrategy::TileBehaviorStrategy(const std::string type) { TileBehavior::register_strategy(type, this); } -void TileBehaviorStrategy::step() { - this->steps++; +void TileBehaviorStrategy::step(Artist &) { + this->interactions++; } diff --git a/TileBehaviorStrategy.h b/TileBehaviorStrategy.h index 01ecd98..156b601 100644 --- a/TileBehaviorStrategy.h +++ b/TileBehaviorStrategy.h @@ -5,10 +5,11 @@ class Tile; class Museum; +class Artist; class TileBehaviorStrategy { public: - virtual void step(); + virtual void step(Artist &); virtual void update(Tile &) = 0; virtual std::unique_ptr<TileBehaviorStrategy> clone(Museum & m) = 0; @@ -17,7 +18,7 @@ protected: TileBehaviorStrategy() = default; protected: - unsigned int steps = 0; + unsigned int interactions = 0; Museum * museum = nullptr; }; diff --git a/YellowTileBehavior.cpp b/YellowTileBehavior.cpp index 4e0b7f1..5697aab 100644 --- a/YellowTileBehavior.cpp +++ b/YellowTileBehavior.cpp @@ -19,8 +19,11 @@ 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++) { + unsigned int new_artists = this->interactions - this->last_interactions; + this->last_interactions = this->interactions; + + for (unsigned int i = 0; i < new_artists; i++) { + if (i >= 2) break; ArtistData new_data = { .x = static_cast<float>(tile.x), .y = static_cast<float>(tile.y), @@ -29,13 +32,11 @@ void YellowTileBehavior::update(Tile & tile) { 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); - } + if (this->interactions < 2) return; + TileData new_data = tile.data; + new_data.type = "G"; + tile.set_data(new_data); } unique_ptr<TileBehaviorStrategy> YellowTileBehavior::clone(Museum & museum) { diff --git a/YellowTileBehavior.h b/YellowTileBehavior.h index 015a244..1b5b2ef 100644 --- a/YellowTileBehavior.h +++ b/YellowTileBehavior.h @@ -12,6 +12,6 @@ private: static YellowTileBehavior instance; YellowTileBehavior() = default; - unsigned int steps_total = 0; + unsigned int last_interactions = 0; }; @@ -15,7 +15,7 @@ static unique_ptr<FileStrategy> open(const char * url) noexcept { unique_ptr<FileStrategy> file = FileReader::open(url); return file; } catch (Exception & e) { - printf("FileStrategy open error: %s\n", e.what()); + printf("file open error: %s\n", e.what()); exit(EXIT_FAILURE); } } @@ -24,7 +24,7 @@ static void parse(FileStrategy & file, Deserializer & deserializer, const char * try { Parser::parse(file, deserializer); } catch (Exception & e) { - printf("Parser error: %s (%s)\n", e.what(), url); + printf("parser error: %s (%s)\n", e.what(), url); exit(EXIT_FAILURE); } } |