from bibliopixel.animation.cube import Cube
from bibliopixel.colors import COLORS
from collections import deque
import random
import copy
import time
import itertools
[docs]class Table:
def __init__(self, width, height, depth, rand_max, table=None):
self.toroidal = True
self._rand_max = rand_max
if table:
self.table = table
self.depth = len(table)
self.height = len(table[0])
self.width = len(table[0][0])
else:
self.height = height
self.width = width
self.depth = depth
self.genNewTable()
self._oldStates = deque()
for i in range(3):
self._oldStates.append([])
self.offsets = list(itertools.product([-1, 0, 1], repeat=3))
self.offsets.remove((0, 0, 0)) # remove center point
[docs] def genNewTable(self):
self.table = []
random.seed(time.time())
for z in range(self.depth):
self.table.append([])
for y in range(0, self.height):
self.table[z].append([])
for x in range(0, self.width):
rand = random.randint(0, self._rand_max)
if rand == 0:
self.table[z][y].append(1)
else:
self.table[z][y].append(0)
[docs] def liveNeighbours(self, z, y, x):
"""Returns the number of live neighbours."""
count = 0
for oz, oy, ox in self.offsets:
cz, cy, cx = z + oz, y + oy, x + ox
if cz >= self.depth:
cz = 0
if cy >= self.height:
cy = 0
if cx >= self.width:
cx = 0
count += self.table[cz][cy][cx]
# if self.toroidal:
# if y == 0:
# if self.table[self.height - 1][x]:
# count = count + 1
# if y == self.height - 1:
# if self.table[0][x]:
# count = count + 1
# if x == 0:
# if self.table[y][self.width - 1]:
# count = count + 1
# if x == self.width - 1:
# if self.table[y][0]:
# count = count + 1
return count
[docs] def turn(self):
"""Turn"""
r = (4, 5, 5, 5)
nt = copy.deepcopy(self.table)
for z in range(self.depth):
for y in range(self.height):
for x in range(self.width):
neighbours = self.liveNeighbours(z, y, x)
if self.table[z][y][x] == 0 and (neighbours > r[0] and neighbours <= r[1]):
nt[z][y][x] = 1
elif self.table[z][y][x] == 1 and (neighbours > r[2] and neighbours < r[3]):
nt[z][y][x] = 0
self._oldStates.append(self.table)
if len(self._oldStates) > 3:
self._oldStates.popleft()
self.table = nt
[docs] def checkStable(self):
for t in self._oldStates:
if self.table == t:
return True
return False
[docs]class CubeGameOfLife(Cube):
COLOR_DEFAULTS = ('bg', COLORS.Off), ('color', COLORS.Red)
def __init__(self, layout, toroidal=False, **kwds):
super().__init__(layout, **kwds)
self._table = Table(self.x, self.y, self.z, 1, None)
self._table.toroidal = toroidal
self._finishCount = 0
[docs] def pre_run(self):
self._step = 0
[docs] def stepTable(self):
x, y, z = 0, 0, 0
for t_z in self._table.table:
for t_y in t_z:
for t_x in t_y:
color = self.palette(t_x != 0)
self.layout.set(x, y, z, color)
# print(x, y, z)
x = x + 1
y = y + 1
x = 0
z = z + 1
y = 0
self._table.turn()
[docs] def step(self, amt=1):
self.stepTable()
if self._table.checkStable():
self._finishCount += 1
if self._finishCount > 10:
self._table.genNewTable()
self._finishCount = 0
self.animComplete = True
self._step = 0