diff --git a/README.md b/README.md index cc59d36..57c5933 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,11 @@ There ist still quite some work to do. And for all others, don't hesitate to open issues when you have problems! ## Changelog +#### 1.0.4 +- Adds active state for automaton +- Adds reactivation method +- Fixes cells active state + #### 1.0.3 - Fixes init_cell_state called twice the necessary amount diff --git a/cellular_automaton/automaton.py b/cellular_automaton/automaton.py index 83eb6e6..bc73b15 100644 --- a/cellular_automaton/automaton.py +++ b/cellular_automaton/automaton.py @@ -86,6 +86,17 @@ class CellularAutomaton(CellularAutomatonCreator, abc.ABC): def __init__(self, neighborhood: Neighborhood, *args, **kwargs): super().__init__(neighborhood=neighborhood, *args, **kwargs) self._evolution_step = 0 + self._active = True + + def is_active(self): + return self._active + + def reactivate(self): + """ Sets all cells active again """ + for cell in self._current_state.values(): + cell.is_active = True + + active = property(is_active) def get_cells(self): return self._current_state @@ -109,6 +120,7 @@ class CellularAutomaton(CellularAutomatonCreator, abc.ABC): :param times: The number of evolution steps processed with one call of this method. """ for _ in itertools.repeat(None, times): + self._active = False self.__evolve_cells(self._current_state, self._next_state) self._current_state, self._next_state = self._next_state, self._current_state self._evolution_step += 1 @@ -122,12 +134,12 @@ class CellularAutomaton(CellularAutomatonCreator, abc.ABC): old.is_active = False evolve_cell(old, new, new_state) - @classmethod - def __evolve_cell(cls, old, cell, new_state): - changed = new_state != cell.state + def __evolve_cell(self, old, cell, new_state): + changed = new_state != old.state cell.state = new_state cell.is_dirty |= changed old.is_dirty |= changed + self._active |= changed if changed: cell.is_active = True for n in cell.neighbors: diff --git a/setup.py b/setup.py index 2f8e15b..ccdd9ce 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open('README.md') as f: setup( name="cellular_automaton", - version="1.0.3", + version="1.0.4", author="Richard Feistenauer", author_email="r.feistenauer@web.de", packages=find_packages(exclude=('tests', 'docs', 'examples')), diff --git a/tests/test_automaton.py b/tests/test_automaton.py index 98d0f42..f5ee7cf 100644 --- a/tests/test_automaton.py +++ b/tests/test_automaton.py @@ -15,7 +15,7 @@ limitations under the License. """ # pylint: disable=missing-function-docstring -# pylint: disable=redefined-outer-name +# pylint: disable=missing-class-docstring import pytest @@ -23,11 +23,11 @@ from .context import cellular_automaton as ca class TAutomaton(ca.CellularAutomaton): - """ Simple Automaton for test purposes """ - def evolve_rule(self, last_cell_state, neighbors_last_states): + + def evolve_rule(self, last_cell_state, __): return [last_cell_state[0] + 1] - def init_cell_state(self, cell_coordinate): + def init_cell_state(self, __): return [0] @@ -53,9 +53,31 @@ def test_dimensions(dimensions): assert automaton.cells[(1, ) * dimensions].state[0] == 1 -def test_process_evolution_calls(): +def test_copy_cells(): automaton = TAutomaton(NEIGHBORHOOD, [3, 3]) automaton.evolve(5) automaton2 = TAutomaton(NEIGHBORHOOD, [3, 3]) automaton2.cells = automaton.cells assert automaton2.cells[(1, 1)].state[0] == 5 + + +def test_automaton_goes_inactive(): + automaton = TAutomaton(NEIGHBORHOOD, [3, 3]) + assert automaton.active + + automaton.evolve_rule = lambda x, y: x + automaton.evolve() + assert not automaton.active + + +def test_reactivation(): + automaton = TAutomaton(NEIGHBORHOOD, [3, 3]) + + rule, automaton.evolve_rule = automaton.evolve_rule, lambda x, y: x + automaton.evolve() + assert not automaton.active + + automaton.reactivate() + automaton.evolve_rule = rule + automaton.evolve() + assert automaton.active