From 4e6255791bc15d45624ee73d9011f2c522e583e3 Mon Sep 17 00:00:00 2001 From: Peter Ward Date: Sat, 22 Feb 2014 20:41:17 +1100 Subject: handle collisions --- robots/game.py | 59 +++++++++++++++++++++++++++++++++++++++++----------------- simple.py | 5 ++--- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/robots/game.py b/robots/game.py index 143f391..8fc507b 100644 --- a/robots/game.py +++ b/robots/game.py @@ -1,5 +1,6 @@ -from copy import deepcopy +from collections import defaultdict from contextlib import contextmanager +from copy import deepcopy from robots.utils import iter_board @@ -56,6 +57,11 @@ class Game: self.board = deepcopy(map_) self._spawns = _extract_spawn_points(self.board) + self._painted_tiles = { + '*': float('inf'), # not used + '.': self.available_tiles, + } + def add_bot(self, bot, name=None): if name is None: name = bot.__name__ @@ -73,6 +79,7 @@ class Game: 'robots': [spawn], 'spawn': spawn, } + self._painted_tiles[name] = 0 @property def width(self): @@ -94,9 +101,7 @@ class Game: def finished(self): return False - def next(self): - all_actions = [] - + def call_bots(self): for whoami, bot in self.bots.items(): try: with protected(self.players, 'players') as players, \ @@ -124,27 +129,47 @@ class Game: else: for bot, action in zip(my_robots, result): - all_actions.append((whoami, bot, action)) + yield whoami, bot, action - new_robots = {} + def apply_actions(self, actions): + new_robots = defaultdict(list) + bot_locations = defaultdict(int) - for whoami, bot, action in all_actions: + for whoami, bot, action in actions: x, y = bot + if action == Actions.PAINT: + previous = self.board[y][x] + self._painted_tiles[previous] -= 1 + self.board[y][x] = whoami - elif action == Actions.NOTHING: - pass - else: + self._painted_tiles[whoami] += 1 + + elif action != Actions.NOTHING: dx, dy = DIRECTIONS[action] - x += dx - y += dy + nx = (x + dx) % self.width + ny = (y + dy) % self.height - x %= self.width - y %= self.height + if self.board[ny][nx] != Squares.WALL: + x = nx + y = ny - if whoami not in new_robots: - new_robots[whoami] = [] new_robots[whoami].append((x, y)) + bot_locations[x, y] += 1 + + to_remove = set( + (x, y) + for (x, y), count in bot_locations.items() + if count > 1 + ) for whoami, info in self.players.items(): - info['robots'][:] = new_robots[whoami] + info['robots'][:] = [ + (x, y) + for x, y in new_robots[whoami] + if (x, y) not in to_remove + ] + + def next(self): + actions = self.call_bots() + self.apply_actions(actions) diff --git a/simple.py b/simple.py index faeb366..1acdd99 100644 --- a/simple.py +++ b/simple.py @@ -3,16 +3,15 @@ import robots def bot(whoami, players, board): my_robots = players[whoami]['robots'] - action = random.choice('UDLRP-') + action = random.choice('URP') return action * len(my_robots) if __name__ == '__main__': random.seed(64) - map_ = robots.empty_map(20, 20, 4) + map_ = robots.empty_map(10, 10, 4) game = robots.Game(map_) game.add_bot(bot, 'Alice') game.add_bot(bot, 'Bob') game.add_bot(bot, 'Charlie') - game.add_bot(bot, 'Doug') viewer = robots.CursesViewer(game) viewer.run() -- cgit v1.2.3