Fix/display stop when done
This commit is contained in:
parent
9e211aa581
commit
6d1666bb8b
@ -98,8 +98,12 @@ 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.8
|
||||
- Fixes automaton using edge cells with radius > 1 not working
|
||||
- Fixes automaton is not stopping after evolution ended
|
||||
|
||||
#### 1.0.7
|
||||
- Fixes automaton ont active on reactivation
|
||||
- Fixes automaton not active on reactivation
|
||||
|
||||
#### 1.0.6
|
||||
- Fixes reactivation not redrawing all cells
|
||||
|
@ -75,15 +75,19 @@ class CellularAutomatonCreator(abc.ABC):
|
||||
|
||||
|
||||
class CellularAutomaton(CellularAutomatonCreator, abc.ABC):
|
||||
"""
|
||||
This class represents a cellular automaton.
|
||||
""" This class represents a cellular automaton.
|
||||
It can be created with n dimensions and can handle different neighborhood definitions.
|
||||
|
||||
:param dimension: Iterable of len = dimensions
|
||||
(e.g. [4, 3, 3, 3] = 4 x 3 x 3 x 3 cells in a four dimensional cube).
|
||||
:param neighborhood: Defines which cells are considered neighbors.
|
||||
It is intended to be uses as base class.
|
||||
Override `init_cell_state()` to define the state the cell(s) are initiated with.
|
||||
Override `evolve()` to define the rule that is aplied on every evolution step of this automaton.
|
||||
"""
|
||||
def __init__(self, neighborhood: Neighborhood, *args, **kwargs):
|
||||
""" Initiates a cellular automaton by the use of the `init_cell_state` method.
|
||||
:param neighborhood: Defines which cells are considered neighbors.
|
||||
:param dimension: Iterable of len = dimensions
|
||||
(e.g. [4, 3, 3, 3] = 4 x 3 x 3 x 3 cells in a four dimensional cube).
|
||||
"""
|
||||
super().__init__(neighborhood=neighborhood, *args, **kwargs)
|
||||
self._evolution_step = 0
|
||||
self._active = True
|
||||
@ -132,7 +136,7 @@ class CellularAutomaton(CellularAutomatonCreator, abc.ABC):
|
||||
evolution_rule = self.evolve_rule
|
||||
for old, new in zip(this_state.values(), next_state.values()):
|
||||
if old.is_active:
|
||||
new_state = evolution_rule(old.state, [n.state for n in old.neighbors])
|
||||
new_state = evolution_rule(old.state.copy(), [n.state for n in old.neighbors])
|
||||
old.is_active = False
|
||||
evolve_cell(old, new, new_state)
|
||||
|
||||
|
@ -117,7 +117,8 @@ class CAWindow:
|
||||
time.sleep(rest_time)
|
||||
|
||||
def _not_at_the_end(self, last_evolution_step):
|
||||
return self._cellular_automaton.evolution_step < last_evolution_step or last_evolution_step <= 0
|
||||
return (self._cellular_automaton.evolution_step < last_evolution_step or last_evolution_step <= 0) \
|
||||
and self._cellular_automaton.active
|
||||
|
||||
def __calculate_cell_display_size(self, stretch_cells): # pragma: no cover
|
||||
grid_dimension = self._cellular_automaton.dimension
|
||||
|
@ -83,7 +83,7 @@ class Neighborhood:
|
||||
yield tuple(map(operator.add, rel_n, cell_coordinate))
|
||||
|
||||
def __is_coordinate_on_an_edge(self, coordinate):
|
||||
return any(ci in [0, di-1] for ci, di in zip(coordinate, self._grid_dimensions))
|
||||
return any(not(self._radius-1 < ci < di-self._radius) for ci, di in zip(coordinate, self._grid_dimensions))
|
||||
|
||||
|
||||
class MooreNeighborhood(Neighborhood):
|
||||
@ -154,7 +154,6 @@ class RadialNeighborhood(Neighborhood):
|
||||
cross_sum = 0
|
||||
for coordinate_i in rel_neighbor:
|
||||
cross_sum += pow(coordinate_i, 2)
|
||||
|
||||
return math.sqrt(cross_sum) <= self._radius + self.delta
|
||||
|
||||
|
||||
|
@ -59,5 +59,7 @@ def profile(code):
|
||||
|
||||
if __name__ == "__main__":
|
||||
with contextlib.suppress(KeyboardInterrupt):
|
||||
print("=== CREATION ===")
|
||||
profile('ca = StarFallAutomaton()')
|
||||
print("=== COMPUTATION ===")
|
||||
profile('ca.evolve(times=10)')
|
||||
|
2
setup.py
2
setup.py
@ -7,7 +7,7 @@ with open('README.md') as f:
|
||||
|
||||
setup(
|
||||
name="cellular_automaton",
|
||||
version="1.0.7",
|
||||
version="1.0.8",
|
||||
author="Richard Feistenauer",
|
||||
author_email="r.feistenauer@web.de",
|
||||
packages=find_packages(exclude=('tests', 'docs', 'examples')),
|
||||
|
@ -52,7 +52,10 @@ class TAutomaton(ca.CellularAutomaton):
|
||||
return [1] if cell_coordinate == (1, 1) else [0]
|
||||
|
||||
def evolve_rule(self, last_cell_state, neighbors_last_states):
|
||||
return [last_cell_state[0] + 1] if neighbors_last_states else last_cell_state
|
||||
ns = last_cell_state[:]
|
||||
if 0 < last_cell_state[0] < 40:
|
||||
ns[0] += 1
|
||||
return ns
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -70,3 +73,12 @@ def test_evolution_steps_per_draw(automaton, pygame_mock):
|
||||
def test_updated_rectangle_calls(automaton, pygame_mock):
|
||||
ca.CAWindow(cellular_automaton=automaton, window_size=(10, 10)).run(last_evolution_step=4)
|
||||
assert pygame_mock.display.update.call_count == 4 * (3 + 1) # steps * (texts + changed cells)
|
||||
|
||||
@import_mock(module='pygame')
|
||||
def test_ends_when_ca_is_done(automaton, pygame_mock):
|
||||
automaton.evolve(39)
|
||||
assert automaton.active == True
|
||||
assert automaton.evolution_step == 39
|
||||
ca.CAWindow(cellular_automaton=automaton, window_size=(10, 10)).run(last_evolution_step=45)
|
||||
assert automaton.active == False
|
||||
assert automaton.evolution_step == 40
|
||||
|
@ -93,6 +93,26 @@ def test_radial():
|
||||
(1, 4), (2, 4), (3, 4))
|
||||
|
||||
|
||||
def test_radial_neighbor_coords():
|
||||
neighborhood = ca.RadialNeighborhood(edge_rule=ca.EdgeRule.FIRST_AND_LAST_CELL_OF_DIMENSION_ARE_NEIGHBORS, radius=2)
|
||||
neighbor_coords = neighborhood.calculate_cell_neighbor_coordinates((0, 0), (10, 10))
|
||||
assert neighbor_coords == ((9, 8), (0, 8), (1, 8),
|
||||
(8, 9), (9, 9), (0, 9), (1, 9), (2, 9),
|
||||
(8, 0), (9, 0), (1, 0), (2, 0),
|
||||
(8, 1), (9, 1), (0, 1), (1, 1), (2, 1),
|
||||
(9, 2), (0, 2), (1, 2))
|
||||
|
||||
|
||||
def test_radial_neighbor_coords():
|
||||
neighborhood = ca.RadialNeighborhood(edge_rule=ca.EdgeRule.FIRST_AND_LAST_CELL_OF_DIMENSION_ARE_NEIGHBORS, radius=2)
|
||||
neighbor_coords = neighborhood.calculate_cell_neighbor_coordinates((1, 1), (10, 10))
|
||||
assert neighbor_coords == ((0, 9), (1, 9), (2, 9),
|
||||
(9, 0), (0, 0), (1, 0), (2, 0), (3, 0),
|
||||
(9, 1), (0, 1), (2, 1), (3, 1),
|
||||
(9, 2), (0, 2), (1, 2), (2, 2), (3, 2),
|
||||
(0, 3), (1, 3), (2, 3))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(('coordinate', 'expected_neighborhood'),
|
||||
(((2, 2), ((1, 0), (2, 0), (3, 0),
|
||||
(0, 1), (1, 1), (2, 1), (3, 1),
|
||||
|
Loading…
Reference in New Issue
Block a user