From f8a9f2b824f0fbbb1e1e9d4a58659a513c8bbe78 Mon Sep 17 00:00:00 2001 From: Peter Ward Date: Sat, 22 Feb 2014 22:44:10 +1100 Subject: various improvements --- simple.py | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 6 deletions(-) (limited to 'simple.py') diff --git a/simple.py b/simple.py index 1acdd99..78d4a7c 100644 --- a/simple.py +++ b/simple.py @@ -1,17 +1,122 @@ +from collections import defaultdict + import random import robots +iter_board = robots.utils.iter_board +DIRECTIONS = robots.game.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 + + 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, players, board): my_robots = players[whoami]['robots'] - action = random.choice('URP') - return action * len(my_robots) + return ''.join( + random.choice('ULDRPP') + for _ in range(len(my_robots)) + ) if __name__ == '__main__': - random.seed(64) - map_ = robots.empty_map(10, 10, 4) +# random.seed(42) + map_ = robots.border_map(30, 10, 4) + game = robots.Game(map_) - game.add_bot(bot, 'Alice') + game.add_bot(attacker, 'Alice') + game.add_bot(attacker, 'Adam') + game.add_bot(bot, 'Barry') game.add_bot(bot, 'Bob') - game.add_bot(bot, 'Charlie') viewer = robots.CursesViewer(game) viewer.run() -- cgit v1.2.3