all skills

Python

one of the first languages that turned "i wonder if..." into actual programs.

PyForge is Python all the way down: a Tkinter app that wraps PyInstaller. the playground here is smaller and sillier.

used in PyForge

python · the browser game is TypeScript

signal snake

score0
best0session 0
speed1x

signal snake

eat the signal. mind the walls, and yourself.

arrows or wasd · space pausesswipe the board or use the pad

Arrow keys or WASD steer. Space or P pauses. R restarts. Eat the diamonds, avoid the walls and your own tail.

ready.

best score stays in this browser. the keys only work while the board has focus.

snake.py has a bug

this version never grows, no matter how much it eats. pick the line that is wrong.

tap a line.

arrows / wasd steerspace / p pauser restartsswipe or use the pad on touch

how this works

the game on this page runs in your browser, written in TypeScript: snake.ts holds the rules and a canvas renderer (not shown here) draws them. snake.py is the same core game for a terminal: same walls, same self-collision, same speed-up per apple. nothing here runs Python in the browser. the browser version adds visual extras on top: a combo, a rare bonus item, particles and a skin. there may be a bug in the python.

"""snake, the terminal version. run it with: python snake.py the rules are the ones snake.ts uses in the browser: walls kill, your own bodykills, no reversing into your neck, and every apple makes it a little faster(down to a floor). the browser version adds a combo, a rare bonus and a skin."""import cursesimport randomfrom collections import deque UP, DOWN, LEFT, RIGHT = (-1, 0), (1, 0), (0, -1), (0, 1)KEYS = {    curses.KEY_UP: UP, ord("w"): UP,    curses.KEY_DOWN: DOWN, ord("s"): DOWN,    curses.KEY_LEFT: LEFT, ord("a"): LEFT,    curses.KEY_RIGHT: RIGHT, ord("d"): RIGHT,}  def place_food(rows, cols, snake):    free = [(r, c) for r in range(1, rows - 1) for c in range(1, cols - 1)            if (r, c) not in snake]    return random.choice(free)  def play(screen):    curses.curs_set(0)    rows, cols = 18, 36    win = curses.newwin(rows, cols, 0, 0)    win.keypad(True)     snake = deque([(9, 10), (9, 9), (9, 8)])    direction = RIGHT    food = place_food(rows, cols, snake)    score, delay = 0, 140     while True:        win.erase()        win.border()        win.addstr(0, 2, f" score {score} ")        win.addch(food[0], food[1], "*")        for r, c in snake:            win.addch(r, c, "#")        win.timeout(delay)         turn = KEYS.get(win.getch())        # ignore a turn straight back into your own neck        if turn and (turn[0] + direction[0], turn[1] + direction[1]) != (0, 0):            direction = turn         head = (snake[0][0] + direction[0], snake[0][1] + direction[1])        hit_wall = head[0] in (0, rows - 1) or head[1] in (0, cols - 1)        if hit_wall or head in snake:            return score         snake.appendleft(head)        if head == food:            score += 1            delay = max(60, delay - 4)  # a little faster every time            food = place_food(rows, cols, snake)        else:            snake.pop()  if __name__ == "__main__":    final = curses.wrapper(play)    print(f"game over. score: {final}")