try with processing, but data share failed
This commit is contained in:
parent
bad67211ec
commit
530072b1d5
@ -32,7 +32,7 @@ class WorldGeneratorWindow:
|
||||
|
||||
surfaces_to_update = []
|
||||
for cell in self._cellular_automaton.grid.get_active_cells().values():
|
||||
if not cell.dirty:
|
||||
if not cell.is_dirty():
|
||||
continue
|
||||
cell_coordinate = cell.coordinate
|
||||
status = cell.get_status_for_iteration(self._cellular_automaton.get_iteration_index())
|
||||
@ -45,6 +45,7 @@ class WorldGeneratorWindow:
|
||||
surface_pos = [x * y for x, y in zip(cell_size, cell_coordinate)]
|
||||
surface_pos[1] += 20
|
||||
surfaces_to_update.append(self.screen.fill(cell_color, (surface_pos, cell_size)))
|
||||
cell.release_dirty()
|
||||
pygame.display.update(surfaces_to_update)
|
||||
|
||||
def main_loop(self):
|
||||
@ -75,6 +76,7 @@ class WorldGeneratorWindow:
|
||||
|
||||
class TestRule(Rule):
|
||||
def evolve_cell(self, cell, neighbors, iteration_index):
|
||||
active = False
|
||||
last_iteration = iteration_index - 1
|
||||
if cell.get_status_for_iteration(last_iteration) is None:
|
||||
rand = random.randrange(0, 101, 1)
|
||||
@ -83,15 +85,18 @@ class TestRule(Rule):
|
||||
cell.set_status_for_iteration([rand], iteration_index)
|
||||
cell.set_status_for_iteration([rand], iteration_index + 1)
|
||||
if rand != 0:
|
||||
cell.dirty = True
|
||||
active = True
|
||||
cell.set_dirty()
|
||||
elif len(neighbors) == 8:
|
||||
left_neighbour_status = neighbors[3].get_status_for_iteration(last_iteration)
|
||||
cell.set_status_for_iteration(left_neighbour_status, iteration_index)
|
||||
return cell.dirty
|
||||
active = cell.set_status_for_iteration(left_neighbour_status, iteration_index)
|
||||
if active:
|
||||
cell.set_dirty()
|
||||
return active
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rule = TestRule()
|
||||
ca = CellularAutomaton([500, 500], MooreNeighborhood(EdgeRule.IGNORE_EDGE_CELLS), rule, thread_count=1)
|
||||
ca = CellularAutomaton([10, 10], MooreNeighborhood(EdgeRule.IGNORE_EDGE_CELLS), rule, thread_count=2)
|
||||
ca_window = WorldGeneratorWindow([1000, 730], ca)
|
||||
ca_window.main_loop()
|
||||
|
@ -4,19 +4,29 @@ class Cell:
|
||||
self.coordinate = coordinate
|
||||
self.neighbours = []
|
||||
self._status = [None, None]
|
||||
self.dirty = False
|
||||
self._dirty = False
|
||||
|
||||
def set_neighbours(self, neighbours: list):
|
||||
self.neighbours = neighbours
|
||||
|
||||
def is_dirty(self):
|
||||
return self._dirty
|
||||
|
||||
def set_dirty(self):
|
||||
self._dirty = True
|
||||
|
||||
def release_dirty(self):
|
||||
self._dirty = False
|
||||
|
||||
def set_status_for_iteration(self, new_status, iteration):
|
||||
""" Will set the new status for Iteration.
|
||||
:param new_status: The new status to set.
|
||||
:param iteration: Uses the iteration index, to differ between current and next state.
|
||||
:return True if status has changed.
|
||||
"""
|
||||
self._status[iteration % 2] = new_status
|
||||
|
||||
self.dirty = self._status[0] != self._status[1]
|
||||
return self._status[0] != self._status[1]
|
||||
|
||||
def get_status_for_iteration(self, iteration):
|
||||
""" Will return the status for the iteration.
|
||||
|
@ -1,4 +1,4 @@
|
||||
import threading
|
||||
import multiprocessing
|
||||
import time
|
||||
|
||||
from cellular_automaton.ca_grid import Grid
|
||||
@ -9,84 +9,73 @@ from cellular_automaton.ca_neighborhood import Neighborhood
|
||||
class CellularAutomaton:
|
||||
def __init__(self, dimension: list, neighborhood: Neighborhood, rule_: Rule=None, thread_count: int=4):
|
||||
self.grid = Grid(dimension, neighborhood)
|
||||
self._rule = rule_
|
||||
self.rule = rule_
|
||||
self._thread_count = thread_count
|
||||
self._iteration = 0
|
||||
self.iteration = 0
|
||||
self.test_number = 0
|
||||
|
||||
def set_rule(self, rule: Rule):
|
||||
self._rule = rule
|
||||
self.rule = rule
|
||||
|
||||
def set_thread_count(self, thread_count: int):
|
||||
self._thread_count = thread_count
|
||||
|
||||
def get_iteration_index(self):
|
||||
return self._iteration
|
||||
return self.iteration
|
||||
|
||||
def evolve(self):
|
||||
""" Evolves all active cells for one time step.
|
||||
:return: True if all cells are inactive.
|
||||
"""
|
||||
if self._all_cells_are_inactive():
|
||||
return True
|
||||
else:
|
||||
self._iteration += 1
|
||||
self._delegate_evolve_to_threads()
|
||||
self.iteration += 1
|
||||
self._start_multi_process_cell_evolution()
|
||||
return False
|
||||
|
||||
def _delegate_evolve_to_threads(self):
|
||||
cell_lists_for_threats = self.create_cell_lists_for_threads()
|
||||
def _start_multi_process_cell_evolution(self):
|
||||
""" Evolves the cells in separate threads """
|
||||
lists_of_cell_names = self._create_list_of_cell_names_lists_for_all_threads()
|
||||
self.grid.clear_active_cells()
|
||||
threads = self._start_treads_to_evolve_grid(cell_lists_for_threats)
|
||||
self._wait_for_all_threads_to_finish(threads)
|
||||
jobs = self._start_treads_to_evolve_grid(lists_of_cell_names)
|
||||
self._wait_for_all_threads_to_finish(jobs)
|
||||
print(self.test_number)
|
||||
|
||||
def _all_cells_are_inactive(self):
|
||||
return len(self.grid.get_names_of_active_cells()) == 0
|
||||
|
||||
def create_cell_lists_for_threads(self):
|
||||
def _create_list_of_cell_names_lists_for_all_threads(self):
|
||||
active_cells = self.grid.get_names_of_active_cells()
|
||||
cell_count_per_thread = int(len(active_cells) / self._thread_count)
|
||||
return self.divide_active_cells(cell_count_per_thread, active_cells)
|
||||
return self._divide_list_in_parts_of_size(active_cells, cell_count_per_thread)
|
||||
|
||||
@staticmethod
|
||||
def divide_active_cells(cell_count_per_thread, active_cells):
|
||||
def _divide_list_in_parts_of_size(active_cells: list, cell_count_per_thread: int):
|
||||
return [active_cells[i:i + cell_count_per_thread]
|
||||
for i in range(0, len(active_cells), cell_count_per_thread)]
|
||||
|
||||
def _start_treads_to_evolve_grid(self, cell_lists_for_threats):
|
||||
threads = []
|
||||
def _start_treads_to_evolve_grid(self, lists_of_cell_names):
|
||||
jobs = []
|
||||
for t in range(self._thread_count):
|
||||
new_thread = _EvolutionThread(self.grid, self._rule, cell_lists_for_threats[t], self._iteration)
|
||||
threads.append(new_thread)
|
||||
new_thread.start()
|
||||
return threads
|
||||
process = multiprocessing.Process(target=_evolve_cells, args=(self, lists_of_cell_names[t]))
|
||||
jobs.append(process)
|
||||
process.start()
|
||||
return jobs
|
||||
|
||||
@staticmethod
|
||||
def _wait_for_all_threads_to_finish(threads):
|
||||
for thread in threads:
|
||||
while not thread.is_finished():
|
||||
time.sleep(0.01)
|
||||
|
||||
thread.join()
|
||||
def _wait_for_all_threads_to_finish(jobs):
|
||||
for process in jobs:
|
||||
process.join()
|
||||
|
||||
|
||||
class _EvolutionThread(threading.Thread):
|
||||
def __init__(self, grid: Grid, rule: Rule, cell_list: list, iteration: int):
|
||||
super(_EvolutionThread, self).__init__()
|
||||
self._grid = grid
|
||||
self._rule = rule
|
||||
self._cell_list = cell_list
|
||||
self._next_state = []
|
||||
self._finished = False
|
||||
self._iteration = iteration
|
||||
|
||||
def run(self):
|
||||
for cell in self._cell_list:
|
||||
cell_info = self._grid.get_cell_and_neighbors(cell)
|
||||
active = self._rule.evolve_cell(cell_info[0], cell_info[1], self._iteration)
|
||||
def _evolve_cells(cellular_automaton, cell_names: list):
|
||||
time.sleep(2)
|
||||
cellular_automaton.test_number += 1
|
||||
print(cellular_automaton.grid)
|
||||
for cell_name in cell_names:
|
||||
cell_info = cellular_automaton.grid.get_cell_and_neighbors(cell_name)
|
||||
active = cellular_automaton.rule.evolve_cell(cell_info[0], cell_info[1], cellular_automaton.iteration)
|
||||
|
||||
if active:
|
||||
self._grid.set_cell_and_neighbours_active(cell_info)
|
||||
self._finished = True
|
||||
|
||||
def get_new_cell_states(self):
|
||||
return self._next_state
|
||||
|
||||
def is_finished(self):
|
||||
return self._finished
|
||||
cellular_automaton.grid.set_cell_and_neighbours_active(cell_info)
|
||||
|
Loading…
Reference in New Issue
Block a user