summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--robots/game.py59
-rw-r--r--simple.py5
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()