-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDucklings.py
More file actions
200 lines (162 loc) · 6.12 KB
/
Ducklings.py
File metadata and controls
200 lines (162 loc) · 6.12 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import random, shutil, sys, time
from enum import Enum
# constants:
Pause = 0.2 #(!) Try changing this to 1.0 or 0.0
Density = 0.10 # (!)Try changin this to anything from 0.0 to 1.0
DUCKLING_WIDTH = 5
LEFT ='left'
RIGHT = 'right'
BEADY = 'beady'
WIDE = 'wide'
HAPPY = 'happy'
ALOOF = 'aloof'
CHUBBY = 'chubby'
VERY_CHUBBY = 'very chubby'
OPEN = 'open'
CLOSED = 'closed'
OUT = 'out'
DOWN = 'down'
UP = 'up'
HEAD = 'head'
BODY = 'body'
FEET = 'feet'
# find terminal window size:
WIDTH = max(shutil.get_terminal_size()[0] - 1, DUCKLING_WIDTH * 2)
def main():
print('Duckling Screensaver')
print('Press Ctrl-C to quit...')
time.sleep(2)
ducklingLanes = [None] * (WIDTH // DUCKLING_WIDTH)
while True: # Main program loop.
for laneNum in range(len(ducklingLanes)): # Loop through indices directly
if ducklingLanes[laneNum] is None and random.random() <= Density:
ducklingLanes[laneNum] = Duckling() # Now the list entry is updated correctly
if ducklingLanes[laneNum] is not None:
print(ducklingLanes[laneNum].getNextBodyPart(), end='')
if ducklingLanes[laneNum].partToDisplayNext is None:
ducklingLanes[laneNum] = None
else:
print(' ' * DUCKLING_WIDTH, end='')
print() # Print a newline.
sys.stdout.flush() # Make sure text appears on the screen
time.sleep(Pause)
class Duckling:
def __init__(self):
"""Create a new duckling with random body features."""
self.direction = random.choice([LEFT, RIGHT])
self.body = random.choice([CHUBBY, VERY_CHUBBY])
self.mouth = random.choice([OPEN,CLOSED])
self.wing = random.choice([OUT, UP, DOWN])
if self.body == CHUBBY:
# chubby ducklings only have beady eyes
self.eyes = BEADY
else:
self.eyes = random.choice([BEADY, WIDE, HAPPY, ALOOF])
self.partToDisplayNext = HEAD
def getHeadStr(self):
"""Returns the string of the duckling's head."""
headStr = ''
if self.direction == LEFT:
# Get the mouth:
if self.mouth == OPEN:
headStr += '>'
elif self.mouth == CLOSED:
headStr += '='
# eyes:
if self.eyes == BEADY and self.body == CHUBBY:
headStr += '"'
elif self.eyes == BEADY and self.body == VERY_CHUBBY:
headStr += '" '
elif self.eyes == WIDE:
headStr += "''"
elif self.eyes == HAPPY:
headStr += '^^'
elif self.eyes == ALOOF:
headStr += '``'
headStr += ')' # Get the back of the head.
if self.direction == RIGHT:
headStr += '(' # Get the back of the head
# Get the eyes:
if self.eyes == BEADY and self.body == CHUBBY:
headStr += '"'
elif self.eyes == BEADY and self.body == VERY_CHUBBY:
headStr += ' "'
elif self.eyes == WIDE:
headStr += "''"
elif self.eyes == HAPPY:
headStr += '^^'
elif self.eyes == ALOOF:
headStr += '``'
# Get mouth:
if self.mouth == OPEN:
headStr += '<'
elif self.mouth == CLOSED:
headStr += '='
if self.body == CHUBBY:
# Get extra space so chubby ducklings are the
# width as very chubby ducklings.
headStr += ' '
return headStr.ljust(DUCKLING_WIDTH)
def getBodyStr(self):
"""Returns the string of the duckling's body."""
bodyStr = '(' # Get the left side of the body.
if self.direction == LEFT:
# Get the interior body space:
if self.body == CHUBBY:
bodyStr += ' '
elif self.body == VERY_CHUBBY:
bodyStr += ' '
# get wing:
if self.wing == OUT:
bodyStr += '>'
elif self.wing == UP:
bodyStr += '^'
elif self.wing == DOWN:
bodyStr += 'v'
if self.direction == RIGHT:
# Get the wing:
if self.wing == OUT:
bodyStr += '<'
elif self.wing == UP:
bodyStr += '^'
elif self.wing == DOWN:
bodyStr += 'v'
# Get the interior body space:
if self.body == CHUBBY:
bodyStr += ' '
elif self.body == VERY_CHUBBY:
bodyStr += ' '
bodyStr += ')' # Get the right side of the body.
if self.body == CHUBBY:
# get an extra space so chubby ducklings are the same
# width as very chubby ducklings.
bodyStr += ' '
return bodyStr.ljust(DUCKLING_WIDTH)
def getFeetStr(self):
"""Returns the string of the duckling's feet."""
if self.body == CHUBBY:
feetStr = ' ^^ '
elif self.body == VERY_CHUBBY:
feetStr= ' ^ ^ '
else:
feetStr = ' ^^ '
return feetStr.ljust(DUCKLING_WIDTH)
def getNextBodyPart(self):
"""Calls the appropriate display method for the next body
part that needs to be displayed. Sets partToDisplayNext
to None when finished. """
if self.partToDisplayNext == HEAD:
self.partToDisplayNext = BODY
return self.getHeadStr()
elif self.partToDisplayNext == BODY:
self.partToDisplayNext = FEET
return self.getBodyStr()
elif self.partToDisplayNext == FEET:
self.partToDisplayNext = None
return self.getFeetStr()
# If this program was run (instead of imported), run the game:
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
sys.exit() # When Ctrl-c is pressed, end the program.