You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

88 lines
2.5 KiB

#!/usr/bin/env python3
import random
import sys
from PIL import Image
def find_valid_rules(valid_one_count):
valid_rules = []
for rule in range(256):
one_count = 0
for bit_number in range(8):
if rule & (1 << bit_number):
one_count += 1
if one_count == valid_one_count:
valid_rules.append(rule)
return valid_rules
def do_step(state, metarule):
new_state = [()]*len(state)
for i in range(-1, len(state) - 1):
value = (state[i - 1][0] << 2) | (state[i][0] << 1) | state[i + 1][0]
rule_left = state[i - 1][1]
rule_center = state[i][1]
rule_right = state[i + 1][1]
new_bit_left = bool(rule_left & (1 << value))
new_bit_center = bool(rule_center & (1 << value))
new_bit_right = bool(rule_right & (1 << value))
new_bit = ((new_bit_left + new_bit_center + new_bit_right) >= 2)
matches_left = (new_bit == new_bit_left)
matches_center = (new_bit == new_bit_center)
matches_right = (new_bit == new_bit_right)
metavalue = (matches_left << 2) | (matches_center << 1) | matches_right
xor_left = bool(metarule & (1 << (metavalue + 2)))
xor_center = bool(metarule & (1 << (metavalue + 1)))
xor_right = bool(metarule & (1 << metavalue))
new_rule = ((rule_left if xor_left else 0)
^ (rule_center if xor_center else 0)
^ (rule_right if xor_right else 0))
new_state[i] = (new_bit, new_rule)
return new_state
def to_color(bit, rule):
upper = bit << 7
lower_r = (rule & (0b111 << 5)) >> 1
lower_g = (rule & (0b111 << 2)) << 2
lower_b = (rule & 0b11) << 5
return (upper | lower_r, upper | lower_g, upper | lower_b)
def paint_row(im, row, state):
print(state)
for x in range(im.size[0]):
im.putpixel((x, row), to_color(*(state[x])))
def main():
if len(sys.argv) > 1:
metarule = int(sys.argv[1])
else:
metarule = random.randrange(2**24)
print(metarule)
valid_rules = list(range(256))#find_valid_rules(4)
state = []
w = 768//2
if len(sys.argv) > 2:
h = int(sys.argv[2])
else:
h = w
for x in range(w):
state.append((random.randrange(2), random.choice(valid_rules)))
im = Image.new('RGB', (w, h))
paint_row(im, 0, state)
for y in range(1, h):
state = do_step(state, metarule)
paint_row(im, y, state)
im.resize((w*2, h*2), Image.NEAREST).save('rulecontest.png')
if __name__ == '__main__':
main()