#!/usr/bin/env python3 import ast import random as r from blup import frame from blup import animation import blup.writebml import argparse import math r.seed() WIDTH = 22 HEIGHT = 16 COLOR_DEPTH = 256 COLORS = 3 DEAD = 0 DEAD_COLOR = (0, 0, 0) ALIVE = 1 ALIVE_COLOR = (r.randint(0, 255), r.randint(0, 255), r.randint(0, 255)) def generate_rand_game_board(): board = [] for rows in range(HEIGHT): x_coordinates = [] for cols in range(WIDTH): x_coordinates.append(r.randint(0, 1)) board.append(x_coordinates) return board def get_neighbors(x, y): for rowNumber in range(y-1, y+2): if 0 <= rowNumber < HEIGHT: for colNumber in range(x-1, x+2): if 0 <= colNumber < WIDTH: if not (y == rowNumber and x == colNumber): yield game_board[rowNumber][colNumber] if __name__ == "__main__": argument_parser = argparse.ArgumentParser(description="Game of Life bml generator") argument_parser.add_argument('-o', dest="output_path", type=str, help="output file (mandatory)") argument_parser.add_argument('-w', dest="world", type=list, default=None, help="pre-constructed world (optional)") argument_parser.add_argument('-t', dest="secs", type=int, default=90, help="time in seconds (optional)") argument_parser.add_argument('-d', dest="delay", type=int, default=300, help="delay between frames (optional)") args = argument_parser.parse_args() frames = int(math.floor(args.secs * 1000 / args.delay)) dimension = frame.FrameDimension(WIDTH, HEIGHT, COLOR_DEPTH, COLORS) game_of_life_animation = animation.Animation(dimension) if args.output_path is None: argument_parser.print_help() exit() if args.world is None: game_board = generate_rand_game_board() else: game_board = ast.literal_eval(args.world) if len(game_board) != HEIGHT: print("len(gameBoard) != " + str(HEIGHT) + ". counted " + str(len(game_board))) exit() for i in game_board: if len(i) != WIDTH: print("len(rows) != "+str(WIDTH)+". counted "+str(len(i))) exit() for frame in range(frames): # construct frame new_frame = animation.AnimationFrame(dimension, args.delay) for row_index in range(HEIGHT): for col_index in range(WIDTH): cell_status = game_board[row_index][col_index] if cell_status == ALIVE: new_frame.setPixel(col_index, row_index, ALIVE_COLOR) else: new_frame.setPixel(col_index, row_index, DEAD_COLOR) game_of_life_animation.addFrame(new_frame) # calculate next step next_game_board_step = [] previous_game_board_step = game_board for row_index in range(HEIGHT): new_row = [] for col_index in range(WIDTH): neighbor_list = list(get_neighbors(col_index, row_index)) alive_neighbors = neighbor_list.count(1) if alive_neighbors < 2: new_row.append(DEAD) elif alive_neighbors == 2: new_row.append(game_board[row_index][col_index]) elif alive_neighbors == 3: new_row.append(ALIVE) elif alive_neighbors >= 4: new_row.append(DEAD) next_game_board_step.append(new_row) game_board = next_game_board_step if game_board == previous_game_board_step: for i in range(20): game_of_life_animation.addFrame(new_frame) break blup.writebml.writeBml(game_of_life_animation, args.output_path)