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
|
#!/usr/bin/env python3
from math import inf, atan2, degrees
from random import randrange
from socket import socket
AROUND = [5, 2, 1, 0, 3, 6, 7, 8]
def get_moves(y, x):
"""Return tuple of encoded moves."""
return ((y - 1, x - 1), (y - 1, x), (y - 1, x + 1),
(y, x - 1), (y, x), (y, x + 1),
(y + 1, x - 1), (y + 1, x), (y + 1, x + 1))
def is_wall(maze, y, x):
"""Return weather the cell (x, y) is wall."""
return maze[y][x] != '0'
clientsocket = socket()
clientsocket.connect(('localhost', 8089))
corners, sides = [0, 2, 6, 8], [1, 3, 5, 7]
around, move = [0, 1, 2, 3, 5, 6, 7, 8], 4
while True:
length = clientsocket.recv(7).decode()
if length in ('', '0000000'): break # connection closed or game over
data = iter(clientsocket.recv(int(length)).decode().split())
nh, ne, nb, score = (int(next(data)) for _ in range(4))
maze = [list(next(data)) for _ in range(nh)]
hp = (lambda c: 0 if c == 48 else 123 - c)(ord(next(data)))
hx, hy, ha = (int(next(data)) for _ in range(3))
attackable, heal = (bool(int(next(data))) for _ in range(2))
if nh:
moves = get_moves(len(maze) // 2, len(maze[0]) // 2)
if move == 4 or is_wall(maze, *moves[move]):
try:
idx = AROUND.index(move)
except ValueError:
pass
else:
around.sort(key=(lambda i: (lambda x: min(x, 8 - x))(
abs(AROUND.index(i) - idx))))
for move in around:
idx = AROUND.index(move)
if all(map(
(lambda i: not is_wall(maze, *moves[i])),
(move, AROUND[idx - 1], AROUND[idx - 7]))):
break
else:
move = 4
angle, shortest = ha, inf
for _ in range(ne):
p = 3 - (ord(next(data)) - 97)%3
x, y, a = (int(next(data)) for _ in range(3))
d = ((x - hx)**2 + (y - hy)**2)**0.5
if d < shortest:
shortest = d
b = degrees(atan2(y - hy, x - hx))
angle = round(b + 360 if b < 0 else b)
if hp <= 2 and heal:
move, attack = 4, 2
elif not ne:
attack = randrange(3) * (attackable and hp > 2)
elif shortest < 160:
move, angle, attack = AROUND[round(angle/45 - 0.5) - 4], ha, 2
else:
attack = 1
clientsocket.send('{} {} {}'.format(move, angle, attack).encode())
clientsocket.close()
|