-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtime_spirals.py
More file actions
102 lines (80 loc) · 2.85 KB
/
Copy pathtime_spirals.py
File metadata and controls
102 lines (80 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python3
"""Time Spirals -- Program 4 from "Marvel Super Heroes Computer Fun, Book One".
Faithful recreation of the type-in BASIC listing: a turtle draws an expanding
square spiral from screen center, erases it, then redraws it forever in random
characters. Cursor-addressed (no scrolling). Runs until you interrupt with
Ctrl-C -- "interrupt the program when you feel you've traveled enough."
python time_spirals.py
"""
import math
import os
import random
import sys
import time
# 900-Line setup (Commodore 64 profile) + line 970: BC=33, CS=95
SW, SH = 40, 24
BC, CS = 33, 95
CELLS_PER_FRAME = 8
FRAME_DELAY = 0.03
GREEN = "\033[32m"
RESET = "\033[0m"
CLEAR = "\033[2J\033[H"
def enable_ansi():
if os.name == "nt":
os.system("")
def build_path():
"""Turtle path from lines 140-310: a fixed (VT,HT) sequence. PW ends at 1
each pass (SH-2 even), so the path repeats and the space-erase aligns."""
path = []
XO, YO = SW // 2, SH // 2 # line 140
PW = 1 # line 130
for I in range(1, SH - 1): # line 150: FOR I=1 TO SH-2
PW = -1 if PW == 1 else 1 # lines 160-170
P2 = -PW # line 180
XN = XO - I * PW # line 190
PX = XO
while (PX <= XN) if P2 > 0 else (PX >= XN): # 200-230
path.append((YO, PX))
PX += P2
XO = XN # line 240
YN = YO - I * PW # line 250
PY = YO
while (PY <= YN) if P2 > 0 else (PY >= YN): # 260-290
path.append((PY, XO))
PY += P2
YO = YN # line 300
return path
def glyph(code):
return chr(code) if 33 <= code <= 126 else "#"
def random_char(): # lines 930 + 340
rd = random.randint(1, CS)
return glyph(rd + BC)
def next_char(prev): # lines 320-340
return " " if prev != " " else random_char()
def plot(vt, ht, ch): # GOSUB 910 + PRINT CH$
if 1 <= vt <= SH and 1 <= ht <= SW:
sys.stdout.write("\033[%d;%dH%s" % (vt, ht, ch))
def play(passes=None, delay=FRAME_DELAY):
enable_ansi()
path = build_path()
sys.stdout.write(CLEAR + GREEN)
ch = "*"
done = 0
try:
while passes is None or done < passes:
for n, (vt, ht) in enumerate(path): # one full pass (lines 150-310)
plot(vt, ht, ch)
if n % CELLS_PER_FRAME == 0:
sys.stdout.flush()
time.sleep(delay)
sys.stdout.flush()
ch = next_char(ch) # lines 320-340
done += 1
except KeyboardInterrupt:
pass
sys.stdout.write("\033[%d;1H" % SH + RESET + "\n")
sys.stdout.flush()
def main():
play()
if __name__ == "__main__":
main()