Python Forum

Full Version: Rule 110 Automata
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
"""
Rule 110 Automata
-----------------
Rules:
current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0
"""
import pygame
from random import choice


def main():
    # Patterns in a dictionary of key "current pattern" and value "new cell"
    patterns = {'###': ' ', '## ': '#', '# #': '#', '#  ': ' ',
                ' ##': '#', ' # ': '#', '  #': '#', '   ': ' '}

    automata_columns = 800
    automata_rows = 600

    pygame.init()
    pygame.display.set_caption('Rule 110')

    screen = pygame.display.set_mode((automata_columns, automata_rows))
    screen.fill(pygame.Color("black"))
    colour = pygame.Color("cyan")

    # Helper function, "screen" and "colour" are in scope because this
    # function is nested
    def peek_pixel(x, y):
        if screen.get_at((x, y)) == colour:
            return "#"
        else:
            return " "

    # inital pattern
    for x in range(automata_columns):
        if choice('# ') == '#':
            screen.set_at((x, 0), colour)

    # do automata
    for y in range(1, automata_rows - 2):
        for x in range(1, automata_columns - 1):
            if (
                patterns[
                    peek_pixel(x - 1, y - 1) +
                    peek_pixel(x, y - 1) +
                    peek_pixel(x + 1, y - 1)
                ] == "#"
            ):
                screen.set_at((x, y), colour)
        pygame.display.update()

    # wait until window is closed
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                done = True

if __name__ == '__main__':
    main()
This is something I wrote to practice Python. If generates a graphical Rule 110 automata.

[Image: IkKOIUS.png]

Sample run above.

I programmed decades ago as a hobby and am looking to pick Python up now also as a hobby.
I believe this would allow you to run it for any pattern:

def generate_pattern(pattern_id):
    pattern = {}
    for power, neighborhood in enumerate(('   |  #| # | ##|#  |# #|## |###'.split('|'))):
        pattern[neighborhood] = 1 if 2 ** power & pattern_id else 0
    return pattern
Oooh, thank you! Big Grin See, signing up here is already a great decision! Cool