Python RGB Matrix games and animations https://www.xythobuz.de/ledmatrix_v2.html
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

life.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #!/usr/bin/env python3
  2. # ----------------------------------------------------------------------------
  3. # "THE BEER-WARE LICENSE" (Revision 42):
  4. # <xythobuz@xythobuz.de> wrote this file. As long as you retain this notice
  5. # you can do whatever you want with this stuff. If we meet some day, and you
  6. # think this stuff is worth it, you can buy me a beer in return. Thomas Buck
  7. # ----------------------------------------------------------------------------
  8. import time
  9. import random
  10. class GameOfLife:
  11. def __init__(self, g, f = 20, c1 = (255, 255, 255), c2 = (0, 0, 0), t = 20.0, rc = None, bt = 45.0):
  12. self.gui = g
  13. self.interval = 1.0 / f
  14. self.setColors(c1, c2)
  15. self.timeout = t
  16. self.randomizeColors = rc
  17. self.backupTimeout = bt
  18. random.seed()
  19. self.restart()
  20. self.editDistFinish = 20
  21. def restart(self):
  22. self.data = self.init()
  23. self.start = time.time()
  24. self.last = time.time()
  25. self.lastColor = time.time()
  26. self.done = False
  27. self.lastDiff = 100
  28. if self.randomizeColors != None:
  29. self.randomize()
  30. def setColors(self, c1 = (255, 255, 255), c2 = (0, 0, 0)):
  31. self.colorFG = c1
  32. self.colorBG = c2
  33. def randomize(self):
  34. c1 = (random.randrange(0, 16) << 4, random.randrange(0, 16) << 4, random.randrange(0, 16) << 4)
  35. c2 = (random.randrange(0, 16) << 0, random.randrange(0, 16) << 0, random.randrange(0, 16) << 0)
  36. self.setColors(c1, c2)
  37. def init(self):
  38. data = []
  39. for x in range(0, self.gui.width):
  40. d = []
  41. for y in range(0, self.gui.height):
  42. v = False
  43. if random.randrange(0, 2) == 1:
  44. v = True
  45. d.append(v)
  46. data.append(d)
  47. return data
  48. def finished(self):
  49. if self.done:
  50. return True
  51. if self.timeout != None:
  52. if (time.time() - self.start) > self.timeout:
  53. return True
  54. else:
  55. if self.lastDiff < self.editDistFinish:
  56. return True
  57. if (time.time() - self.start) > self.backupTimeout:
  58. return True
  59. return False
  60. def alive(self, data, x, y):
  61. if (x < 0) or (y < 0) or (x >= self.gui.width) or (y >= self.gui.height):
  62. return False
  63. return data[x][y]
  64. def live_neighbours(self, data, x, y):
  65. c = 0
  66. for xOff in range(-1, 2):
  67. for yOff in range(-1, 2):
  68. if (xOff == 0) and (yOff == 0):
  69. continue
  70. if self.alive(data, x + xOff, y + yOff):
  71. c += 1
  72. if c == 4:
  73. # 4 or more is not interesting for us
  74. break
  75. return c
  76. def step(self):
  77. # deep copy
  78. old = [x[:] for x in self.data]
  79. for x in range(0, self.gui.width):
  80. for y in range(0, self.gui.height):
  81. ln = self.live_neighbours(old, x, y)
  82. if old[x][y] and ((ln == 2) or (ln == 3)):
  83. # Any live cell with two or three live neighbours survives.
  84. self.data[x][y] = True
  85. elif (not old[x][y]) and (ln == 3):
  86. # Any dead cell with three live neighbours becomes a live cell.
  87. self.data[x][y] = True
  88. else:
  89. # All other live cells die in the next generation. Similarly, all other dead cells stay dead.
  90. self.data[x][y] = False
  91. # compare new and old states
  92. diff = 0
  93. for x in range(0, self.gui.width):
  94. for y in range(0, self.gui.height):
  95. if self.data[x][y] != old[x][y]:
  96. diff += 1
  97. if self.timeout == None:
  98. if diff >= self.editDistFinish:
  99. break
  100. else:
  101. if diff >= 1:
  102. break
  103. self.done = (diff == 0)
  104. self.lastDiff = diff
  105. def draw(self):
  106. now = time.time()
  107. if (now - self.last) > self.interval:
  108. self.last = now
  109. self.step()
  110. if (self.randomizeColors != None) and (self.randomizeColors != True):
  111. now = time.time()
  112. if (now - self.lastColor) > self.randomizeColors:
  113. self.lastColor = now
  114. self.randomize()
  115. for x in range(0, self.gui.width):
  116. for y in range(0, self.gui.height):
  117. if self.data[x][y]:
  118. self.gui.set_pixel(x, y, self.colorFG)
  119. else:
  120. self.gui.set_pixel(x, y, self.colorBG)
  121. if __name__ == "__main__":
  122. import util
  123. t = util.getTarget()
  124. g = GameOfLife(t, 20, (255, 255, 255), (0, 0, 0), None, 2.0)
  125. def helper():
  126. if g.finished():
  127. g.restart()
  128. g.draw()
  129. util.loop(t, helper)