-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsnake.py
More file actions
executable file
·106 lines (91 loc) · 3.3 KB
/
snake.py
File metadata and controls
executable file
·106 lines (91 loc) · 3.3 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
import os
import json
import math
import random
from http.server import HTTPServer, BaseHTTPRequestHandler
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
handle_get_meta_data(self)
def do_POST(self):
if self.path == '/start':
handle_start(self)
elif self.path == '/move':
handle_move(self)
elif self.path == '/end':
handle_end(self)
def handle_get_meta_data(request_handler):
content = json.dumps({
'apiversion': '1',
'author': 'robvanderleek',
'version': '1.0',
'color': '#3776ab',
'head': 'safe',
'tail': 'sharp'
})
request_handler.send_response(200)
request_handler.end_headers()
request_handler.wfile.write(content.encode('utf-8'))
def handle_start(request_handler):
body = get_body(request_handler)
game_id = body['game']['id']
print(f'Game started: {game_id}');
request_handler.send_response(200)
request_handler.end_headers()
def handle_end(request_handler):
request_handler.send_response(201)
request_handler.end_headers()
def get_body(request_handler):
content_length = int(request_handler.headers['Content-Length'])
post_data = request_handler.rfile.read(content_length)
return json.loads(post_data.decode('utf-8'))
def handle_move(request_handler):
body = get_body(request_handler)
turn = body['turn']
print(f'Turn: {turn}')
board = body['board']
snake = body['you']
direction = get_direction(board, snake)
request_handler.send_response(200)
request_handler.end_headers()
request_handler.wfile.write(f'{{"move": "{direction}"}}'.encode('utf-8'))
def get_direction(board, snake):
head = snake['head']
directions = preferred_directions(board, head)
return select_direction(board, head, directions)
def preferred_directions(board, head):
food = nearest_food(head, board['food'])
result = []
if head['x'] != food['x']:
result.append('right' if head['x'] < food['x'] else 'left')
if head['y'] != food['y']:
result.append('up' if head['y'] < food['y'] else 'down')
for d in ['right', 'down', 'left', 'up']:
if not d in result:
result.append(d)
return result
def nearest_food(head, food):
food.sort(key=lambda f: distance(head, f))
return food[0]
def distance(p1, p2):
return math.sqrt(pow(p2['x'] - p1['x'], 2) + pow(p2['y'] - p1['y'], 2))
def select_direction(board, head, directions):
for d in directions:
if d == 'left' and free_cell(board, head['x'] - 1, head['y']):
return 'left'
if d == 'right' and free_cell(board, head['x'] + 1, head['y']):
return 'right'
if d == 'down' and free_cell(board, head['x'], head['y'] - 1):
return 'down'
if d == 'up' and free_cell(board, head['x'], head['y'] + 1):
return 'up'
else:
return random.choice(['left', 'right', 'down', 'up'])
def free_cell(board, x, y):
for s in board['snakes']:
if {'x': x, 'y': y} in s['body']:
return False
return x >= 0 and y >= 0 and x < board['width'] and y < board['height']
PORT=int(os.getenv('PORT', 3000))
print(f'Starting Battlesnake server on port: {PORT}')
server = HTTPServer(('0.0.0.0', PORT), RequestHandler)
server.serve_forever()