|
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # libcaca Colour ASCII-Art library
- # Python language bindings
- # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com>
- # All Rights Reserved
- #
- # This library is free software. It comes without any warranty, to
- # the extent permitted by applicable law. You can redistribute it
- # and/or modify it under the terms of the Do What The Fuck You Want
- # To Public License, Version 2, as published by Sam Hocevar. See
- # http://sam.zoy.org/wtfpl/COPYING for more details.
- #
-
- """ Libcaca Python bindings """
-
- import random
- import sys
- import time
-
- import caca
-
- from caca.canvas import Canvas
- from caca.display import Display, Event
-
- class CellArray(object):
- def __init__(self, width, height):
- self.array = []
- self.width = width
- self.height = height
-
- for i in xrange(0, self.height):
- self.array.append([])
- for j in xrange(0, self.width):
- self.array[i].append([])
-
- def get(self, x, y):
- return self.array[x][y]
-
- def set(self, x, y, value):
- self.array[x][y] = value
-
- def neighbors(self, x, y):
- n = 0
- h = self.height
- w = self.width
-
- if self.get((x-1)%h, (y-1)%w):
- n += 1
- if self.get((x-1)%h, y):
- n += 1
- if self.get((x-1)%h, (y+1)%w):
- n += 1
- if self.get(x, (y-1)%w):
- n += 1
- if self.get(x, (y+1)%w):
- n += 1
- if self.get((x+1)%h, (y-1)%w):
- n += 1
- if self.get((x+1)%h, y):
- n += 1
- if self.get((x+1)%h, (y+1)%w):
- n += 1
-
- return n
-
- def population(self):
- n = 0
-
- for i in xrange(0, self.height):
- for j in xrange(0, self.width):
- if self.get(i, j):
- n += 1
-
- return n
-
- class CellApp(object):
- def __init__(self, width, height):
- self.cycle = 0
- self.auto = False
- self.width = width
- self.height = height
-
- self.ca = CellArray(self.width, self.height)
- self.cbuf = CellArray(self.width, self.height)
-
- def nextCycle(self):
- self.cycle += 1
- for x in xrange(0, self.ca.height):
- for y in xrange(0, self.ca.width):
- if self.ca.get(x, y):
- if self.ca.neighbors(x, y) >= 2 and self.ca.neighbors(x, y) <= 3:
- self.cbuf.set(x, y, 1)
- else:
- self.cbuf.set(x, y, 0)
- elif not self.ca.get(x, y):
- if self.ca.neighbors(x, y) == 3:
- self.cbuf.set(x, y, 1)
- else:
- self.cbuf.set(x, y, 0)
- else:
- self.cbuf.set(x, y, 0)
- for x in xrange(0, self.ca.height):
- for y in xrange(0, self.ca.width):
- self.ca.set(x, y, self.cbuf.get(x, y))
-
- def resetCycle(self):
- self.cycle = 0
-
- def randomCells(self):
- for x in xrange(0, self.ca.height):
- for y in xrange(0, self.ca.width):
- self.ca.set(x, y, random.randint(0, 1))
-
- def renderCells(self, cv):
- cv.clear()
- cv.set_color_ansi(caca.COLOR_WHITE, caca.COLOR_BLUE)
- cv.put_str(0, 0, " "*cv.get_width())
- cv.put_str(0, 0, "s: start, p: pause, n: next, r: random cells, z: reset all")
- cv.put_str(0, cv.get_height()-1, " "*cv.get_width())
- cv.put_str(0, cv.get_height()-1, "generation: %d, population: %d" % (self.cycle, self.ca.population()))
- cv.set_color_ansi(caca.COLOR_DEFAULT, caca.COLOR_BLACK)
- posx = (cv.get_height() - self.height) / 2
- posy = (cv.get_width() - self.width) / 2
- for x in xrange(0, self.ca.height):
- for y in xrange(0, self.ca.width):
- if self.ca.get(x, y):
- cv.put_str(posy+y, posx+x, '@')
-
- def zeroCells(self):
- for x in xrange(0, self.ca.height):
- for y in xrange(0, self.ca.width):
- self.ca.set(x, y, 0)
-
- if __name__ == "__main__":
- cv = Canvas()
- dp = Display(cv)
- ev = Event()
-
- app = CellApp(80, 20)
- app.zeroCells()
-
- while True:
- if dp.get_event(caca.EVENT_KEY_PRESS, ev, 2):
- ch = ev.get_key_ch()
- if ch == ord('q'):
- break
- elif ch == ord('s'):
- app.auto = True
- elif ch == ord('n'):
- app.nextCycle()
- elif ch == ord('r'):
- app.randomCells()
- elif ch == ord('p'):
- if app.auto:
- app.auto = False
- else:
- app.auto = True
- elif ch == ord('z'):
- app.resetCycle()
- app.zeroCells()
- app.auto = False
-
- if app.auto:
- app.nextCycle()
-
- app.renderCells(cv)
- dp.refresh()
- time.sleep(0.2)
|