Files
2024-08-19 03:46:27 +03:00

170 lines
4.0 KiB
Python

"""
LIFE
An implementation of John Conway's popular cellular automaton
Ported by Dave LeCompte
"""
from typing import Dict
PAGE_WIDTH = 64
MAX_WIDTH = 70
MAX_HEIGHT = 24
def print_centered(msg) -> None:
spaces = " " * ((PAGE_WIDTH - len(msg)) // 2)
print(spaces + msg)
def print_header(title) -> None:
print_centered(title)
print_centered("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print()
print()
print()
def get_pattern() -> Dict[int, str]:
print("ENTER YOUR PATTERN:")
c = 0
pattern: Dict[int, str] = {}
while True:
line = input()
if line == "DONE":
return pattern
# BASIC input would strip of leading whitespace.
# Python input does not. The following allows you to start a
# line with a dot to disable the whitespace stripping. This is
# unnecessary for Python, but for historical accuracy, it's
# staying in.
if line[0] == ".":
line = f" {line[1:]}"
pattern[c] = line
c += 1
def main() -> None:
print_header("LIFE")
pattern = get_pattern()
pattern_height = len(pattern)
pattern_width = 0
for _line_num, line in pattern.items():
pattern_width = max(pattern_width, len(line))
min_x = 11 - pattern_height // 2
min_y = 33 - pattern_width // 2
max_x = MAX_HEIGHT - 1
max_y = MAX_WIDTH - 1
a = [[0 for _ in range(MAX_WIDTH)] for _ in range(MAX_HEIGHT)]
p = 0
g = 0
invalid = False
# line 140
# transcribe the input pattern into the active array
for x in range(0, pattern_height):
for y in range(0, len(pattern[x])):
if pattern[x][y] != " ":
a[min_x + x][min_y + y] = 1
p += 1
print()
print()
print()
while True:
inv_str = "INVALID!" if invalid else ""
print(f"GENERATION: {g}\tPOPULATION: {p} {inv_str}")
next_min_x = MAX_HEIGHT - 1
next_min_y = MAX_WIDTH - 1
next_max_x = 0
next_max_y = 0
p = 0
g += 1
for _ in range(min_x):
print()
for x in range(min_x, max_x + 1):
print()
line_list = [" "] * MAX_WIDTH
for y in range(min_y, max_y + 1):
if a[x][y] == 2:
a[x][y] = 0
continue
elif a[x][y] == 3:
a[x][y] = 1
elif a[x][y] != 1:
continue
line_list[y] = "*"
next_min_x = min(x, next_min_x)
next_max_x = max(x, next_max_x)
next_min_y = min(y, next_min_y)
next_max_y = max(y, next_max_y)
print("".join(line_list))
# line 295
for _ in range(max_x + 1, MAX_HEIGHT):
print()
print()
min_x = next_min_x
max_x = next_max_x
min_y = next_min_y
max_y = next_max_y
if min_x < 3:
min_x = 3
invalid = True
if max_x > 22:
max_x = 22
invalid = True
if min_y < 3:
min_y = 3
invalid = True
if max_y > 68:
max_y = 68
invalid = True
# line 309
p = 0
for x in range(min_x - 1, max_x + 2):
for y in range(min_y - 1, max_y + 2):
count = 0
for i in range(x - 1, x + 2):
for j in range(y - 1, y + 2):
if a[i][j] in [1, 2]:
count += 1
if a[x][y] == 0:
if count == 3:
a[x][y] = 3
p += 1
elif (count < 3) or (count > 4):
a[x][y] = 2
else:
p += 1
# line 635
min_x = min_x - 1
min_y = min_y - 1
max_x = max_x + 1
max_y = max_y + 1
if __name__ == "__main__":
main()