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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
from collections import defaultdict
import random
import robots
from robots.constants import DIRECTIONS
def shuffled(items):
items = list(items)
random.shuffle(items)
return items
def get_enemy_robots(me, players):
robots = {}
for name, info in players.items():
if name != me:
for x, y in info['robots']:
robots[x, y] = name
return robots
def paths_to_enemies(enemies, board, iterations=None):
width = len(board[0])
height = len(board)
if iterations is None:
iterations = 10
iterations = width * height
distances = []
for y in range(height):
distances.append([])
for x in range(width):
if (x, y) in enemies:
value = (0, None, (x, y))
else:
value = (float('inf'), None, None)
distances[-1].append(value)
DIRECTION_ITEMS = shuffled(DIRECTIONS.items())
for i in range(iterations):
for y in range(height):
for x in range(width):
for move, (dx, dy) in DIRECTION_ITEMS:
nx = (x + dx) % width
ny = (y + dy) % height
if board[ny][nx] == '*':
continue
current_dist = distances[y][x][0]
this_dist, _, dest = distances[ny][nx]
this_dist += 1
if this_dist < current_dist:
distances[y][x] = (this_dist, move, dest)
return distances
def attacker(whoami, players, board):
width = len(board[0])
height = len(board)
my_robots = players[whoami]['robots']
enemies = get_enemy_robots(whoami, players)
paths = paths_to_enemies(enemies, board)
allocations = defaultdict(list)
for x, y in my_robots:
dist, dir, dest = paths[y][x]
allocations[dest].append((dist, dir, (x, y)))
searchers = int(len(my_robots) * 0.7)
assignments = {}
for options in allocations.values():
for dist, dir, robot in sorted(options)[:searchers]:
assignments[robot] = dir
results = []
for x, y in my_robots:
choice = assignments.get((x, y))
if board[y][x] != whoami and (not choice or random.random() < 0.5):
choice = 'P'
elif choice:
pass
else:
moves = []
for dir, (dx, dy) in DIRECTIONS.items():
nx = (x + dx) % width
ny = (y + dy) % height
if board[ny][nx] != '*':
moves.append(dir)
choice = random.choice(moves or '-')
results.append(choice)
return ''.join(results)
def never_paint(whoami, players, board):
my_robots = players[whoami]['robots']
return ''.join(
random.choice('ULD--')
for _ in range(len(my_robots))
)
def bot(whoami, state):
my_robots = state.robots_by_player[whoami]
return ''.join(
random.choice('ULDRP-')
for _ in range(len(my_robots))
)
if __name__ == '__main__':
# random.seed(42)
map_ = robots.border_map(30, 10, 0)
for y in range(8):
map_[y][10] = 'X'
for y in range(11, 2, -1):
map_[y][20] = 'X'
map_[5][5] = '1'
map_[5][15] = '3'
map_[5][25] = '2'
game = robots.Game(map_)
game.add_bot(bot, 'Alice')
game.add_bot(bot, 'Bob')
viewer = robots.CursesViewer(game)
viewer.run()
|