From 9acf1ee8064b6c7bbf5446085eac769effb0df13 Mon Sep 17 00:00:00 2001 From: Peter Ward Date: Thu, 10 Apr 2014 20:11:12 +1000 Subject: split out bots into separate files --- capturer.py | 69 +++++++++++++++++++++++++++++++++ simple.py | 126 +++++------------------------------------------------------- 2 files changed, 79 insertions(+), 116 deletions(-) create mode 100644 capturer.py diff --git a/capturer.py b/capturer.py new file mode 100644 index 0000000..a6bb990 --- /dev/null +++ b/capturer.py @@ -0,0 +1,69 @@ +import random + +import robots + +from robots.algorithms import distance_relaxer +from robots.constants import City +from robots.utils import add_spawns + +class CaptureSpawns(object): + def __init__(self, variance=0.1): + self.distances = None + self.iterations = 10 + self.variance = variance + + def __call__(self, whoami, state): + my_robots = state.robots_by_player[whoami] + + self.distances = [ + [ + { + City.NORMAL: ( + float('inf') +# if self.distances is None or self.distances[y][x] is None +# else self.distances[y][x] + self.iterations // 2 + ), + City.FACTORY: ( + 0 + if state.allegiances.get((x, y)) != whoami else + float('inf') + ), + City.GHOST: None, + }[city] + for x, city in enumerate(row) + ] + for y, row in enumerate(state.cities) + ] + + predecessors = distance_relaxer(self.distances, None) + + results = [] + for x, y, energy in my_robots: + if random.random() < self.variance: + result = random.choice('ULDR') + elif predecessors[y][x]: + result = predecessors[y][x] + elif state.allegiances.get((x, y)) != whoami: + result = 'P' + else: + result = random.choice('UDLR') + results.append(result) + return results + +if __name__ == '__main__': +# random.seed(42) + map_ = robots.border_map(40, 30, 0) + + add_spawns(map_, 300, 'X') + add_spawns(map_, 20, '+') + + for y in range(20): + map_[y][20] = 'X' + + add_spawns(map_, 6) + + game = robots.Game(map_) + game.add_bot(CaptureSpawns(variance=0), 'Alice') + game.add_bot(CaptureSpawns(variance=0.01), 'Bob') + viewer = robots.CursesViewer(game) + viewer.run() diff --git a/simple.py b/simple.py index 45f63fa..2876948 100644 --- a/simple.py +++ b/simple.py @@ -1,131 +1,25 @@ -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)) - ) +import robots +from robots.utils import add_spawns -def bot(whoami, state): +def random_walk(whoami, state): my_robots = state.robots_by_player[whoami] return ''.join( - random.choice('ULDRP-') + 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' + map_ = robots.border_map(20, 10, 0) - for y in (2, 8): - for x in (5, 15, 25): - map_[y][x] = '+' + add_spawns(map_, 10, 'X') + add_spawns(map_, 20, '+') + add_spawns(map_, 4) game = robots.Game(map_) - game.add_bot(bot, 'Alice') - game.add_bot(bot, 'Bob') - game.add_bot(bot, 'Charlie') + game.add_bot(random_walk, 'Alice') + game.add_bot(random_walk, 'Bob') viewer = robots.CursesViewer(game) viewer.run() -- cgit v1.2.3