def on_configure(self, server, msg): attrutil.pprint(msg) if self.game_info is None: self.game_info = lookup.by_name(msg.game) self.sm = self.game_info.get_sm() else: if self.game_info.game != msg.game: log.critical("Game changed to %s" % msg.game) sys.exit(1) self.self_play_conf = msg.self_play_conf self.latest_generation_name = msg.generation_name # refresh the neural network. May have to run some commands to get it. self.nn = None while self.nn is None: try: self.nn = get_manager().load_network(self.game_info.game, self.latest_generation_name) except Exception as exc: log.error("error in on_configure(): %s" % exc) for l in traceback.format_exc().splitlines(): log.error(l) time.sleep(1.0) self.configure_self_play() return msgs.Ok("configured")
def gameserver_timeout(self): log.critical("Timeout from server - forcing aborting") if self.current_match: self.current_match.do_abort() self.current_match = None self.timeout_deferred = None
def remove_broker_client(self, worker): if worker not in self.workers: log.critical("worker removed, but not in workers %s" % worker) self.workers[worker].cleanup() if self.workers[worker] == self.the_nn_trainer: self.the_nn_trainer = None self.training_in_progress = False del self.workers[worker]
def abort(self): assert self.current_match is not None try: res = self.current_match.do_abort() except Exception as exc: log.critical("CRITICAL ERROR - during abort: %s" % exc) log.critical(traceback.format_exc()) # always set it none self.current_match = None # and cancel any timeouts self.update_gameserver_timeout(None)
def do_play(self, move): enter_time = time.time() if self.verbose: log.debug("do_play: %s" % (move, )) if move is not None: self.apply_move(move) current_state = self.get_current_state() if self.verbose: current_str = self.game_info.model.basestate_to_str(current_state) log.info("Current state : '%s'" % current_str) self.sm.update_bases(current_state) if self.sm.is_terminal(): return "done" end_time = enter_time + self.move_time if self.cushion_time > 0: end_time -= self.cushion_time legal_choice = self.player.on_next_move(end_time) # we have no idea what on_next_move() left the state machine. So reverting it back to # correct state here. self.sm.update_bases(self.get_current_state()) # get possible possible legal moves and check 'move' is a valid ls = self.sm.get_legal_state(self.our_role_index) # store last move (in our own mapping, *not* gamemaster) self.last_played_move = self.sm.legal_to_move(self.our_role_index, legal_choice) # check the move remaps and is a legal choice move = self.legal_to_gamemaster_move(legal_choice) legal_moves = [ self.legal_to_gamemaster_move(ls.get_legal(ii)) for ii in range(ls.get_count()) ] if move not in legal_moves: msg = "Choice was %s not in legal choices %s" % (move, legal_moves) log.critical(msg) raise CriticalError(msg) if self.verbose: log.info("(%s) do_play '%s' sending move: %s" % (self.player.name, self.role, move)) return move
def apply_move(self, moves): self.game_depth += 1 if self.verbose: log.debug("apply moves: %s" % (moves, )) # we give the player an one time opportunity to return debug/extra information # about the move it just played self.move_info.append(self.player.before_apply_info()) # get the previous state - incase our statemachine is out of sync self.sm.update_bases(self.get_current_state()) # fish tediously for move in available legals our_move = None preserve_move = [] for role_index, gamemaster_move in enumerate(moves): move = gamemaster_move # map the gamemaster move if self.gdl_symbol_mapping: for k, v in self.gdl_symbol_mapping.items(): move = replace_symbols(move, k, v) if self.verbose: log.debug("remapped move from '%s' -> '%s'" % (gamemaster_move, move)) preserve_move.append(move) # find the move found = False ls = self.sm.get_legal_state(role_index) choices = [ls.get_legal(ii) for ii in range(ls.get_count())] for choice in choices: choice_move = self.sm.legal_to_move(role_index, choice) if choice_move == str(move): found = True if role_index == self.our_role_index: our_move = choice_move self.joint_move.set(role_index, choice) break assert found, move assert our_move is not None # check that our move was the same. May be a timeout or ther gamemaster due to bad # network. In these cases, we force an abort (locally) to the game.. if self.last_played_move is not None: if self.last_played_move != our_move: # all we do is log, and continue. Really messed up though. msg = "Gamemaster sent back a different move from played move %s != %s" % ( self.last_played_move, our_move) log.critical(msg) raise CriticalError(msg) new_base_state = self.sm.new_base_state() self.sm.next_state(self.joint_move, new_base_state) self.sm.update_bases(new_base_state) # save for next time / prospserity self.moves.append(preserve_move) self.states.append(new_base_state) # in case player needs to cleanup some state self.player.on_apply_move(self.joint_move)
def critical_error(msg): log.critical(msg) reactor.stop() sys.exit(1)