forked from ukoethe/bomberman_rl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
replay.py
102 lines (82 loc) · 3.1 KB
/
replay.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import pickle
from time import sleep
import numpy as np
import settings as s
from agents import Agent
from environment import GenericWorld, WorldArgs
from fallbacks import pygame
from items import Coin
class ReplayWorld(GenericWorld):
def __init__(self, args: WorldArgs):
super().__init__(args)
replay_file = args.replay
self.logger.info(f'Loading replay file "{replay_file}"')
self.replay_file = replay_file
with open(replay_file, 'rb') as f:
self.replay = pickle.load(f)
if not 'n_steps' in self.replay:
self.replay['n_steps'] = s.MAX_STEPS
pygame.display.set_caption(f'{replay_file}')
# Recreate the agents
self.agents = [ReplayAgent(name, self.colors.pop())
for (name, s, b, xy) in self.replay['agents']]
self.new_round()
def new_round(self):
self.logger.info('STARTING REPLAY')
# Bookkeeping
self.step = 0
self.bombs = []
self.explosions = []
self.running = True
self.frame = 0
# Game world and objects
self.arena = np.array(self.replay['arena'])
self.coins = []
for xy in self.replay['coins']:
if self.arena[xy] == 0:
self.coins.append(Coin(xy, True))
else:
self.coins.append(Coin(xy, False))
self.active_agents = [a for a in self.agents]
for i, agent in enumerate(self.agents):
agent.start_round()
agent.x, agent.y = self.replay['agents'][i][-1]
agent.total_score = 0
def poll_and_run_agents(self):
# Perform recorded agent actions
perm = self.replay['permutations'][self.step - 1]
for i in perm:
a = self.active_agents[i]
self.logger.debug(f'Repeating action from agent <{a.name}>')
action = self.replay['actions'][a.name][self.step - 1]
self.logger.info(f'Agent <{a.name}> chose action {action}.')
self.perform_agent_action(a, action)
def time_to_stop(self):
time_to_stop = super().time_to_stop()
if self.step == self.replay['n_steps']:
self.logger.info('Replay ends here, wrap up round')
time_to_stop = True
return time_to_stop
def end_round(self):
super().end_round()
if self.running:
self.running = False
# Wait in case there is still a game step running
sleep(self.args.update_interval)
else:
self.logger.warning('End-of-round requested while no round was running')
self.logger.debug('Setting ready_for_restart_flag')
self.ready_for_restart_flag.set()
class ReplayAgent(Agent):
"""
Agents class firing off a predefined sequence of actions.
"""
def __init__(self, name, color):
"""Recreate the agent as it was at the beginning of the original game."""
super().__init__(color, name, None, False, None)
def setup(self):
pass
def act(self, game_state):
pass
def wait_for_act(self):
return 0, self.actions.popleft()