#include #include #include #include "Canvas.h" #include "Exception.h" #include "util.h" #include "Museum.h" using namespace std; Canvas::Canvas(Museum & museum) : museum(museum), tile_behavior(museum), tile_color() { } Tile * & Canvas::get_tile_unsafe(const XY & pos) { size_t index = pos.y * this->data.columns + pos.x; return this->tiles[index]; } Tile & Canvas::get_tile(const XY & pos) { Exception outside_range("get_tile: position (%d, %d) outside canvas", pos.x, pos.y); if (pos.x < 0) throw outside_range; if (pos.y < 0) throw outside_range; if (pos.x >= this->data.columns) throw outside_range; if (pos.y >= this->data.rows) throw outside_range; Tile * tile = get_tile_unsafe(pos); assert(tile != nullptr); return *tile; } void Canvas::set_tile(TileData data) { Tile * & tile = this->get_tile_unsafe({ static_cast(data.x), static_cast(data.y) }); if (tile != nullptr) delete tile; tile = new Tile(this->museum, data); } 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 (int y = 0; y < this->data.rows; y++) { for (int x = 0; x < this->data.columns; x++) { if (this->get_tile_unsafe({ x, y }) != nullptr) continue; this->set_tile({ .x = static_cast(x), .y = static_cast(y), }); } } } Canvas::~Canvas() { for (size_t i = 0; i < this->tiles.size(); i++) { if (this->tiles[i] == nullptr) continue; delete this->tiles[i]; this->tiles[i] = nullptr; } } string Canvas::to_string(bool truecolor) { string out = ""; for (int y = 0; y < this->data.rows; y++) { for (int x = 0; x < this->data.columns; x++) { Tile * tile = this->get_tile_unsafe({ x, y }); string type_str = tile->data.type; if (type_str.length() == 0) type_str = "."; if (truecolor) out += stringf("\e[38;2;0;0;0;48;2;%d;%d;%dm", tile->color.red, tile->color.green, tile->color.blue); out += stringf("%-2s ", type_str.c_str()); } if (truecolor) out += "\e[0m"; out += "\n"; } return out; } void Canvas::update_steps() { for (Artist * artist : this->museum.people.get_artists()) { if (artist->step == false) continue; artist->step = false; Tile * tile = this->get_tile_unsafe({ static_cast(artist->data.x), static_cast(artist->data.y) }); tile->behavior->step(artist); } } void Canvas::update_tiles() { for (Tile * tile : this->tiles) { if (tile == nullptr) continue; tile->update(); } } Memories Canvas::save() { Memories data; data.push_back(make_unique(this->data)); for (Tile * tile : this->tiles) { data.push_back(make_unique(tile->data)); } return data; } void Canvas::restore(const Memories & memories) { for (const unique_ptr & memory : memories) { auto canvas = dynamic_cast(memory.get()); if (canvas != nullptr) { this->set_data(canvas->data); } auto tile = dynamic_cast(memory.get()); if (tile != nullptr) { this->set_tile(tile->data); } } }