2019-01-31 12:38:48 +00:00
|
|
|
import multiprocessing
|
|
|
|
|
2018-12-01 19:37:18 +00:00
|
|
|
from cellular_automaton.ca_rule import Rule
|
2019-02-09 18:06:18 +00:00
|
|
|
from cellular_automaton.ca_cell import Cell
|
2019-02-15 18:33:15 +00:00
|
|
|
from ctypes import c_int
|
2018-12-01 14:14:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
class CellularAutomaton:
|
2019-02-03 16:17:57 +00:00
|
|
|
def __init__(self, cells, dimension, evolution_rule: Rule):
|
|
|
|
self.cells = cells
|
|
|
|
self.dimension = dimension
|
2018-12-08 21:33:13 +00:00
|
|
|
self.evolution_rule = evolution_rule
|
2019-02-15 18:33:15 +00:00
|
|
|
self.evolution_iteration_index = -1
|
2018-12-01 14:14:22 +00:00
|
|
|
|
2018-12-01 19:37:18 +00:00
|
|
|
|
2019-01-06 10:21:46 +00:00
|
|
|
class CellularAutomatonProcessor:
|
2019-02-15 18:33:15 +00:00
|
|
|
def __init__(self, cellular_automaton):
|
|
|
|
self._ca = cellular_automaton
|
|
|
|
|
|
|
|
def evolve_x_times(self, x):
|
|
|
|
for x in range(x):
|
|
|
|
self.evolve()
|
|
|
|
|
|
|
|
def evolve(self):
|
|
|
|
self._ca.evolution_iteration_index += 1
|
|
|
|
i = self._ca.evolution_iteration_index
|
|
|
|
r = self._ca.evolution_rule.evolve_cell
|
|
|
|
list(map(lambda c: Cell.evolve_if_ready((c.state, c.neighbours), r, i), self._ca.cells))
|
|
|
|
# print(sum(1 for c in self._ca.cells if c.state.is_set_for_redraw()))
|
|
|
|
|
|
|
|
|
|
|
|
class CellularAutomatonMultiProcessor(CellularAutomatonProcessor):
|
|
|
|
def __init__(self, cellular_automaton, process_count: int = 2):
|
|
|
|
if process_count < 1:
|
|
|
|
raise ValueError
|
|
|
|
super().__init__(cellular_automaton)
|
2019-02-03 16:17:57 +00:00
|
|
|
self.ca = cellular_automaton
|
2019-02-09 18:06:18 +00:00
|
|
|
cells = {i: (c.state, c.neighbours) for i, c in enumerate(self.ca.cells)}
|
2019-02-03 16:17:57 +00:00
|
|
|
self.evolve_range = range(len(self.ca.cells))
|
2019-02-15 18:33:15 +00:00
|
|
|
self.evolution_iteration_index = multiprocessing.RawValue(c_int, -1)
|
|
|
|
|
|
|
|
self.pool = multiprocessing.Pool(processes=process_count,
|
|
|
|
initializer=_init_process,
|
|
|
|
initargs=(cells,
|
|
|
|
self.ca.evolution_rule,
|
|
|
|
self.evolution_iteration_index))
|
|
|
|
self._evolve_method = self.pool.map
|
|
|
|
|
2019-02-03 16:17:57 +00:00
|
|
|
for cell in self.ca.cells:
|
2019-02-09 18:06:18 +00:00
|
|
|
del cell.neighbours
|
2019-02-03 16:17:57 +00:00
|
|
|
|
|
|
|
def evolve(self):
|
2019-02-15 18:33:15 +00:00
|
|
|
self.ca.evolution_iteration_index += 1
|
|
|
|
self.evolution_iteration_index.value = self.ca.evolution_iteration_index
|
|
|
|
self.pool.map(_process_routine, self.evolve_range)
|
2019-02-03 16:17:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
global_cells = None
|
|
|
|
global_rule = None
|
|
|
|
global_iteration = None
|
|
|
|
|
|
|
|
|
|
|
|
def _init_process(cells, rule, index):
|
|
|
|
global global_rule, global_cells, global_iteration
|
|
|
|
global_cells = cells
|
|
|
|
global_rule = rule
|
|
|
|
global_iteration = index
|
|
|
|
|
|
|
|
|
|
|
|
def _process_routine(i):
|
2019-02-09 18:06:18 +00:00
|
|
|
Cell.evolve_if_ready(global_cells[i], global_rule.evolve_cell, global_iteration.value)
|
2019-01-06 10:21:46 +00:00
|
|
|
|