changed grid to factory
This commit is contained in:
parent
9c855c507a
commit
743d6f4548
@ -3,6 +3,9 @@
|
|||||||
from cellular_automaton.ca_cell_state import CellState
|
from cellular_automaton.ca_cell_state import CellState
|
||||||
from cellular_automaton.ca_rule import Rule
|
from cellular_automaton.ca_rule import Rule
|
||||||
|
|
||||||
|
from cellular_automaton.cellular_automaton import CellularAutomaton, CellularAutomatonProcessor
|
||||||
|
from cellular_automaton.ca_factory import Factory
|
||||||
|
|
||||||
|
|
||||||
class TestRule(Rule):
|
class TestRule(Rule):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -31,23 +34,24 @@ class MyState(CellState):
|
|||||||
return [red, 0, 0]
|
return [red, 0, 0]
|
||||||
|
|
||||||
|
|
||||||
|
def make_cellular_automaton(dimension, neighborhood, rule, state_class):
|
||||||
|
ca_factory = Factory()
|
||||||
|
cells = ca_factory.make_cellular_automaton(dimension=dimension, neighborhood=neighborhood, state_class=state_class)
|
||||||
|
return CellularAutomaton(cells, dimension, rule)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import random
|
import random
|
||||||
from multiprocessing import freeze_support
|
from multiprocessing import freeze_support
|
||||||
|
|
||||||
from cellular_automaton.cellular_automaton import CellularAutomaton, CellularAutomatonProcessor
|
|
||||||
from cellular_automaton.ca_neighborhood import MooreNeighborhood, EdgeRule
|
from cellular_automaton.ca_neighborhood import MooreNeighborhood, EdgeRule
|
||||||
from cellular_automaton.ca_display import PyGameFor2D
|
from cellular_automaton.ca_display import PyGameFor2D
|
||||||
from cellular_automaton.ca_grid import Grid
|
|
||||||
|
|
||||||
freeze_support()
|
freeze_support()
|
||||||
|
|
||||||
random.seed(1000)
|
random.seed(1000)
|
||||||
dimension = [100, 100]
|
# best is 400/400 with 0,2 ca speed and 0,09 redraw
|
||||||
rule = TestRule()
|
neighborhood = MooreNeighborhood(EdgeRule.FIRST_AND_LAST_CELL_OF_DIMENSION_ARE_NEIGHBORS)
|
||||||
grid = Grid(dimension=dimension, # best is 400/400 with 0,2 ca speed and 0,09 redraw
|
ca = make_cellular_automaton(dimension=[100, 100], neighborhood=neighborhood, rule=TestRule(), state_class=MyState)
|
||||||
neighborhood=MooreNeighborhood(EdgeRule.FIRST_AND_LAST_CELL_OF_DIMENSION_ARE_NEIGHBORS),
|
|
||||||
state_class=MyState)
|
|
||||||
ca = CellularAutomaton(tuple(grid.get_cells().values()), dimension, rule)
|
|
||||||
ca_window = PyGameFor2D(window_size=[1000, 800], cellular_automaton=ca)
|
ca_window = PyGameFor2D(window_size=[1000, 800], cellular_automaton=ca)
|
||||||
ca_processor = CellularAutomatonProcessor(process_count=4, cellular_automaton=ca)
|
ca_processor = CellularAutomatonProcessor(process_count=4, cellular_automaton=ca)
|
||||||
ca_window.main_loop(cellular_automaton_processor=ca_processor,
|
ca_window.main_loop(cellular_automaton_processor=ca_processor,
|
||||||
|
@ -77,7 +77,7 @@ class PyGameFor2D:
|
|||||||
size = asizeof.asizeof(self._cellular_automaton)
|
size = asizeof.asizeof(self._cellular_automaton)
|
||||||
cProfile.runctx("cap.evolve_x_times(10)", None, locals(), "performance_test")
|
cProfile.runctx("cap.evolve_x_times(10)", None, locals(), "performance_test")
|
||||||
print("PERFORMANCE")
|
print("PERFORMANCE")
|
||||||
p = pstats.Stats('performance_test2')
|
p = pstats.Stats('performance_test')
|
||||||
p.strip_dirs()
|
p.strip_dirs()
|
||||||
# sort by cumulative time in a function
|
# sort by cumulative time in a function
|
||||||
p.sort_stats('cumulative').print_stats(10)
|
p.sort_stats('cumulative').print_stats(10)
|
||||||
|
61
src/cellular_automaton/ca_factory.py
Normal file
61
src/cellular_automaton/ca_factory.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
from cellular_automaton.ca_cell import Cell, CellState
|
||||||
|
from cellular_automaton.ca_neighborhood import Neighborhood
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
|
|
||||||
|
class Factory:
|
||||||
|
def __init__(self):
|
||||||
|
self._dimension = None
|
||||||
|
self._state_class = None
|
||||||
|
self._cells = {}
|
||||||
|
|
||||||
|
def make_cellular_automaton(self,
|
||||||
|
dimension,
|
||||||
|
neighborhood: Type[Neighborhood],
|
||||||
|
state_class: Type[CellState]):
|
||||||
|
self._dimension = dimension
|
||||||
|
self._state_class = state_class
|
||||||
|
|
||||||
|
self.__create_cells()
|
||||||
|
self.__set_cell_neighbours(self._cells, neighborhood)
|
||||||
|
return tuple(self._cells.values())
|
||||||
|
|
||||||
|
def __create_cells(self, dimension_index=0, coordinate=None):
|
||||||
|
""" Recursively steps down the dimensions to create cells in n dimensions and adds them to a dict.
|
||||||
|
:param dimension_index: The index indicating which dimension is currently traversed.
|
||||||
|
:param coordinate: The coordinate generated so far.
|
||||||
|
(each recursion adds one dimension to the coordinate.
|
||||||
|
"""
|
||||||
|
coordinate = _instantiate_coordinate_if_necessary(coordinate)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.__recursive_step_down_dimensions(coordinate, dimension_index)
|
||||||
|
except IndexError:
|
||||||
|
coordinate_string = _join_coordinate(coordinate)
|
||||||
|
self._cells[coordinate_string] = Cell(self._state_class, coordinate)
|
||||||
|
|
||||||
|
def __recursive_step_down_dimensions(self, coordinate, dimension_index):
|
||||||
|
""" For the range of the current dimension, recalls the recursion method.
|
||||||
|
:param coordinate: The coordinate so far.
|
||||||
|
:param dimension_index: The current dimension lvl.
|
||||||
|
"""
|
||||||
|
for cell_index in range(self._dimension[dimension_index]):
|
||||||
|
new_cod = coordinate + [cell_index]
|
||||||
|
self.__create_cells(dimension_index + 1, new_cod)
|
||||||
|
|
||||||
|
def __set_cell_neighbours(self, cells, neighborhood):
|
||||||
|
for cell in cells.values():
|
||||||
|
n_coordinates = neighborhood.calculate_cell_neighbor_coordinates(cell.get_coordinate(),
|
||||||
|
self._dimension)
|
||||||
|
cell.set_neighbours([cells[_join_coordinate(coordinate)].get_state() for coordinate in n_coordinates])
|
||||||
|
|
||||||
|
|
||||||
|
def _instantiate_coordinate_if_necessary(coordinate):
|
||||||
|
if coordinate is None:
|
||||||
|
coordinate = []
|
||||||
|
return coordinate
|
||||||
|
|
||||||
|
|
||||||
|
def _join_coordinate(coordinate):
|
||||||
|
return '-'.join(str(x) for x in coordinate)
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
from cellular_automaton.ca_cell import Cell
|
|
||||||
from cellular_automaton.ca_neighborhood import Neighborhood
|
|
||||||
|
|
||||||
|
|
||||||
class Grid:
|
|
||||||
def __init__(self, dimension: list, neighborhood: Neighborhood, state_class):
|
|
||||||
self._dimension = dimension
|
|
||||||
self._cells = {}
|
|
||||||
self._active_cells = {}
|
|
||||||
self._state_class = state_class
|
|
||||||
|
|
||||||
self._init_cells(neighborhood)
|
|
||||||
|
|
||||||
def _init_cells(self, neighborhood):
|
|
||||||
self._create_cells()
|
|
||||||
self._set_cell_neighbours(neighborhood)
|
|
||||||
self._active_cells = self._cells.copy()
|
|
||||||
self._set_all_cells_active()
|
|
||||||
|
|
||||||
def _create_cells(self, dimension_index=0, coordinate=None):
|
|
||||||
""" Recursively steps down the dimensions to create cells in n dimensions and adds them to a dict.
|
|
||||||
:param dimension_index: The index indicating which dimension is currently traversed.
|
|
||||||
:param coordinate: The coordinate generated so far.
|
|
||||||
(each recursion adds one dimension to the coordinate.
|
|
||||||
"""
|
|
||||||
coordinate = _instantiate_coordinate_if_necessary(coordinate)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._recursive_step_down_dimensions(coordinate, dimension_index, self._create_cells)
|
|
||||||
except IndexError:
|
|
||||||
coordinate_string = _join_coordinate(coordinate)
|
|
||||||
self._cells[coordinate_string] = Cell(self._state_class, coordinate)
|
|
||||||
|
|
||||||
def _recursive_step_down_dimensions(self, coordinate, dimension_index, recursion_method):
|
|
||||||
""" For the range of the current dimension, recalls the recursion method.
|
|
||||||
:param coordinate: The coordinate so far.
|
|
||||||
:param dimension_index: The current dimension lvl.
|
|
||||||
:param recursion_method: The method to call for recursion.
|
|
||||||
"""
|
|
||||||
for cell_index in range(self._dimension[dimension_index]):
|
|
||||||
new_cod = coordinate + [cell_index]
|
|
||||||
recursion_method(dimension_index + 1, new_cod)
|
|
||||||
|
|
||||||
def _set_cell_neighbours(self, neighborhood):
|
|
||||||
for cell in self._cells.values():
|
|
||||||
neighbours_coordinates = neighborhood.calculate_cell_neighbor_coordinates(cell.get_coordinate(),
|
|
||||||
self._dimension)
|
|
||||||
cell.set_neighbours(list(map(self._get_cell_state_by_coordinate, neighbours_coordinates)))
|
|
||||||
|
|
||||||
def _get_cell_state_by_coordinate(self, coordinate):
|
|
||||||
return self._cells[_join_coordinate(coordinate)].get_state()
|
|
||||||
|
|
||||||
def _set_all_cells_active(self):
|
|
||||||
for cell_key, cell in self._cells.items():
|
|
||||||
self._active_cells[cell_key] = cell
|
|
||||||
|
|
||||||
def get_active_cell_names(self):
|
|
||||||
return list(self._active_cells.keys())
|
|
||||||
|
|
||||||
def get_active_cells(self):
|
|
||||||
return self._active_cells
|
|
||||||
|
|
||||||
def get_cells(self):
|
|
||||||
return self._cells
|
|
||||||
|
|
||||||
def get_dimension(self):
|
|
||||||
return self._dimension
|
|
||||||
|
|
||||||
|
|
||||||
def _instantiate_coordinate_if_necessary(coordinate):
|
|
||||||
if coordinate is None:
|
|
||||||
coordinate = []
|
|
||||||
return coordinate
|
|
||||||
|
|
||||||
|
|
||||||
def _join_coordinate(coordinate):
|
|
||||||
return '-'.join(str(x) for x in coordinate)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user