123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #!/usr/bin/env python3
-
- # ----------------------------------------------------------------------------
- # "THE BEER-WARE LICENSE" (Revision 42):
- # <xythobuz@xythobuz.de> wrote this file. As long as you retain this notice
- # you can do whatever you want with this stuff. If we meet some day, and you
- # think this stuff is worth it, you can buy me a beer in return. Thomas Buck
- # ----------------------------------------------------------------------------
-
- import time
- import random
-
- class GameOfLife:
- def __init__(self, g, f = 20, c1 = (255, 255, 255), c2 = (0, 0, 0), t = 20.0):
- self.gui = g
- self.interval = 1.0 / f
- self.setColors(c1, c2)
- self.timeout = t
- random.seed()
- self.restart()
-
- def restart(self):
- self.data = self.init()
- self.start = time.time()
- self.last = time.time()
- self.done = False
-
- def setColors(self, c1, c2):
- self.colorFG = c1
- self.colorBG = c2
-
- def init(self):
- data = []
- for x in range(0, self.gui.width):
- d = []
- for y in range(0, self.gui.height):
- v = False
- if random.randrange(0, 2) == 1:
- v = True
-
- d.append(v)
- data.append(d)
- return data
-
- def finished(self):
- if self.done or ((time.time() - self.start) > self.timeout):
- return True
- return False
-
- def alive(self, data, x, y):
- if (x < 0) or (y < 0) or (x >= self.gui.width) or (y >= self.gui.height):
- return False
- return data[x][y]
-
- def live_neighbours(self, data, x, y):
- c = 0
- for xOff in range(-1, 2):
- for yOff in range(-1, 2):
- if (xOff == 0) and (yOff == 0):
- continue
- if self.alive(data, x + xOff, y + yOff):
- c += 1
- if c == 4:
- # 4 or more is not interesting for us
- break
- return c
-
- def step(self):
- # deep copy
- old = [x[:] for x in self.data]
-
- for x in range(0, self.gui.width):
- for y in range(0, self.gui.height):
- ln = self.live_neighbours(old, x, y)
- if old[x][y] and ((ln == 2) or (ln == 3)):
- # Any live cell with two or three live neighbours survives.
- self.data[x][y] = True
- elif (not old[x][y]) and (ln == 3):
- # Any dead cell with three live neighbours becomes a live cell.
- self.data[x][y] = True
- else:
- # All other live cells die in the next generation. Similarly, all other dead cells stay dead.
- self.data[x][y] = False
-
- # compare new and old states
- same = True
- for x in range(0, self.gui.width):
- for y in range(0, self.gui.height):
- if self.data[x][y] != old[x][y]:
- same = False
- break
- self.done = same
-
- def draw(self):
- if (time.time() - self.last) > self.interval:
- self.last = time.time()
- self.step()
-
- for x in range(0, self.gui.width):
- for y in range(0, self.gui.height):
- if self.data[x][y]:
- self.gui.set_pixel(x, y, self.colorFG)
- else:
- self.gui.set_pixel(x, y, self.colorBG)
-
- if __name__ == "__main__":
- import platform
- t = None
- if platform.machine() == "armv7l":
- from pi import PiMatrix
- t = PiMatrix()
- else:
- from test import TestGUI
- t = TestGUI()
-
- g = GameOfLife(t)
-
- def helperRestart():
- c1 = (random.randrange(0, 256), random.randrange(0, 256), random.randrange(0, 256))
- c2 = (random.randrange(0, 128), random.randrange(0, 128), random.randrange(0, 128))
- g.setColors(c1, c2)
-
- # start out with random colors
- helperRestart()
-
- def helper():
- if g.finished():
- g.restart()
- helperRestart()
- g.draw()
-
- t.debug_loop(helper)
|