diff --git a/buba/__main__.py b/buba/__main__.py index 14337f2..6b0f1d6 100644 --- a/buba/__main__.py +++ b/buba/__main__.py @@ -7,6 +7,7 @@ from geventwebsocket.websocket import WebSocket from buba.animations.dbf import DBFAnimation from buba.animations.icalevents import IcalEvents +from buba.animations.snake import SnakeAnimation from buba.animations.time import BubaTime from buba.appconfig import AppConfig from buba.bubaanimator import BubaAnimator @@ -33,7 +34,7 @@ animator.add(DBFAnimation, ds100="AHST", station="Holstenstraße") animator.add(DBFAnimation, ds100="AHS", station="Altona", count=9) animator.add(IcalEvents, url="https://cloud.hamburg.ccc.de/remote.php/dav/public-calendars/QJAdExziSnNJEz5g?export", title="CCCHH Events") - +animator.add(SnakeAnimation) @app.route("/static/") def server_static(filepath): diff --git a/buba/animations/snake.py b/buba/animations/snake.py new file mode 100644 index 0000000..ece9a4c --- /dev/null +++ b/buba/animations/snake.py @@ -0,0 +1,92 @@ +import random +from time import sleep + +from buba.bubaanimator import BubaAnimation + + +class SnakeAnimation(BubaAnimation): + def __init__(self, buba): + super().__init__(buba) + # characters to render the grid and the snake + # Because of Python's limited codec, instead of using the correct Unicode + # codepoints, we're using the CP437 codepoints directly. + self.width = 20 + self.height = 4 + self.grid = [] + # 0:Space + self.charset = " " + # 1:up 2:right 3:down 4:left + self.charset += "\u001e\u0010\u001f\u0011" + # 5:vertical 6:horizontal + self.charset += "\u2551\u2550" + # 7:up-right 8:down-right 9:down-left 10:up-left + self.charset += "\u255a\u2554\u2557\u255d" + # 11:tail + self.charset += "\u25a0" + self.turn = [ + [5, 8, 5, 9], # have been going up, so coming from down + [10, 6, 9, 6], # have been going right, so coming from left + [5, 7, 5, 10], # have been going down, so coming from up + [7, 6, 8, 6], # have been going left, so coming from right + ] + + random.seed() + + def run(self): + self.grid = [list([0] * self.width) for i in range(self.height)] + x = random.randrange(self.width) + y = random.randrange(self.height) + d = random.randrange(4) + self.grid[y][x] = 1 + d + for r in range(self.height): + self.buba.simple_text(0, r, 0, "") # clear display + self.render() + while True: + if self.is_blocked(x, y, d): + end = True + prev_d = d + for n in self.shift(list(range(4))): + if not self.is_blocked(x, y, n): + end = False + d = n + break + if end: + self.grid[y][x] = 11 + self.render() + break + self.grid[y][x] = self.turn[prev_d][d] + else: + self.grid[y][x] = 5 + (d % 2) + (x, y) = self.next(x, y, d) + self.grid[y][x] = 1 + d + self.render() + sleep(0.5) + sleep(5) + + @staticmethod + def shift(a): + i = random.randrange(1, len(a)) + return a[i:] + a[:i] + + def next(self, x, y, d): + match d: + case 0: + y -= 1 + case 1: + x += 1 + case 2: + y += 1 + case 3: + x -= 1 + return (x, y) + + def is_blocked(self, x, y, d): + (x, y) = self.next(x, y, d) + return (y < 0 or y >= self.height or + x < 0 or x >= self.width or + self.grid[y][x] != 0) + + def render(self): + for r, row in enumerate(self.grid): + for c, col in enumerate(row): + self.buba.text(0, r, c*6, (c+1)*6-1, self.charset[col])