103 lines
2.1 KiB
C++
103 lines
2.1 KiB
C++
/*
|
|
* File name: rules.cpp
|
|
* Author: lejulien
|
|
* Date created: 10-01-2026 21:49:14
|
|
// Date modified: 12-01-2026 21:59:00
|
|
* ------
|
|
*/
|
|
|
|
#include "../includes/rules.hpp"
|
|
#include "../includes/world.hpp"
|
|
|
|
// Contructor
|
|
|
|
Rules::Rules() {}
|
|
|
|
// Private functions
|
|
|
|
void Rules::offset_coord(int &i, int &j) {
|
|
if (i < 0) {
|
|
i = this->_width - 1;
|
|
} else if (i >= this->_width) {
|
|
i = 0;
|
|
}
|
|
if (j < 0) {
|
|
j = this->_height - 1;
|
|
} else if (j >= this->_height) {
|
|
j = 0;
|
|
}
|
|
}
|
|
|
|
bool Rules::is_alive(int i, int j) {
|
|
offset_coord(i, j);
|
|
if (this->_buffer[i + j * this->_width])
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void Rules::ortho_neighbors(int &neighbors, int i, int j) {
|
|
// top
|
|
if (is_alive(i, j - 1))
|
|
neighbors++;
|
|
// bottom
|
|
if (is_alive(i, j + 1))
|
|
neighbors++;
|
|
// left
|
|
if (is_alive(i - 1, j))
|
|
neighbors++;
|
|
// right
|
|
if (is_alive(i + 1, j))
|
|
neighbors++;
|
|
}
|
|
|
|
void Rules::diag_neighbors(int &neighbors, int i, int j) {
|
|
// top-left
|
|
if (is_alive(i - 1, j - 1))
|
|
neighbors++;
|
|
// top-right
|
|
if (is_alive(i + 1, j - 1))
|
|
neighbors++;
|
|
// bottom-left
|
|
if (is_alive(i - 1, j + 1))
|
|
neighbors++;
|
|
// bottom-right
|
|
if (is_alive(i + 1, j + 1))
|
|
neighbors++;
|
|
}
|
|
|
|
// Member function
|
|
|
|
void Rules::setup(std::shared_ptr<World> world) {
|
|
_world = world;
|
|
_width = world->getWidth();
|
|
_height = world->getHeight();
|
|
}
|
|
|
|
void Rules::newWorld(std::shared_ptr<World> world) {
|
|
_world = world;
|
|
_width = world->getWidth();
|
|
_height = world->getHeight();
|
|
}
|
|
|
|
void Rules::update() {
|
|
int neighbors = 0;
|
|
std::vector<bool> *world_data = _world->getWorldData();
|
|
this->_buffer = *world_data;
|
|
|
|
// apply the rules for each cells
|
|
for (int j = 0; j < this->_height; j++) {
|
|
for (int i = 0; i < this->_width; i++) {
|
|
// count neighbors
|
|
neighbors = 0;
|
|
ortho_neighbors(neighbors, i, j);
|
|
diag_neighbors(neighbors, i, j);
|
|
|
|
// Apply the rules
|
|
if (neighbors < 2 || neighbors > 3)
|
|
(*world_data)[i + j * this->_width] = false;
|
|
else if (neighbors == 3)
|
|
(*world_data)[i + j * this->_width] = true;
|
|
}
|
|
}
|
|
}
|