-
Yann Boucher authoredYann Boucher authored
automaton.cpp 2.13 KiB
#include "automaton.hpp"
Automaton::Automaton() : alphabet(), grid(0,0), border_policy(BoundaryPolicy::Periodic), neighbourhoodRule(nullptr), transitionRule(nullptr) {}
Automaton::~Automaton() {
delete neighbourhoodRule;
delete transitionRule;
}
void Automaton::setAlphabet(const Alphabet& A) {
alphabet = A;
for(int i=0; i<static_cast<int>(grid.get_col()); ++i) {
for(int j=0; j<static_cast<int>(grid.get_rows()); ++j) {
grid.set_cell({i,j}, 0);
}
}
}
void Automaton::setNeighborhoodRule(NeighborhoodRule* NR) {
delete neighbourhoodRule;
neighbourhoodRule = NR;
}
NeighborhoodRule* Automaton::getNeighborhoodRule() const {
return neighbourhoodRule;
}
void Automaton::setTransitionRule(TransitionRule* TR) {
delete transitionRule;
transitionRule = TR;
}
TransitionRule* Automaton::getTransitionRule() const {
return transitionRule;
}
void Automaton::setCell(const Coord& coord, unsigned int val) {
grid.set_cell(coord, val%alphabet.taille());
}
const Grid& Automaton::getGrid() const {
return grid;
}
void Automaton::setGrid(const Grid& G) {
grid = G;
unsigned int state;
for(int i=0; i<static_cast<int>(grid.get_col()); ++i) {
for(int j=0; j<static_cast<int>(grid.get_rows()); ++j) {
state = grid.get_state({i,j});
if(state >= alphabet.taille()) {
grid.set_cell({i,j}, state%alphabet.taille());
}
}
}
}
void Automaton::runOnce() {
// On s'assure d'avoir une stratégie de frontière de réseau à jour
grid.set_boundary_policy(border_policy);
Grid tempGrid(grid);
for(int i=0; i<static_cast<int>(grid.get_rows()); ++i) {
for(int j=0; j<static_cast<int>(grid.get_col()); ++j) {
unsigned prev = grid.get_state({j,i});
unsigned next = transitionRule->getState(prev,neighbourhoodRule->getNeighborhood(grid, {j, i}));
if (next >= alphabet.taille()) // embrace the magic of branch prediction
next %= alphabet.taille();
if (prev != next)
tempGrid.set_cell({j, i}, next);
}
}
grid = tempGrid;
}