Skip to content

Commit d077e67

Browse files
committed
Add options for disappearing apple
1 parent c3d74e9 commit d077e67

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

snakeng/__main__.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,25 @@ def main():
6262
' saved to the specified filename when you quit with Ctrl-C.')
6363
parser.add_argument('-i', '--input-file', default=None, type=str, help='If set, the game state will be'
6464
' loaded from the specified filename.')
65+
parser.add_argument('-p', '--permanent-apples', default=False, action='store_true', help='If True, apples '
66+
'will stay forever until collected. Default is to disappear after a fixed number of '
67+
'frames.')
68+
parser.add_argument('-a', '--apple-ticks', default=None, type=int, help='Specifies the number of frames '
69+
'before an uncollected apple disappears. Can only be used if -p is not set. Default is '
70+
'to use the width or height of the game area, whichever is larger.')
6571
args = parser.parse_args()
6672

73+
if args.permanent_apples and (args.apple_ticks is not None):
74+
print("Error: -a/--apple-ticks can not be used if -p/--permanent-apples is set")
75+
return
76+
6777
speed = None
6878
if args.fixed_speed is not None:
6979
args_speed = args.fixed_speed.lower()
7080
speed = speedmap.get(args_speed)
7181

72-
game = SnakeGame(width=args.width, height=args.height, fixed_speed=speed, wall_wrap=not args.wall_death)
82+
game = SnakeGame(width=args.width, height=args.height, fixed_speed=speed, wall_wrap=not args.wall_death,
83+
apples_disappear=not args.permanent_apples, apple_disappear_ticks=args.apple_ticks)
7384

7485
if args.input_file is not None:
7586
with open(args.input_file, 'r') as fh:

snakeng/snake.py

+33-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
MEDIUM_SCORE_THRESHOLD = 25
88
FAST_SCORE_THRESHOLD = 70
99

10-
1110
class Direction(object):
1211
"""
1312
Enumerates all possible directions
@@ -185,6 +184,10 @@ class SnakeGameState(object):
185184
:ivar apple_position: Position object representing the current position of \
186185
the apple, or None if there is no apple.
187186
:ivar bool dead: True if the snake has died
187+
:ivar bool apples_disappear: If True, apples will disappear after a fixed period \
188+
of time if not collected. If False, apples will stay forever until collected.
189+
:ivar int apple_disappear_ticks: specifies number of frames before apple disappears. \
190+
If set to None, a sane default will be used.
188191
"""
189192
area_width: int = 120
190193
area_height: int = 120
@@ -195,7 +198,8 @@ class SnakeGameState(object):
195198
score: int = 0
196199
apple_position: Position = None
197200
dead: bool = False
198-
201+
apples_disappear: bool = True
202+
apple_disappear_ticks: int = None
199203

200204
def serialize(self):
201205
"""
@@ -212,7 +216,9 @@ def serialize(self):
212216
'score': self.score,
213217
'apple_position': self.apple_position.serialize(),
214218
'snake_speed': self.snake_speed,
215-
'fixed_speed': self.fixed_speed
219+
'fixed_speed': self.fixed_speed,
220+
'apples_disappear': self.apples_disappear,
221+
'apple_disappear_ticks': self.apple_disappear_ticks
216222
}
217223

218224
def deserialize(self, attrs):
@@ -229,6 +235,8 @@ def deserialize(self, attrs):
229235
self.apple_position = Position().deserialize(attrs['apple_position'])
230236
self.snake_speed = attrs['snake_speed']
231237
self.fixed_speed = attrs['fixed_speed']
238+
self.apples_disappear = attrs['apples_disappear']
239+
self.apple_disappear_ticks = attrs['apple_disappear_ticks']
232240
return self
233241

234242
def to_string(self, frame_corner_char='+', frame_horiz_char='-', frame_vert_char='|',
@@ -310,7 +318,7 @@ class SnakeGame(object):
310318
Represents a single instance of a snake game
311319
"""
312320
def __init__(self, width=40, height=30, wall_wrap=True, initial_direction=Direction.DOWN,
313-
fixed_speed=None):
321+
fixed_speed=None, apples_disappear=True, apple_disappear_ticks=None):
314322
"""
315323
:param int width: Game area width, in units of snake body segments
316324
:param int height: Game area height, in units of snake body segments
@@ -322,10 +330,15 @@ def __init__(self, width=40, height=30, wall_wrap=True, initial_direction=Direct
322330
the snake size increases. If set to one of the values defined under the Speed \
323331
class, then the snake speed will be set to the specified speed for the duration of \
324332
the game, with no speed increases.
333+
:param bool apples_disappear: If True, apples will disappear after a fixed period \
334+
of time if not collected. If False, apples will stay forever until collected.
335+
:param int apple_disappear_ticks: specifies number of frames before apple disappears. \
336+
If set to None, a sane default will be used.
325337
"""
326338
head_pos = Position(x=int(width / 2), y=int(height / 2))
327339

328-
self.state = SnakeGameState(area_width=width, area_height=height, snake_direction=initial_direction)
340+
self.state = SnakeGameState(area_width=width, area_height=height, snake_direction=initial_direction,
341+
apples_disappear=apples_disappear)
329342
self.state.snake_segments.append(head_pos)
330343

331344
self.state.apple_position = self._new_apple_position()
@@ -336,6 +349,13 @@ def __init__(self, width=40, height=30, wall_wrap=True, initial_direction=Direct
336349
self.table = [[0 for _ in range(width)] for _ in range(height)]
337350
self.table[head_pos.y][head_pos.x] = 1
338351

352+
if apple_disappear_ticks is None:
353+
self.state.apple_disappear_ticks = max(width, height)
354+
else:
355+
self.state.apple_disappear_ticks = apple_disappear_ticks
356+
357+
self.apple_ticks = 0
358+
339359
if fixed_speed is not None:
340360
self.state.fixed_speed = True
341361
self.state.snake_speed = fixed_speed
@@ -458,11 +478,19 @@ def process(self, direction_input=None):
458478
# Check if hit apple, delete apple and increment score if so
459479
if new_head == self.state.apple_position:
460480
self.state.apple_position = self._new_apple_position()
481+
self.apple_ticks = 0
461482
self.state.score += 1
462483
else:
463484
tail = self.state.snake_segments.pop(0)
464485
self.table[tail.y][tail.x] = 0
465486

487+
if self.state.apples_disappear:
488+
if self.apple_ticks >= self.state.apple_disappear_ticks:
489+
self.state.apple_position = self._new_apple_position()
490+
self.apple_ticks = 0
491+
492+
self.apple_ticks += 1
493+
466494
# Check if we crossed a score threshold
467495
if not self.state.fixed_speed:
468496
if self.state.snake_speed == Speed.SLOW:

0 commit comments

Comments
 (0)