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.
 
 
 
 
 
 

172 line
4.9 KiB

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # libcaca Colour ASCII-Art library
  5. # Python language bindings
  6. # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com>
  7. # All Rights Reserved
  8. #
  9. # This library is free software. It comes without any warranty, to
  10. # the extent permitted by applicable law. You can redistribute it
  11. # and/or modify it under the terms of the Do What the Fuck You Want
  12. # to Public License, Version 2, as published by Sam Hocevar. See
  13. # http://www.wtfpl.net/ for more details.
  14. #
  15. """ Libcaca Python bindings """
  16. import random
  17. import sys
  18. import time
  19. import caca
  20. from caca.canvas import Canvas
  21. from caca.display import Display, Event
  22. class CellArray(object):
  23. def __init__(self, width, height):
  24. self.array = []
  25. self.width = width
  26. self.height = height
  27. for i in range(0, self.height):
  28. self.array.append([])
  29. for j in range(0, self.width):
  30. self.array[i].append([])
  31. def get(self, x, y):
  32. return self.array[x][y]
  33. def set(self, x, y, value):
  34. self.array[x][y] = value
  35. def neighbors(self, x, y):
  36. n = 0
  37. h = self.height
  38. w = self.width
  39. if self.get((x-1)%h, (y-1)%w):
  40. n += 1
  41. if self.get((x-1)%h, y):
  42. n += 1
  43. if self.get((x-1)%h, (y+1)%w):
  44. n += 1
  45. if self.get(x, (y-1)%w):
  46. n += 1
  47. if self.get(x, (y+1)%w):
  48. n += 1
  49. if self.get((x+1)%h, (y-1)%w):
  50. n += 1
  51. if self.get((x+1)%h, y):
  52. n += 1
  53. if self.get((x+1)%h, (y+1)%w):
  54. n += 1
  55. return n
  56. def population(self):
  57. n = 0
  58. for i in range(0, self.height):
  59. for j in range(0, self.width):
  60. if self.get(i, j):
  61. n += 1
  62. return n
  63. class CellApp(object):
  64. def __init__(self, width, height):
  65. self.cycle = 0
  66. self.auto = False
  67. self.width = width
  68. self.height = height
  69. self.ca = CellArray(self.width, self.height)
  70. self.cbuf = CellArray(self.width, self.height)
  71. def nextCycle(self):
  72. self.cycle += 1
  73. for x in range(0, self.ca.height):
  74. for y in range(0, self.ca.width):
  75. if self.ca.get(x, y):
  76. if self.ca.neighbors(x, y) >= 2 and self.ca.neighbors(x, y) <= 3:
  77. self.cbuf.set(x, y, 1)
  78. else:
  79. self.cbuf.set(x, y, 0)
  80. elif not self.ca.get(x, y):
  81. if self.ca.neighbors(x, y) == 3:
  82. self.cbuf.set(x, y, 1)
  83. else:
  84. self.cbuf.set(x, y, 0)
  85. else:
  86. self.cbuf.set(x, y, 0)
  87. for x in range(0, self.ca.height):
  88. for y in range(0, self.ca.width):
  89. self.ca.set(x, y, self.cbuf.get(x, y))
  90. def resetCycle(self):
  91. self.cycle = 0
  92. def randomCells(self):
  93. for x in range(0, self.ca.height):
  94. for y in range(0, self.ca.width):
  95. self.ca.set(x, y, random.randint(0, 1))
  96. def renderCells(self, cv):
  97. cv.clear()
  98. cv.set_color_ansi(caca.COLOR_WHITE, caca.COLOR_BLUE)
  99. cv.put_str(0, 0, " "*cv.get_width())
  100. cv.put_str(0, 0, "s: start, p: pause, n: next, r: random cells, z: reset all")
  101. cv.put_str(0, cv.get_height()-1, " "*cv.get_width())
  102. cv.put_str(0, cv.get_height()-1, "generation: %d, population: %d" % (self.cycle, self.ca.population()))
  103. cv.set_color_ansi(caca.COLOR_DEFAULT, caca.COLOR_BLACK)
  104. posx = (cv.get_height() - self.height) // 2
  105. posy = (cv.get_width() - self.width) // 2
  106. for x in range(0, self.ca.height):
  107. for y in range(0, self.ca.width):
  108. if self.ca.get(x, y):
  109. cv.put_str(posy+y, posx+x, "@")
  110. def zeroCells(self):
  111. for x in range(0, self.ca.height):
  112. for y in range(0, self.ca.width):
  113. self.ca.set(x, y, 0)
  114. if __name__ == "__main__":
  115. cv = Canvas()
  116. dp = Display(cv)
  117. ev = Event()
  118. app = CellApp(80, 20)
  119. app.zeroCells()
  120. while True:
  121. if dp.get_event(caca.EVENT_KEY_PRESS, ev, 2):
  122. ch = ev.get_key_ch()
  123. if ch == ord('q'):
  124. break
  125. elif ch == ord('s'):
  126. app.auto = True
  127. elif ch == ord('n'):
  128. app.nextCycle()
  129. elif ch == ord('r'):
  130. app.randomCells()
  131. elif ch == ord('p'):
  132. if app.auto:
  133. app.auto = False
  134. else:
  135. app.auto = True
  136. elif ch == ord('z'):
  137. app.resetCycle()
  138. app.zeroCells()
  139. app.auto = False
  140. if app.auto:
  141. app.nextCycle()
  142. app.renderCells(cv)
  143. dp.refresh()
  144. time.sleep(0.2)