Skip to content

Commit 644c679

Browse files
committed
Minor updates
1 parent b18ddd0 commit 644c679

File tree

4 files changed

+93
-99
lines changed

4 files changed

+93
-99
lines changed

README.rst

+38-43
Original file line numberDiff line numberDiff line change
@@ -34,32 +34,24 @@ This is the simplest possible implementation of snake, using ``snakeng``:
3434
import sys
3535
import time
3636
import keyboard
37-
from snakeng.snake import SnakeGame, SnakeDirection
37+
from snakeng.snake import SnakeGame, Direction
3838
39-
last_direction = SnakeDirection.DOWN
39+
last_direction = Direction.DOWN
40+
dirmap = {'up': Direction.UP, 'down': Direction.DOWN, 'left': Direction.LEFT, 'right': Direction.RIGHT}
4041
41-
# Callback function to save the last arrow keypress
4242
def keypress_event(e):
4343
global last_direction
44-
if e.name == 'up':
45-
last_direction = SnakeDirection.UP
46-
elif e.name == 'down':
47-
last_direction = SnakeDirection.DOWN
48-
elif e.name == 'left':
49-
last_direction = SnakeDirection.LEFT
50-
elif e.name == 'right':
51-
last_direction = SnakeDirection.RIGHT
44+
new_direction = dirmap.get(e.name, None)
45+
if new_direction is not None:
46+
last_direction = new_direction
5247
53-
# Register callback function
54-
keyboard.on_press(keypress_event)
55-
56-
game = SnakeGame()
48+
keyboard.on_press(keypress_event) # Register callback function to save last keypress
49+
game = SnakeGame() # Create game instance
5750
5851
while True:
59-
new_state = game.process(last_direction) # Produce new frame
60-
sys.stdout.write("\033[2J\n") # Clear terminal screen
61-
sys.stdout.write(new_state.to_string()) # Print new game state
62-
sys.stdout.flush() # Flush output
52+
new_state = game.process(last_direction) # Produce new frame
53+
sys.stdout.write("\033[2J\n" + new_state.to_string()) # Clear terminal screen and print new game state
54+
sys.stdout.flush() # Flush output
6355
time.sleep(0.05)
6456
6557
Sample command-line (ASCII) implementation
@@ -78,30 +70,33 @@ The terminal-based implementation accepts several arguments, detailed here:
7870

7971
::
8072

81-
usage: snakeng [-h] [-x WIDTH] [-y HEIGHT] [-s {slow,medium,fast,faster}]
82-
[-o OUTPUT_FILE] [-i INPUT_FILE] [-f FPS]
83-
84-
Simple terminal-based snake game showing how to use snakeng. Use arrow keys to
85-
change snake direction, use 'p' to pause, and use 'Ctrl-C' to quit.
86-
87-
options:
88-
-h, --help show this help message and exit
89-
-x WIDTH, --width WIDTH
90-
Game area width in characters (default: 40)
91-
-y HEIGHT, --height HEIGHT
92-
Game area height in characters (default: 30)
93-
-s {slow,medium,fast,faster}, --fixed-speed {slow,medium,fast,faster}
94-
Sets the snake speed for the whole game. If unset, the
95-
snake speed will automatically increase as the snake
96-
size increases. (default: None)
97-
-o OUTPUT_FILE, --output-file OUTPUT_FILE
98-
If set, the game state will be saved to the specified
99-
filename when you quit with Ctrl-C (default: None)
100-
-i INPUT_FILE, --input-file INPUT_FILE
101-
If set, the game state will be loaded from the
102-
specified filename (default: None)
103-
-f FPS, --fps FPS Framerate in frames per second (default: 24)
104-
73+
usage: snakeng [-h] [-x WIDTH] [-y HEIGHT] [-f FPS]
74+
[-s {slow,medium,fast,faster}] [-w] [-o OUTPUT_FILE]
75+
[-i INPUT_FILE]
76+
77+
Simple terminal-based snake game showing how to use snakeng. Use arrow keys to
78+
change snake direction, use 'p' to pause, and use 'Ctrl-C' to quit.
79+
80+
options:
81+
-h, --help show this help message and exit
82+
-x WIDTH, --width WIDTH
83+
Game area width in characters. (default: 40)
84+
-y HEIGHT, --height HEIGHT
85+
Game area height in characters. (default: 30)
86+
-f FPS, --fps FPS Framerate in frames per second. (default: 24)
87+
-s {slow,medium,fast,faster}, --fixed-speed {slow,medium,fast,faster}
88+
Sets the snake speed for the whole game. If unset, the
89+
snake speed will automatically increase as the snake
90+
size increases. (default: None)
91+
-w, --wall-death If True, snake will die if it hits a wall. Default
92+
behaviour is to "wrap around" and come out of the
93+
opposite wall. (default: False)
94+
-o OUTPUT_FILE, --output-file OUTPUT_FILE
95+
If set, the game state will be saved to the specified
96+
filename when you quit with Ctrl-C. (default: None)
97+
-i INPUT_FILE, --input-file INPUT_FILE
98+
If set, the game state will be loaded from the
99+
specified filename. (default: None)
105100

106101
NOTE: the sample implementation uses an ANSI escape sequence to clear the terminal screen,
107102
so it won't work in terminals that don't support ANSI escape sequences.

examples/readme_example.py

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
import sys
22
import time
33
import keyboard
4-
from snakeng.snake import SnakeGame, SnakeDirection
4+
from snakeng.snake import SnakeGame, Direction
55

6-
last_direction = SnakeDirection.DOWN
6+
# Holds the last direction input received
7+
last_direction = Direction.DOWN
8+
9+
# Maps key names from 'keyboard' lib to snakeng.Direction values
10+
dirmap = {'up': Direction.UP, 'down': Direction.DOWN, 'left': Direction.LEFT, 'right': Direction.RIGHT}
711

812
# Callback function to save the last arrow keypress
913
def keypress_event(e):
1014
global last_direction
11-
if e.name == 'up':
12-
last_direction = SnakeDirection.UP
13-
elif e.name == 'down':
14-
last_direction = SnakeDirection.DOWN
15-
elif e.name == 'left':
16-
last_direction = SnakeDirection.LEFT
17-
elif e.name == 'right':
18-
last_direction = SnakeDirection.RIGHT
15+
new_direction = dirmap.get(e.name, None)
16+
if new_direction is not None:
17+
last_direction = new_direction
1918

2019
# Register callback function
2120
keyboard.on_press(keypress_event)
2221

22+
# Create game instance
2323
game = SnakeGame()
2424

2525
while True:
26-
new_state = game.process(last_direction) # Produce new frame
27-
new_state_string = new_state.to_string()
28-
sys.stdout.write("\033[2J\n" + new_state_string) # Clear terminal screen and print new game state
29-
sys.stdout.flush() # Flush output
26+
new_state = game.process(last_direction) # Produce new frame
27+
sys.stdout.write("\033[2J\n" + new_state.to_string()) # Clear terminal screen and print new game state
28+
sys.stdout.flush() # Flush output
3029
time.sleep(0.05)

snakeng/__main__.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import keyboard
99

10-
from snakeng.snake import SnakeGame, SnakeSpeed, SnakeDirection
10+
from snakeng.snake import SnakeGame, Speed, Direction
1111

1212
scheduler = sched.scheduler(time.time, time.sleep)
1313

@@ -22,13 +22,13 @@ def keypress_event(e):
2222
ret = None
2323

2424
if e.name == 'up':
25-
ret = SnakeDirection.UP
25+
ret = Direction.UP
2626
elif e.name == 'down':
27-
ret = SnakeDirection.DOWN
27+
ret = Direction.DOWN
2828
elif e.name == 'left':
29-
ret = SnakeDirection.LEFT
29+
ret = Direction.LEFT
3030
elif e.name == 'right':
31-
ret = SnakeDirection.RIGHT
31+
ret = Direction.RIGHT
3232
elif e.name == 'p':
3333
runtime_data['paused'] = not runtime_data['paused']
3434

@@ -74,13 +74,13 @@ def main():
7474
if args.fixed_speed is not None:
7575
args_speed = args.fixed_speed.lower()
7676
if args_speed == 'slow':
77-
speed = SnakeSpeed.SLOW
77+
speed = Speed.SLOW
7878
elif args_speed == 'medium':
79-
speed = SnakeSpeed.MEDIUM
79+
speed = Speed.MEDIUM
8080
elif args_speed == 'fast':
81-
speed = SnakeSpeed.FAST
81+
speed = Speed.FAST
8282
elif args_speed == 'faster':
83-
speed = SnakeSpeed.FASTER
83+
speed = Speed.FASTER
8484

8585
game = SnakeGame(width=args.width, height=args.height, fixed_speed=speed, wall_wrap=not args.wall_death)
8686

snakeng/snake.py

+33-33
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
FAST_SCORE_THRESHOLD = 70
99

1010

11-
class SnakeDirection(object):
11+
class Direction(object):
1212
"""
1313
Enumerates all possible directions
1414
@@ -23,7 +23,7 @@ class SnakeDirection(object):
2323
DOWN = 3
2424

2525

26-
class SnakeSpeed(object):
26+
class Speed(object):
2727
"""
2828
Enumerates all possible movement speeds for the snake
2929
@@ -39,10 +39,10 @@ class SnakeSpeed(object):
3939

4040

4141
_MOVEMAP = {
42-
SnakeDirection.LEFT: (-1, 0),
43-
SnakeDirection.RIGHT: (1, 0),
44-
SnakeDirection.UP: (0, 1),
45-
SnakeDirection.DOWN: (0, -1)
42+
Direction.LEFT: (-1, 0),
43+
Direction.RIGHT: (1, 0),
44+
Direction.UP: (0, 1),
45+
Direction.DOWN: (0, -1)
4646
}
4747

4848

@@ -82,9 +82,9 @@ class SnakeGameState(object):
8282
:ivar list snake_segments: List of Position objects representing the current \
8383
position of each segment of the snake
8484
:ivar int snake_direction: Current movement direction of the snake, one of \
85-
the constants defined by the SnakeDirection class
85+
the constants defined by the Direction class
8686
:ivar int snake_speed: Current movement speed of the snake, one of \
87-
the constants defined by the SnakeSpeed class
87+
the constants defined by the Speed class
8888
:ivar fixed_speed: If True, snake speed does not change relative to snake size
8989
:ivar int score: Number of apples the snake has collected
9090
:ivar apple_position: Position object representing the current position of \
@@ -94,8 +94,8 @@ class SnakeGameState(object):
9494
area_width: int = 120
9595
area_height: int = 120
9696
snake_segments: List = field(default_factory=lambda: [])
97-
snake_direction: int = SnakeDirection.UP
98-
snake_speed: int = SnakeSpeed.SLOW
97+
snake_direction: int = Direction.UP
98+
snake_speed: int = Speed.SLOW
9999
fixed_speed: bool = False
100100
score: int = 0
101101
apple_position: Position = None
@@ -183,13 +183,13 @@ def to_string(self, frame_corner_char='+', frame_horiz_char='-', frame_vert_char
183183
table[pos.y][pos.x] = snake_body_char
184184

185185
snake_head_char = '#'
186-
if self.snake_direction == SnakeDirection.UP:
186+
if self.snake_direction == Direction.UP:
187187
snake_head_char = snake_head_up_char
188-
elif self.snake_direction == SnakeDirection.DOWN:
188+
elif self.snake_direction == Direction.DOWN:
189189
snake_head_char = snake_head_down_char
190-
elif self.snake_direction == SnakeDirection.LEFT:
190+
elif self.snake_direction == Direction.LEFT:
191191
snake_head_char = snake_head_left_char
192-
elif self.snake_direction == SnakeDirection.RIGHT:
192+
elif self.snake_direction == Direction.RIGHT:
193193
snake_head_char = snake_head_right_char
194194

195195
snakehead = self.snake_segments[-1]
@@ -214,17 +214,17 @@ class SnakeGame(object):
214214
"""
215215
Represents a single instance of a snake game
216216
"""
217-
def __init__(self, width=40, height=30, wall_wrap=True, initial_direction=SnakeDirection.DOWN,
217+
def __init__(self, width=40, height=30, wall_wrap=True, initial_direction=Direction.DOWN,
218218
fixed_speed=None):
219219
"""
220220
:param int width: Game area width, in units of snake body segments
221221
:param int height: Game area height, in units of snake body segments
222222
:param bool wall_wrap: If True, the snake will die when it hits a wall. If False, \
223223
the snake will 'teleport' through the wall and continue from the opposite wall.
224224
:param int initial_direction: Initial movement direction for the snake. Expected to \
225-
be one of the values defined under the SnakeDirection class.
225+
be one of the values defined under the Direction class.
226226
:param int fixed_speed: If unset, then the snake speed will automatically increase as \
227-
the snake size increases. If set to one of the values defined under the SnakeSpeed \
227+
the snake size increases. If set to one of the values defined under the Speed \
228228
class, then the snake speed will be set to the specified speed for the duration of \
229229
the game, with no speed increases.
230230
"""
@@ -277,13 +277,13 @@ def _new_apple_position(self):
277277
def _wall_collision(self, x, y):
278278
ret = None
279279
if x <= 0:
280-
ret = SnakeDirection.LEFT
280+
ret = Direction.LEFT
281281
elif x >= (self.state.area_width - 1):
282-
ret = SnakeDirection.RIGHT
282+
ret = Direction.RIGHT
283283
elif y <= 0:
284-
ret = SnakeDirection.DOWN
284+
ret = Direction.DOWN
285285
elif y >= (self.state.area_height - 1):
286-
ret = SnakeDirection.UP
286+
ret = Direction.UP
287287

288288
return ret
289289

@@ -309,22 +309,22 @@ def _new_head(self):
309309
self.state.dead = True
310310
else:
311311
# Wrap new snake head position around to the opposite wall
312-
if collision_dir == SnakeDirection.LEFT:
312+
if collision_dir == Direction.LEFT:
313313
newx = self.state.area_width - 2
314-
elif collision_dir == SnakeDirection.RIGHT:
314+
elif collision_dir == Direction.RIGHT:
315315
newx = 1
316-
elif collision_dir == SnakeDirection.UP:
316+
elif collision_dir == Direction.UP:
317317
newy = 1
318-
elif collision_dir == SnakeDirection.DOWN:
318+
elif collision_dir == Direction.DOWN:
319319
newy = self.state.area_height - 2
320320

321321
return Position(x=newx, y=newy)
322322

323323
def _opposite_dirs(self, dir1, dir2):
324324
dirs = [dir1, dir2]
325-
if (SnakeDirection.UP in dirs) and (SnakeDirection.DOWN in dirs):
325+
if (Direction.UP in dirs) and (Direction.DOWN in dirs):
326326
return True
327-
elif (SnakeDirection.LEFT in dirs) and (SnakeDirection.RIGHT in dirs):
327+
elif (Direction.LEFT in dirs) and (Direction.RIGHT in dirs):
328328
return True
329329

330330
return False
@@ -370,14 +370,14 @@ def process(self, direction_input=None):
370370

371371
# Check if we crossed a score threshold
372372
if not self.state.fixed_speed:
373-
if self.state.snake_speed == SnakeSpeed.SLOW:
373+
if self.state.snake_speed == Speed.SLOW:
374374
if self.state.score >= SLOW_SCORE_THRESHOLD:
375-
self.state.snake_speed = SnakeSpeed.MEDIUM
376-
elif self.state.snake_speed == SnakeSpeed.MEDIUM:
375+
self.state.snake_speed = Speed.MEDIUM
376+
elif self.state.snake_speed == Speed.MEDIUM:
377377
if self.state.score >= MEDIUM_SCORE_THRESHOLD:
378-
self.state.snake_speed = SnakeSpeed.FAST
379-
elif self.state.snake_speed == SnakeSpeed.FAST:
378+
self.state.snake_speed = Speed.FAST
379+
elif self.state.snake_speed == Speed.FAST:
380380
if self.state.score >= FAST_SCORE_THRESHOLD:
381-
self.state.snake_speed = SnakeSpeed.FASTER
381+
self.state.snake_speed = Speed.FASTER
382382

383383
return self.state

0 commit comments

Comments
 (0)