I've been working on a two player snake game in python. I would really appreciate any suggestions/general input that would help improve my coding.
"""
5-13-2018
Nathan van 't Hof
2 player snake game
players can move around using wasd (player 1) and ijkl (player 2)
eating apples: - will increase players length
"""
import random
import keyboard
import os
import colorama
import time
def get_apple(width, height, snake1, snake2):
"""
find new random coordinate to place the apple
"""
if len(snake1) + len(snake2) >= width*height:
u = raw_input('You win!')
quit()
while True:
apple = [random.randint(0, width - 1), random.randint(0, height-1)]
if apple not in snake1 and apple not in snake2:
return apple
def draw(game_field, i, key):
"""
change a specific coordinate of the game field
to a different type
"""
game_field[i[0]][i[1]] = key
return game_field
def move_snake(game_field, snake, typ):
"""
move the snake one step
"""
game_field = draw(game_field, snake[-2], typ)
game_field = draw(game_field, snake[-1], 'O')
return game_field
def change_pos(prev, width, height, dx, dy):
"""
change the coordinate of the head of the snake
"""
return [(prev[0]+dx)%width, (prev[1]+dy)%height]
def print_game(game_field):
"""
print the game (in a readable format)
"""
output = '.' * ((len(game_field)) * 2 + 1) + '\n'
for i in game_field:
output += '.' + ' '.join(i) + '.' + '\n'
output += '.' * ((len(game_field)) * 2 + 1)
# moves the marker to the top to prevent flikkering
print('\033[H' + output)
def check_die(snake1, snake2):
"""
check whether the snakes 'die'
by letting the head bump into a tail/other head
"""
dead = False
if snake1[-1] == snake2[-1]:
u = raw_input('Both snakes died')
dead = True
elif snake1[-1] in snake2 or snake1.count(snake1[-1]) >= 2:
u = raw_input('Snake 1 died')
dead = True
elif snake2[-1] in snake1 or snake2.count(snake2[-1]) >= 2:
u = raw_input('Snake 2 died')
dead = True
if dead:
quit()
def check_movement(dx, dy, ch1, ch2, ch3, ch4):
"""
check where the snake moves
"""
if keyboard.is_pressed(ch1) and dx != -1 and dy != 0:
return -1, 0
if keyboard.is_pressed(ch2) and dx != 0 and dy != -1:
return 0, -1
if keyboard.is_pressed(ch3) and dx != 1 and dy != 0:
return 1, 0
if keyboard.is_pressed(ch4) and dx != 0 and dy != 1:
return 0,1
return dx, dy
def update_snake(new_pos, apple, game_field, snake1, snake2):
snake1.append(new_pos)
if new_pos == apple:
apple = get_apple(width, height, snake1, snake2)
game_field = draw(game_field, apple, '-')
else:
game_field = draw(game_field, snake1[0], ' ')
del snake1[0]
return snake1, apple, game_field
# init
width, height = 20, 20
snake1 = [[0,0],[0,1]]
snake2 = [[width/2, 0], [width/2 + 1, 0]]
apple = get_apple(width, height, snake1, snake2)
dx1, dy1 = 0, 1
dx2, dy2 = 0, 1
os.system('cls' if os.name == 'nt' else 'clear')
# this allows '\033[H' to work
colorama.init()
# draw inital positions of the field
game_field = [height*[' '] for i in range(width)]
for i in snake1:
game_field = draw(game_field, i, 'x')
for i in snake2:
game_field = draw(game_field, i, '+')
game_field = draw(game_field, snake1[-1], 'O')
game_field = draw(game_field, snake2[-1], 'O')
game_field = draw(game_field, apple, '-')
prev_time = time.time()
while True:
try:
fps = float(input('What framerate would you like to run at?'))
break
except:
print('Please input a number')
os.system('cls' if os.name == 'nt' else 'clear')
while True:
# check inputs from players
dx1, dy1 = check_movement(dx1, dy1, 'w', 'a', 's', 'd')
dx2, dy2 = check_movement(dx2, dy2, 'i', 'j', 'k', 'l')
# update screen if enough time has passed
if time.time() - prev_time > 1./fps:
prev_time = time.time()
print_game(game_field)
new_pos1 = change_pos(snake1[-1], width, height, dx1, dy1)
new_pos2 = change_pos(snake2[-1], width, height, dx2, dy2)
# update snakes and playing field
check_die(snake1, snake2)
snake1, apple, game_field = update_snake(new_pos1, apple, game_field, snake1, snake2)
snake2, apple, game_field = update_snake(new_pos2, apple, game_field, snake2, snake1)
game_field = move_snake(game_field, snake1, 'x')
game_field = move_snake(game_field, snake2, '+')