From 9acf1ee8064b6c7bbf5446085eac769effb0df13 Mon Sep 17 00:00:00 2001
From: Peter Ward <peteraward@gmail.com>
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