aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Artist.cpp28
-rw-r--r--Artist.h18
-rw-r--r--BlueTileBehavior.cpp6
-rw-r--r--BlueTileBehavior.h4
-rw-r--r--Canvas.cpp39
-rw-r--r--Canvas.h9
-rw-r--r--GrayTileBehavior.cpp6
-rw-r--r--GrayTileBehavior.h4
-rw-r--r--Museum.cpp6
-rw-r--r--Museum.h2
-rw-r--r--NullTileBehavior.cpp8
-rw-r--r--NullTileBehavior.h4
-rw-r--r--People.cpp8
-rw-r--r--People.h5
-rw-r--r--RedTileBehavior.cpp6
-rw-r--r--RedTileBehavior.h4
-rw-r--r--Tile.cpp17
-rw-r--r--Tile.h13
-rw-r--r--TileBehaviorStrategy.cpp4
-rw-r--r--TileBehaviorStrategy.h10
-rw-r--r--YellowTileBehavior.cpp35
-rw-r--r--YellowTileBehavior.h6
-rw-r--r--input/test.csv4
23 files changed, 177 insertions, 69 deletions
diff --git a/Artist.cpp b/Artist.cpp
index cf61bdb..ee075c9 100644
--- a/Artist.cpp
+++ b/Artist.cpp
@@ -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;
}
diff --git a/Artist.h b/Artist.h
index be66230..80d24cb 100644
--- a/Artist.h
+++ b/Artist.h
@@ -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;
diff --git a/Canvas.cpp b/Canvas.cpp
index 723ebff..d4b4670 100644
--- a/Canvas.cpp
+++ b/Canvas.cpp
@@ -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();
+ }
+}
+
diff --git a/Canvas.h b/Canvas.h
index 7917d95..928e4dc 100644
--- a/Canvas.h
+++ b/Canvas.h
@@ -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;
diff --git a/Museum.cpp b/Museum.cpp
index 76931b7..361afaf 100644
--- a/Museum.cpp
+++ b/Museum.cpp
@@ -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() {
diff --git a/Museum.h b/Museum.h
index 378e449..b5e8c2a 100644
--- a/Museum.h
+++ b/Museum.h
@@ -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;
diff --git a/People.cpp b/People.cpp
index 5bc11f7..32a9227 100644
--- a/People.cpp
+++ b/People.cpp
@@ -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();
}
}
diff --git a/People.h b/People.h
index 0b7277b..6c3af9a 100644
--- a/People.h
+++ b/People.h
@@ -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;
diff --git a/Tile.cpp b/Tile.cpp
index cb7b89b..d73abe7 100644
--- a/Tile.cpp
+++ b/Tile.cpp
@@ -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();
}
diff --git a/Tile.h b/Tile.h
index dc0b375..70e91d0 100644
--- a/Tile.h
+++ b/Tile.h
@@ -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