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
127
128
129
130
131
|
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'
for y in (2, 8):
for x in (5, 15, 25):
map_[y][x] = '+'
game = robots.Game(map_)
game.add_bot(bot, 'Alice')
game.add_bot(bot, 'Bob')
game.add_bot(bot, 'Charlie')
viewer = robots.CursesViewer(game)
viewer.run()
|