mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-08 05:40:54 -08:00
170 lines
4.0 KiB
Python
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()
|