patternpythonMinor
Simple console snake game in Python
Viewed 0 times
simplesnakegamepythonconsole
Problem
Here's a simple snake game I implemented in Python, which works in a console. It's not complete yet (doesn't generate food yet, and no scoring or difficulty levels), but it works. I would be really grateful if you give me any suggestions on how I can improve my code. Note that I did some of the things I did in a really complicated manner, just to learn new tricks, like the needlessly complicated binary manipulations, but suggestions would be helpful anyway.
All kinds of suggestions would be welcome, but what I really want to know right now, would be how I should accept user input. Should I use threads? If so, how should I implement it? Or should I just poll for input in a
```
import math
import time
import msvcrt
import ctypes
import random
from ctypes import wintypes
####### ## # ## # ## #######
# # # # # # # ## #
# # # # # # # ## #
####### # # # ######## #### #####
# # # # # # # ## #
# # ## # # # ## #
####### # # # # # ## #######
#----------------------*#
# A simple command line snake game in Python. #
#----------------------*#
########################################################
########################################################
DUMP = False
class GameState:
field_width = None
field_height = None
field_state = []
snake_length = 0
snake_head = [0, 0]
# dir codes for movement
# up
# 8
#
# left 4 6 right
#
# 2
# down
head_dir = 4
game_lost = False
snakebody = []
defaults = {}
map = None
def initialize(settings):
# Initialize functions
try:
for prop in settings:
if not callable(getattr(GameState, prop)):
All kinds of suggestions would be welcome, but what I really want to know right now, would be how I should accept user input. Should I use threads? If so, how should I implement it? Or should I just poll for input in a
for loop?```
import math
import time
import msvcrt
import ctypes
import random
from ctypes import wintypes
####### ## # ## # ## #######
# # # # # # # ## #
# # # # # # # ## #
####### # # # ######## #### #####
# # # # # # # ## #
# # ## # # # ## #
####### # # # # # ## #######
#----------------------*#
# A simple command line snake game in Python. #
#----------------------*#
########################################################
########################################################
DUMP = False
class GameState:
field_width = None
field_height = None
field_state = []
snake_length = 0
snake_head = [0, 0]
# dir codes for movement
# up
# 8
#
# left 4 6 right
#
# 2
# down
head_dir = 4
game_lost = False
snakebody = []
defaults = {}
map = None
def initialize(settings):
# Initialize functions
try:
for prop in settings:
if not callable(getattr(GameState, prop)):
Solution
Refactoring
The
The first thing we need to do is add a "magic method" named
It was a little hard to tell which variables should be included in the parameters, so I took an educated guess.
This isn't all though, next, we need to initialize the class attributes, and set them to the values of the parameters. Our
Now that we've done this, all of the
Now that you've done this, you should be able to just create a new instance of
Defining a main function
Right now, you just have a top-level
You may think that this isn't very important, but it does do some important things, namely preventing
Style
To start off, it's worth mentioning that Python, unlike many other languages, comes with an official style guide, PEP8. It might be worth your time to take a quick peek at that whenever you have a chance.
To start off, some of your naming is incorrect. Names in Python should follow the following conventions:
Secondly, in Python, there's no sort of value alignment, like you've done here:
And here:
There is no need to align the values with extra spaces.
There should also be two blank lines between top-level code/function/class definitions, like this:
And not like this:
Finally, please indent code contained in
And not like this:
It helps clear up readability a lot. If you're just using the
GameStateThe
GameState class feels a little odd to me. Is there a reason why it's a static class? This class would be much more useful if you could instantiate it and create multiple, varying GameStates, rather than changing the static variables contained inside the static GameState class.The first thing we need to do is add a "magic method" named
__init__. This "magic method" is called whenever an instance of the specified class is created, in essence, the constructor. This means that'd you'd define an __init__ method that looks something like this:It was a little hard to tell which variables should be included in the parameters, so I took an educated guess.
class GameState:
def __init__(self, field_width, field_height, field_state, snake_length, snake_head, head_dir):
...
...This isn't all though, next, we need to initialize the class attributes, and set them to the values of the parameters. Our
__init__ method now becomes this:class GameState:
def __init__(self, field_width, field_height, field_state, snake_length, snake_head, head_dir):
self.field_width = field_width
self.field_height = field_height
self.field_state = field_state
self.snake_length = snake_length
self.snake_head = snake_head
self.head_dir = head_dir
...
...Now that we've done this, all of the
GameState. prefixes in your GameState classmethods should be prefixed with self. instead.Now that you've done this, you should be able to just create a new instance of
GameState for each individual game, like this:current_game_state = GameState( ... )Defining a main function
Right now, you just have a top-level
while loop that runs your code. No main function, and no if __name__ == "__main__" guards. The best thing to do would be to define a main function, and the run it underneath a guard, like this:if __name__ == "__main__":
main()You may think that this isn't very important, but it does do some important things, namely preventing
main from running if your file is imported, rather than run directly. You can see more on this subject matter here.Style
To start off, it's worth mentioning that Python, unlike many other languages, comes with an official style guide, PEP8. It might be worth your time to take a quick peek at that whenever you have a chance.
To start off, some of your naming is incorrect. Names in Python should follow the following conventions:
- Variables should be in
snake_case.
- Constants should be in
UPPER_SNAKE_CASE.
- Function names should be in
snake_case.
- Class names should be in
PascalCase.
Secondly, in Python, there's no sort of value alignment, like you've done here:
'field_width' : 75,
'field_height' : 20,
'snake_length' : 10,
'head_dir' : 4,
'snake_head' : [75//2, 20//2]And here:
WIN32 = ctypes.WinDLL("kernel32")
stdout = WIN32.GetStdHandle(-11)There is no need to align the values with extra spaces.
There should also be two blank lines between top-level code/function/class definitions, like this:
class Spam:
...
def eggs():
...And not like this:
class Spam:
...
def eggs():
...Finally, please indent code contained in
if/while/def/etc. blocks like this:if spam:
eggsAnd not like this:
if spam: eggsIt helps clear up readability a lot. If you're just using the
if statement to assign a new value to a variable as well, you can just use a ternary, like this:spam = eggs if foo else barCode Snippets
class GameState:
def __init__(self, field_width, field_height, field_state, snake_length, snake_head, head_dir):
...
...class GameState:
def __init__(self, field_width, field_height, field_state, snake_length, snake_head, head_dir):
self.field_width = field_width
self.field_height = field_height
self.field_state = field_state
self.snake_length = snake_length
self.snake_head = snake_head
self.head_dir = head_dir
...
...current_game_state = GameState( ... )if __name__ == "__main__":
main()'field_width' : 75,
'field_height' : 20,
'snake_length' : 10,
'head_dir' : 4,
'snake_head' : [75//2, 20//2]Context
StackExchange Code Review Q#104524, answer score: 4
Revisions (0)
No revisions yet.