Copying from gitlab
This commit is contained in:
155
src/world.cpp
Normal file
155
src/world.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* / ) */
|
||||
/* world.cpp (\__/) ( ( */
|
||||
/* ) ( ) ) */
|
||||
/* By: lejulien <leo.julien.42@gmail.com> ={ }= / / */
|
||||
/* ) `-------/ / */
|
||||
/* Created: 2023/01/09 12:25:55 by lejulien ( / */
|
||||
/* Updated: 2023/01/14 17:06:54 by lejulien \ | */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/world.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
// Constructor and destructor
|
||||
|
||||
World::World(int width, int height) : _width(width), _height(height) {
|
||||
// create world data
|
||||
this->_data = new std::vector<bool>(width * height, false);
|
||||
}
|
||||
|
||||
World::~World() { delete this->_data; }
|
||||
|
||||
// Getters
|
||||
|
||||
std::vector<bool> *World::getWorldData() { return this->_data; }
|
||||
|
||||
int World::getWidth() { return this->_width; }
|
||||
|
||||
int World::getHeight() { return this->_height; }
|
||||
|
||||
// Member function
|
||||
|
||||
void World::randomize() {
|
||||
// setup randomization
|
||||
_history.clear();
|
||||
_cycle_index = 0;
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now.time_since_epoch())
|
||||
.count();
|
||||
|
||||
std::srand(ms);
|
||||
|
||||
// filling data with random states
|
||||
for (auto cell : *this->_data) {
|
||||
if (std::rand() % 2)
|
||||
cell = true;
|
||||
else
|
||||
cell = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> World::getCompressed() {
|
||||
if (!_data || _data->empty()) {
|
||||
return {};
|
||||
}
|
||||
bool previous_state = (*_data)[0];
|
||||
std::vector<uint32_t> compressed_out;
|
||||
compressed_out.push_back(_width);
|
||||
compressed_out.push_back(_height);
|
||||
compressed_out.push_back((previous_state) ? 1 : 0);
|
||||
unsigned int count = 0;
|
||||
for (auto state : *_data) {
|
||||
if (state != previous_state) {
|
||||
compressed_out.push_back(count);
|
||||
previous_state = state;
|
||||
count = 1;
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
compressed_out.push_back(count);
|
||||
return compressed_out;
|
||||
}
|
||||
|
||||
void World::loadCompressed(const std::vector<uint32_t> &compressed) {
|
||||
if (compressed.empty()) {
|
||||
std::cerr << "Error: Compressed data is empty." << std::endl;
|
||||
return;
|
||||
}
|
||||
auto it = compressed.begin();
|
||||
int width = *it++;
|
||||
int height = *it++;
|
||||
bool actual_state = (*it++ == 1);
|
||||
auto new_data = new std::vector<bool>();
|
||||
while (it != compressed.end()) {
|
||||
unsigned int count = *it++;
|
||||
for (unsigned int i = 0; i < count; ++i) {
|
||||
new_data->push_back(actual_state);
|
||||
}
|
||||
actual_state = !actual_state;
|
||||
}
|
||||
delete this->_data;
|
||||
this->_data = new_data;
|
||||
this->_width = width;
|
||||
this->_height = height;
|
||||
}
|
||||
|
||||
void World::saveCompressed() {
|
||||
_cycle_index++;
|
||||
if (_history.size() >= MAX_HISTORY_SIZE) {
|
||||
_history.erase(_history.begin());
|
||||
}
|
||||
_history.push_back(getCompressed());
|
||||
}
|
||||
|
||||
void World::clear() {
|
||||
_history.clear();
|
||||
_cycle_index = 0;
|
||||
for (auto cell : *this->_data) {
|
||||
cell = false;
|
||||
}
|
||||
}
|
||||
|
||||
void World::stepBack() {
|
||||
if (_history.empty()) {
|
||||
std::cerr << "Error: Invalid history index." << std::endl;
|
||||
// [TODO] Generate new history from initial state to _history_index;
|
||||
return;
|
||||
}
|
||||
_cycle_index--;
|
||||
loadCompressed(_history[_history.size() - 1]);
|
||||
_history.resize(_history.size() - 1);
|
||||
}
|
||||
|
||||
void World::setCell(int x, int y) {
|
||||
_history.clear();
|
||||
_cycle_index = 0;
|
||||
if (!_data) {
|
||||
return;
|
||||
}
|
||||
(*_data)[x + y * _width] = !(*_data)[x + y * _width];
|
||||
}
|
||||
|
||||
void World::resize(int width, int height) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_data->resize(width * height, false);
|
||||
clear();
|
||||
}
|
||||
|
||||
std::vector<uint32_t> World::getSelection(Vector2i &origin, Vector2i &size) {
|
||||
// We assume the selection is in the grid for now
|
||||
std::vector<uint32_t> data = {static_cast<uint32_t>(size.x),
|
||||
static_cast<uint32_t>(size.y)};
|
||||
for (int y = origin.y; y < origin.y + size.y; y++) {
|
||||
for (int x = origin.x; x < origin.x + size.x; x++) {
|
||||
data.push_back((*_data)[x + y * _width]);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user