def game(self, task, report_status=False): self.post_id += 1 try: matchup_id = int(task["matchup_id"]) log.info("Running game %s..." % matchup_id) options = None if 'game_options' in task: options = task["game_options"] if options == None: options = copy(server_info["game_options"]) options["map"] = self.get_map(task['map_filename']) options["output_json"] = True game = Ants(options) bots = [] for submission_id in task["submissions"]: submission_id = int(submission_id) if self.compile(submission_id, run_test=False): submission_dir = self.submission_dir(submission_id) run_cmd = compiler.get_run_cmd(submission_dir) #run_dir = tempfile.mkdtemp(dir=server_info["compiled_path"]) bot_dir = os.path.join(submission_dir, 'bot') bots.append((bot_dir, run_cmd)) #shutil.copytree(submission_dir, run_dir) else: self.clean_download(submission_id) raise Exception('bot', 'Can not compile bot %s' % submission_id) options['game_id'] = matchup_id log.debug((game.__class__.__name__, task['submissions'], options, matchup_id)) # set worker debug logging if self.debug: options['verbose_log'] = sys.stdout replay_log = open('replay.json', 'w') options['replay_log'] = replay_log #options['stream_log'] = sys.stdout options['error_logs'] = [sys.stderr for _ in range(len(bots))] # options['output_logs'] = [sys.stdout, sys.stdout] # options['input_logs'] = [sys.stdout, sys.stdout] options['capture_errors'] = True result = run_game(game, bots, options) if self.debug: replay_log.close() log.debug(result) if 'game_id' in result: del result['game_id'] result['matchup_id'] = matchup_id result['post_id'] = self.post_id if report_status: return self.cloud.post_result('api_game_result', result) except Exception as ex: log.debug(traceback.format_exc()) result = {"post_id": self.post_id, "matchup_id": matchup_id, "error": str(ex) } success = self.cloud.post_result('api_game_result', result) # cleanup download dirs map(self.clean_download, map(int, task['submissions'])) return success
def functional_test(self, submission_id): self.post_id += 1 log.info("Running functional test for %s" % submission_id) options = copy(server_info["game_options"]) options['strict'] = True # kills bot on invalid inputs options['food'] = 'none' options['turns'] = 30 log.debug(options) options["map"] = self.get_test_map() options['capture_errors'] = True game = Ants(options) if submission_id in self.download_dirs: bot_dir = self.download_dirs[submission_id] else: bot_dir = self.submission_dir(submission_id) bots = [(os.path.join(bot_dir, 'bot'), compiler.get_run_cmd(bot_dir)), (os.path.join(server_info['repo_path'], "ants", "submission_test"), "python TestBot.py")] log.debug(bots) # set worker debug logging if self.debug: options['verbose_log'] = sys.stdout #options['stream_log'] = sys.stdout options['error_logs'] = [sys.stderr, sys.stderr] # options['output_logs'] = [sys.stdout, sys.stdout] # options['input_logs'] = [sys.stdout, sys.stdout] result = run_game(game, bots, options) if 'status' in result: if result['status'][1] in ('crashed', 'timeout', 'invalid'): if type(result['errors'][1]) == unicode: errors_str = uni_to_ascii(result['errors'][1]) else: errors_str = '["' + '","'.join( uni_to_ascii(e) for e in result['errors'][1]) + '"]' msg = 'TestBot is not operational\n' + errors_str log.error(msg) return msg log.info(result['status'][0]) # player 0 is the bot we are testing if result['status'][0] in ('crashed', 'timeout', 'invalid'): if type(result['errors'][1]) == unicode: errors_str = uni_to_ascii(result['errors'][0]) else: errors_str = '["' + '","'.join( uni_to_ascii(e) for e in result['errors'][0]) + '"]' log.info(errors_str) return result['errors'][0] elif 'error' in result: msg = 'Function Test failure: ' + result['error'] log.error(msg) return msg return None
def functional_test(self, submission_id): self.post_id += 1 log.info("Running functional test for %s" % submission_id) options = copy(server_info["game_options"]) options['strict'] = True # kills bot on invalid inputs options['food'] = 'none' options['turns'] = 30 log.debug(options) options["map"] = self.get_test_map() options['capture_errors'] = True game = Ants(options) if submission_id in self.download_dirs: bot_dir = self.download_dirs[submission_id] else: bot_dir = self.submission_dir(submission_id) bots = [(os.path.join(bot_dir, 'bot'), compiler.get_run_cmd(bot_dir)), (os.path.join(server_info['repo_path'],"ants","submission_test"), "python TestBot.py")] log.debug(bots) # set worker debug logging if self.debug: options['verbose_log'] = sys.stdout #options['stream_log'] = sys.stdout options['error_logs'] = [sys.stderr, sys.stderr] # options['output_logs'] = [sys.stdout, sys.stdout] # options['input_logs'] = [sys.stdout, sys.stdout] result = run_game(game, bots, options) if 'status' in result: if result['status'][1] in ('crashed', 'timeout', 'invalid'): if type(result['errors'][1]) == unicode: errors_str = uni_to_ascii(result['errors'][1]) else: errors_str = '["'+ '","'.join(uni_to_ascii(e) for e in result['errors'][1]) + '"]' msg = 'TestBot is not operational\n' + errors_str log.error(msg) return msg log.info(result['status'][0]) # player 0 is the bot we are testing if result['status'][0] in ('crashed', 'timeout', 'invalid'): if type(result['errors'][1]) == unicode: errors_str = uni_to_ascii(result['errors'][0]) else: errors_str = '["'+ '","'.join(uni_to_ascii(e) for e in result['errors'][0]) + '"]' log.info(errors_str) return result['errors'][0] elif 'error' in result: msg = 'Function Test failure: ' + result['error'] log.error(msg) return msg return None
def run_rounds(): # this split of options is not needed, but left for documentation turns = 10 rounds = 1 game_options = { "map": '../../maps/random4.txt', "attack": 'damage', "food": 'sections', "viewradius2": 96, "attackradius2": 5, "spawnradius2": 2, "loadtime": 3000, "turntime": 1000, "turns": rounds, "seed": 42, } engine_options = { "loadtime": 3000, "turntime": 1000, "map_file": '../../maps/random4.txt', "turns": turns, "output_dir": '../../viewer/bro_viewer', "output_json": False, "log_input": False, "log_output": False, "serial": None, "verbose": True, "visualizer": opts.visualizer, } bots_files = ("python ../../dist/sample_bots/python/HunterBot.py", "python ../../dist/sample_bots/python/keth.py", "python ../../bots/bro/bro.py", "python ../../dist/sample_bots/python/HunterBot.py") random.seed(game_options['seed']) for round in range(game_options['turns']): map_file = open(game_options['map'], 'r') game_options["map"] = map_file.read() map_file.close() game = Ants(game_options) bots = [('.', arg) for arg in bots_files] if game.num_players != len(bots): print("Incorrect number of bots for map. Need %s, got %s" % (game.num_players, len(bots))) for arg in args: print("Bot Cmd: %s" % arg) break print('playgame round %s' % round) result = run_game(game, bots, engine_options, round) if engine_options['output_json']: print result
def run_rounds(): # this split of options is not needed, but left for documentation turns = 10 rounds = 1 game_options = { "map": '../../maps/random4.txt', "attack": 'damage', "food": 'sections', "viewradius2": 96, "attackradius2": 5, "spawnradius2": 2, "loadtime": 3000, "turntime": 1000, "turns": rounds, "seed": 42 } engine_options = { "loadtime": 3000, "turntime": 1000, "map_file": '../../maps/random4.txt', "turns": turns, "output_dir": '../../viewer/bro_viewer', "output_json": False, "log_input": False, "log_output": False, "serial": None, "verbose": True } bots_files = ( "python ../../dist/sample_bots/python/HunterBot.py", "python ../../dist/sample_bots/python/keth.py", "python ../../bots/bro/bro.py", "python ../../dist/sample_bots/python/HunterBot.py" ) random.seed(game_options['seed']) for round in range(game_options['turns']): map_file = open(game_options['map'], 'r') game_options["map"] = map_file.read() map_file.close() game = Ants(game_options) bots = [('.', arg) for arg in bots_files] if game.num_players != len(bots): print("Incorrect number of bots for map. Need %s, got %s" % (game.num_players, len(bots))) for arg in args: print("Bot Cmd: %s" % arg) break print('playgame round %s' % round) result = run_game(game, bots, engine_options, round) if engine_options['output_json']: print result
def game(self, task, report_status=False): self.post_id += 1 try: matchup_id = int(task["matchup_id"]) log.info("Running game %s..." % matchup_id) if 'options' in task: options = task["options"] else: options = server_info["game_options"] options["map"] = self.get_map(task['map_filename']) options["output_json"] = True game = Ants(options) bots = [] for submission_id in task["players"]: if self.compile(submission_id): submission_dir = self.submission_dir(submission_id) run_cmd = compiler.get_run_cmd(submission_dir) #run_dir = tempfile.mkdtemp(dir=server_info["submissions_path"]) bots.append((submission_dir, run_cmd)) #shutil.copytree(submission_dir, run_dir) else: raise Exception('bot', 'Can not compile bot %s' % submission_id) output_dir = os.path.join(server_info["root_path"], "games", str(matchup_id)) if not os.path.exists(output_dir): try: os.makedirs(output_dir) except: pass options['output_dir'] = output_dir options['log_input'] = True options['log_output'] = True result = run_game(game, bots, options, matchup_id) result['matchup_id'] = task['matchup_id'] result['post_id'] = self.post_id if report_status: self.cloud.post_result('api_game_result', result) except Exception as ex: import traceback traceback.print_exc() result = { "post_id": self.post_id, "matchup_id": matchup_id, "error": str(ex) } self.cloud.post_result('api_game_result', result)
def functional_test(self, submission_id): self.post_id += 1 try: matchup_id = 0 log.info("Running functional test for %s" % submission_id) options = server_info["game_options"] options["map"] = self.get_test_map() options["output_json"] = True game = Ants(options) submission_dir = self.submission_dir(submission_id) bots = [("../ants/submission_test/", "python TestBot.py"), (submission_dir, compiler.get_run_cmd(submission_dir))] result = run_game(game, bots, options, matchup_id) log.info(result) return True except Exception as ex: log.error(traceback.format_exc()) return False
def run_rounds(opts, args): # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "food": opts.food, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "spawnradius2": opts.spawnradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "turns": opts.turns, "seed": opts.seed } engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "map_file": opts.map, "turns": opts.turns, "output_dir": opts.output_dir, "output_json": opts.output_json, "log_input": opts.log_input, "log_output": opts.log_output, "serial": opts.serial, "verbose": opts.verbose } random.seed(opts.seed) for round in range(opts.rounds): map_file = open(opts.map, 'r') game_options["map"] = map_file.read() map_file.close() game = Ants(game_options) bots = [('.', arg) for arg in args] if game.num_players != len(bots): print("Incorrect number of bots for map. Need %s, got %s" % (game.num_players, len(bots))) for arg in args: print("Bot Cmd: %s" % arg) break print('playgame round %s' % round) result = run_game(game, bots, engine_options, round) if opts.output_json: print result
def run_rounds(opts,args): # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "food": opts.food, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "spawnradius2": opts.spawnradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "turns": opts.turns, "seed": opts.seed } engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "map_file": opts.map, "turns": opts.turns, "output_dir": opts.output_dir, "output_json": opts.output_json, "log_input": opts.log_input, "log_output": opts.log_output, "serial": opts.serial, "verbose": opts.verbose } random.seed(opts.seed) for round in range(opts.rounds): map_file = open(opts.map, 'r') game_options["map"] = map_file.read() map_file.close() game = Ants(game_options) bots = [('.', arg) for arg in args] if game.num_players != len(bots): print("Incorrect number of bots for map. Need %s, got %s" % (game.num_players, len(bots))) for arg in args: print("Bot Cmd: %s" % arg) break print('playgame round %s' % round) result = run_game(game, bots, engine_options, round) if opts.output_json: print result
def run_rounds(opts, args): def get_cmd_wd(cmd): ''' get the proper working directory from a command line ''' new_cmd = [] wd = None for i, part in enumerate(reversed(cmd.split())): if wd == None and os.path.exists(part): wd = os.path.split(os.path.realpath(part))[0] if i == 0: new_cmd.insert(0, os.path.join(".", os.path.basename(part))) else: new_cmd.insert(0, os.path.basename(part)) else: new_cmd.insert(0, part) return wd, ' '.join(new_cmd) def get_cmd_name(cmd): ''' get the name of a bot from the command line ''' for i, part in enumerate(reversed(cmd.split())): if os.path.exists(part): return os.path.basename(part) # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "food": opts.food, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "spawnradius2": opts.spawnradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "turns": opts.turns, "food_rate": opts.food_rate, "food_turn": opts.food_turn, "food_start": opts.food_start, "food_visible": opts.food_visible, "cutoff_turn": opts.cutoff_turn, "cutoff_percent": opts.cutoff_percent } if opts.player_seed != None: game_options['player_seed'] = opts.player_seed if opts.engine_seed != None: game_options['engine_seed'] = opts.engine_seed engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "map_file": opts.map, "turns": opts.turns, "log_replay": opts.log_replay, "log_stream": opts.log_stream, "log_input": opts.log_input, "log_output": opts.log_output, "log_error": opts.log_error, "serial": opts.serial, "strict": opts.strict, "capture_errors": opts.capture_errors, "secure_jail": opts.secure_jail, "end_wait": opts.end_wait } for round in range(opts.rounds): # initialize game game_id = round + opts.game_id with open(opts.map, 'r') as map_file: game_options['map'] = map_file.read() if opts.engine_seed: game_options['engine_seed'] = opts.engine_seed + round game = Ants(game_options) # initialize bots bots = [get_cmd_wd(arg) for arg in args] bot_count = len(bots) # insure correct number of bots, or fill in remaining positions if game.num_players != len(bots): if game.num_players > len(bots) and opts.fill: extra = game.num_players - len(bots) for _ in range(extra): bots.append(bots[-1]) else: print("Incorrect number of bots for map. Need {0}, got {1}". format(game.num_players, len(bots)), file=stderr) for arg in args: print("Bot Cmd: {0}".format(arg), file=stderr) break bot_count = len(bots) # move position of first bot specified if opts.position > 0 and opts.position <= len(bots): first_bot = bots[0] bots = bots[1:] bots.insert(opts.position, first_bot) # initialize file descriptors if opts.log_dir and not os.path.exists(opts.log_dir): os.mkdir(opts.log_dir) if not opts.log_replay and not opts.log_stream and (opts.log_dir or opts.log_stdout): opts.log_replay = True replay_path = None # used for visualizer launch if opts.log_replay: if opts.log_dir: replay_path = os.path.join(opts.log_dir, '{0}.replay'.format(game_id)) engine_options['replay_log'] = open(replay_path, 'w') if opts.log_stdout: if 'replay_log' in engine_options and engine_options[ 'replay_log']: engine_options['replay_log'] = Tee( sys.stdout, engine_options['replay_log']) else: engine_options['replay_log'] = sys.stdout else: engine_options['replay_log'] = None if opts.log_stream: if opts.log_dir: engine_options['stream_log'] = open( os.path.join(opts.log_dir, '{0}.stream'.format(game_id)), 'w') if opts.log_stdout: if engine_options['stream_log']: engine_options['stream_log'] = Tee( sys.stdout, engine_options['stream_log']) else: engine_options['stream_log'] = sys.stdout else: engine_options['stream_log'] = None if opts.log_input and opts.log_dir: engine_options['input_logs'] = [ open( os.path.join(opts.log_dir, '{0}.bot{1}.input'.format(game_id, i)), 'w') for i in range(bot_count) ] else: engine_options['input_logs'] = None if opts.log_output and opts.log_dir: engine_options['output_logs'] = [ open( os.path.join(opts.log_dir, '{0}.bot{1}.output'.format(game_id, i)), 'w') for i in range(bot_count) ] else: engine_options['output_logs'] = None if opts.log_error and opts.log_dir: if opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [ Tee( Comment(stderr), open( os.path.join( opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count) ] else: engine_options['error_logs'] = [ Tee( stderr, open( os.path.join( opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count) ] else: engine_options['error_logs'] = [ open( os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w') for i in range(bot_count) ] elif opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Comment(stderr)] * bot_count else: engine_options['error_logs'] = [stderr] * bot_count else: engine_options['error_logs'] = None if opts.verbose: if opts.log_stdout: engine_options['verbose_log'] = Comment(sys.stdout) else: engine_options['verbose_log'] = sys.stdout engine_options['game_id'] = game_id if opts.rounds > 1: print('# playgame round {0}, game id {1}'.format(round, game_id)) # intercept replay log so we can add player names if opts.log_replay: intcpt_replay_io = StringIO.StringIO() real_replay_io = engine_options['replay_log'] engine_options['replay_log'] = intcpt_replay_io result = run_game(game, bots, engine_options) # add player names, write to proper io, reset back to normal if opts.log_replay: replay_json = json.loads(intcpt_replay_io.getvalue()) replay_json['playernames'] = [get_cmd_name(arg) for arg in args] real_replay_io.write(json.dumps(replay_json)) intcpt_replay_io.close() engine_options['replay_log'] = real_replay_io # close file descriptors if engine_options['stream_log']: engine_options['stream_log'].close() if engine_options['replay_log']: engine_options['replay_log'].close() if engine_options['input_logs']: for input_log in engine_options['input_logs']: input_log.close() if engine_options['output_logs']: for output_log in engine_options['output_logs']: output_log.close() if engine_options['error_logs']: for error_log in engine_options['error_logs']: error_log.close() if replay_path: if opts.nolaunch: if opts.html_file: visualizer.visualize_locally.launch( replay_path, True, opts.html_file) else: if opts.html_file == None: visualizer.visualize_locally.launch( replay_path, generated_path="replay.{0}.html".format(game_id)) else: visualizer.visualize_locally.launch( replay_path, generated_path=opts.html_file)
def run_rounds(opts,args): def get_cmd_wd(cmd, exec_rel_cwd=False): ''' get the proper working directory from a command line ''' new_cmd = [] wd = None for i, part in reversed(list(enumerate(cmd.split()))): if wd == None and os.path.exists(part): wd = os.path.dirname(os.path.realpath(part)) basename = os.path.basename(part) if i == 0: if exec_rel_cwd: new_cmd.insert(0, os.path.join(".", basename)) else: new_cmd.insert(0, part) else: new_cmd.insert(0, basename) else: new_cmd.insert(0, part) return wd, ' '.join(new_cmd) def get_cmd_name(cmd): ''' get the name of a bot from the command line ''' for i, part in enumerate(reversed(cmd.split())): if os.path.exists(part): return os.path.basename(part) # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "sim_steps": opts.sim_steps, "loadtime": opts.loadtime, "turntime": opts.turntime, "turns": opts.turns, "cutoff_turn": opts.cutoff_turn, "cutoff_percent": opts.cutoff_percent, "scenario": opts.scenario } if opts.player_seed != None: game_options['player_seed'] = opts.player_seed if opts.engine_seed != None: game_options['engine_seed'] = opts.engine_seed engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "map_file": opts.map, "turns": opts.turns, "log_replay": opts.log_replay, "log_stream": opts.log_stream, "log_input": opts.log_input, "log_output": opts.log_output, "log_error": opts.log_error, "serial": opts.serial, "strict": opts.strict, "capture_errors": opts.capture_errors, "secure_jail": opts.secure_jail, "end_wait": opts.end_wait } for round in range(opts.rounds): # initialize game game_id = round + opts.game_id if opts.map is not None: with open(opts.map, 'r') as map_file: game_options['map'] = map_file.read() if opts.engine_seed: game_options['engine_seed'] = opts.engine_seed + round game = LifeGame(game_options) # initialize bots bots = [get_cmd_wd(arg, exec_rel_cwd=opts.secure_jail) for arg in args] bot_count = len(bots) # insure correct number of bots, or fill in remaining positions if game.num_players != len(bots): if game.num_players > len(bots) and opts.fill: extra = game.num_players - len(bots) for _ in range(extra): bots.append(bots[-1]) else: print("Incorrect number of bots for map. Need {0}, got {1}" .format(game.num_players, len(bots)), file=stderr) for arg in args: print("Bot Cmd: {0}".format(arg), file=stderr) break bot_count = len(bots) # move position of first bot specified if opts.position > 0 and opts.position <= len(bots): first_bot = bots[0] bots = bots[1:] bots.insert(opts.position, first_bot) # initialize file descriptors if opts.log_dir and not os.path.exists(opts.log_dir): os.mkdir(opts.log_dir) if not opts.log_replay and not opts.log_stream and (opts.log_dir or opts.log_stdout): opts.log_replay = True replay_path = None # used for visualizer launch if opts.log_replay: if opts.log_dir: replay_path = os.path.join(opts.log_dir, '{0}.replay'.format(game_id)) engine_options['replay_log'] = open(replay_path, 'w') if opts.log_stdout: if 'replay_log' in engine_options and engine_options['replay_log']: engine_options['replay_log'] = Tee(sys.stdout, engine_options['replay_log']) else: engine_options['replay_log'] = sys.stdout else: engine_options['replay_log'] = None if opts.log_stream: if opts.log_dir: engine_options['stream_log'] = open(os.path.join(opts.log_dir, '{0}.stream'.format(game_id)), 'w') if opts.log_stdout: if engine_options['stream_log']: engine_options['stream_log'] = Tee(sys.stdout, engine_options['stream_log']) else: engine_options['stream_log'] = sys.stdout else: engine_options['stream_log'] = None if opts.log_input and opts.log_dir: engine_options['input_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.input'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['input_logs'] = None if opts.log_output and opts.log_dir: engine_options['output_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.output'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['output_logs'] = None if opts.log_error and opts.log_dir: if opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Tee(Comment(stderr), open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [Tee(stderr, open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w') for i in range(bot_count)] elif opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Comment(stderr)] * bot_count else: engine_options['error_logs'] = [stderr] * bot_count else: engine_options['error_logs'] = None if opts.verbose: if opts.log_stdout: engine_options['verbose_log'] = Comment(sys.stdout) else: engine_options['verbose_log'] = sys.stdout engine_options['game_id'] = game_id if opts.rounds > 1: print('# playgame round {0}, game id {1}'.format(round, game_id)) # intercept replay log so we can add player names if opts.log_replay: intcpt_replay_io = StringIO() real_replay_io = engine_options['replay_log'] engine_options['replay_log'] = intcpt_replay_io result = run_game(game, bots, engine_options) # add player names, write to proper io, reset back to normal if opts.log_replay: replay_json = json.loads(intcpt_replay_io.getvalue()) replay_json['playernames'] = [get_cmd_name(arg) for arg in args] real_replay_io.write(json.dumps(replay_json)) intcpt_replay_io.close() engine_options['replay_log'] = real_replay_io # close file descriptors if engine_options['stream_log']: engine_options['stream_log'].close() if engine_options['replay_log']: engine_options['replay_log'].close() if engine_options['input_logs']: for input_log in engine_options['input_logs']: input_log.close() if engine_options['output_logs']: for output_log in engine_options['output_logs']: output_log.close() if engine_options['error_logs']: for error_log in engine_options['error_logs']: error_log.close() if replay_path: if opts.html_file == None: visualizer.visualize_locally.launch(replay_path, opts.nolaunch, "replay.{0}.html".format(game_id)) else: visualizer.visualize_locally.launch(replay_path, opts.nolaunch, opts.html_file)
print("bot%2d is %s" % (i, bot['fname'])) print("-" * 80 + '\n') print("DEBUG") print("=====") if not os.path.exists(engine_options["log_dir"]): os.mkdir(engine_options["log_dir"]) if not os.path.exists(engine_options["arena"]): os.mkdir(engine_options["arena"]) if not os.path.exists(engine_options["json_logdir"]): os.mkdir(engine_options["json_logdir"]) engine_options["game_log"] = open( os.path.join(engine_options["log_dir"], "game_log.r%d.log" % 0), 'w') # round 0 result, json_start, json_end, json_mybot_ipstream, json_mybot_invalid, json_mybot_ignored, json_mybot_valid = engine.run_game( game, bot_details, engine_options) # json_replay_list is also ready, # jsonize it json_replay = json.dumps(json_replay_list, separators=(',', ':')) jnotify = json.dumps(json_notifications, separators=(',', ':')) # do more logging if os.path.exists(engine_options["json_logdir"]): json_data_dump = open( os.path.join(engine_options["json_logdir"], "game_replay.js"), 'w') json_data_dump.write( "GAME_START=%s;\nGAME_REPLAY=%s;\nMYBOT_IP_STREAM=%s;\nMYBOT_INV_STREAM=%s;\nMYBOT_IGN_STREAM=%s;\nMYBOT_VAL_STREAM=%s\nGAME_END=%s;\nGAME_NOTIFICATIONS=%s;\n" % (json_start, json_replay, json_mybot_ipstream, json_mybot_invalid, json_mybot_ignored, json_mybot_valid, json_end, jnotify)) json_data_dump.close() print()
def run(self): starttime = time() log.info( "run game %d %s %s" % (self.id,self.map_name,self.players) ) for i,p in enumerate(self.bots): p.write( "INFO: game " + str(self.id) + " " + str(self.map_name) + " : " + str(self.players) + "\n" ) # finally, THE GAME ! game_result = run_game(self.ants, self.bots, self.opts) ## don't need the client threads any more, so we can kill them now for i,b in enumerate(self.bots): del(self.bots[i]) self.bots = None try: states = game_result["status"] except: log.error("broken game %d: %s" % (self.id,game_result) ) return if self.ants.turn < 1: log.error("broken game %d (0 turns)" % (self.id) ) return scores = game_result["score"] ranks = game_result["rank"] # count draws draws = 0 hist = [0]*len(ranks) for r in ranks: hist[r] += 1 for h in hist: if h>0: draws += (h-1) # save replay, add playernames to it game_result['game_id'] = self.id game_result['playernames'] = [] for i,p in enumerate(self.players): game_result['playernames'].append(p) # save to db db = game_db.GameDB() data = json.dumps(game_result) db.add_replay( self.id, data ) plr = {} for i,p in enumerate(self.players): plr[p] = (scores[i], states[i]) db.update("insert into gameindex values(?,?,?)",(None,p,self.id)) db.add_game( self.id, self.map_name, self.ants.turn, draws,json.dumps(plr) ) # update trueskill #~ if sum(ranks) >= len(ranks)-1: if self.opts['trueskill'] == 'jskills': self.calk_ranks_js( self.players, ranks, db ) else : # default self.calc_ranks_py( self.players, ranks, db ) #~ else: #~ log.error( "game "+str(self.id)+" : ranking unsuitable for trueskill " + str(ranks) ) ## this should go out # update rankings for i, p in enumerate(db.retrieve("select name from players order by skill desc",())): db.update_player_rank( p[0], i+1 ) db.con.commit() # dbg display ds = time() - starttime mins = int(ds / 60) secs = ds - mins*60 log.info("saved game %d : %d turns %dm %2.2fs" % (self.id,self.ants.turn,mins,secs) ) log.info("players: %s" % self.players) log.info("ranks : %s %s draws" % (ranks, draws) ) log.info("scores : %s" % scores) log.info("status : %s" % states)
def main(argv): usage = "Usage: %prog [options] map bot1 bot2\n\nYou must specify a map file." parser = OptionParser(usage=usage) # map to be played # number of players is determined by the map file parser.add_option("-m", "--map_file", dest="map", help="Name of the map file") # maximum number of turns that the game will be played parser.add_option("-t", "--turns", dest="turns", default=200, type="int", help="Number of turns in the game") # the output directory will contain the replay file used by the visualizer # it will also contain the bot input/output logs, if requested parser.add_option("-o", "--output_dir", dest="output_dir", help="Directory to dump replay files to.") parser.add_option("-j", "--output_json", dest="output_json", action="store_true", default=False, help="Return json result from engine.") parser.add_option("-I", "--log_input", dest="log_input", action="store_true", default=False, help="Log input streams sent to bots") parser.add_option("-O", "--log_output", dest="log_output", action="store_true", default=False, help="Log output streams from bots") parser.add_option("--serial", dest="serial", action="store_true", help="Run bots in serial, instead of parallel.") parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Print out status as game goes.") parser.add_option("--turntime", dest="turntime", default=1000, type="int", help="Amount of time to give each bot, in milliseconds") parser.add_option("--loadtime", dest="loadtime", default=3000, type="int", help="Amount of time to give for load, in milliseconds") parser.add_option("-r", "--rounds", dest="rounds", default=1, type="int", help="Number of rounds to play") parser.add_option("--seed", dest="seed", default=None, type="int", help="Seed for the random number generator") # ants specific game options parser.add_option( "--attack", dest="attack", default="damage", help= "Attack method to use for engine. (closest, power, support, damage)") parser.add_option( "--food", dest="food", default="sections", help="Food spawning method. (none, random, sections, symmetric)") parser.add_option("--viewradius2", dest="viewradius2", default=96, type="int", help="Vision radius of ants squared") parser.add_option("--spawnradius2", dest="spawnradius2", default=2, type="int", help="Spawn radius of ants squared") parser.add_option("--attackradius2", dest="attackradius2", default=5, type="int", help="Attack radius of ants squared") (opts, args) = parser.parse_args(argv) if opts.map is None or not os.path.exists(opts.map): parser.print_help() return -1 try: # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "food": opts.food, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "spawnradius2": opts.spawnradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "turns": opts.turns, "seed": opts.seed } engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "map_file": opts.map, "turns": opts.turns, "output_dir": opts.output_dir, "output_json": opts.output_json, "log_input": opts.log_input, "log_output": opts.log_output, "serial": opts.serial, "verbose": opts.verbose } random.seed(opts.seed) for round in range(opts.rounds): map_file = open(opts.map, 'r') game_options["map"] = map_file.read() map_file.close() game = Ants(game_options) bots = [('.', arg) for arg in args] if game.num_players != len(bots): print("Incorrect number of bots for map. Need %s, got %s" % (game.num_players, len(bots))) break print('playgame round %s' % round) result = run_game(game, bots, engine_options, round) if opts.output_json: print result except Exception: traceback.print_exc() finally: return 1
def run_rounds(opts,args): def get_bot_paths(cmd, zip_encapsulator): ''' Receives a single file string from the command line and Returns a 3 list of <working_dir> <full_file_path> <file_name> ''' filepath = os.path.realpath(cmd) if filepath.endswith('.zip'): # if we get zip file - override original filepath for abstraction filepath = zip_encapsulator.unzip(filepath) working_dir = os.path.dirname(filepath) bot_name = os.path.basename(cmd).split('.')[0] return working_dir, filepath, bot_name def get_cmd_wd(cmd, exec_rel_cwd=False): ''' get the proper working directory from a command line ''' new_cmd = [] wd = None for i, part in reversed(list(enumerate(cmd.split()))): if wd == None and os.path.exists(part): wd = os.path.dirname(os.path.realpath(part)) basename = os.path.basename(part) if i == 0: if exec_rel_cwd: new_cmd.insert(0, os.path.join(".", basename)) else: new_cmd.insert(0, part) else: new_cmd.insert(0, basename) else: new_cmd.insert(0, part) return wd, ' '.join(new_cmd) def get_cmd_name(cmd): ''' get the name of a bot from the command line ''' for i, part in enumerate(reversed(cmd.split())): # if extra whatever-"-character-called in the line - remove them part = part.replace('"','') if os.path.exists(part): return os.path.basename(part) # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "recover_errors": opts.recover_errors, "turns": opts.turns, "cutoff_turn": opts.cutoff_turn, "cutoff_percent": opts.cutoff_percent, "scenario": opts.scenario, "maxpoints" : opts.maxpoints, "actions_per_turn" : opts.actions_per_turn, "reload_turns" : opts.reload_turns, "defense_reload_turns" : opts.defense_reload_turns, "defense_expiration_turns" : opts.defense_expiration_turns, "treasure_spawn_turns" : opts.treasure_spawn_turns, "spawn_turns" : opts.spawn_turns, "sober_turns" : opts.sober_turns, "ghostcooldown" : opts.ghostcooldown, "fogofwar" : opts.fogofwar } if opts.player_seed != None: game_options['player_seed'] = opts.player_seed if opts.engine_seed != None: game_options['engine_seed'] = opts.engine_seed engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "extratime": opts.extratime, "map_file": opts.map, "turns": opts.turns, "debug_in_replay": opts.debug_in_replay, "debug_max_length": opts.debug_max_length, "debug_max_count": opts.debug_max_count, "log_replay": opts.log_replay, "log_stream": opts.log_stream, "log_input": opts.log_input, "log_output": opts.log_output, "log_error": opts.log_error, "serial": opts.serial, "strict": opts.strict, "capture_errors": opts.capture_errors, "secure_jail": opts.secure_jail, "end_wait": opts.end_wait } for round in range(opts.rounds): # initialize bots zip_encapsulator = ZipEncapsulator() bots = [get_bot_paths(arg, zip_encapsulator) for arg in args] bot_count = len(bots) # initialize game game_id = "{0}.{1}".format(opts.game_id, round) if opts.rounds > 1 else opts.game_id with open(opts.map, 'r') as map_file: game_options['map'] = map_file.read() if opts.engine_seed: game_options['engine_seed'] = opts.engine_seed + round game_options['bot_names'] = map(lambda b: b[2], bots) game = Pirates(game_options) # insure correct number of bots, or fill in remaining positions if game.num_players != len(bots): print("Incorrect number of bots for map. Need {0}, got {1}" .format(game.num_players, len(bots)), file=stderr) # initialize file descriptors if opts.log_dir and not os.path.exists(opts.log_dir): os.mkdir(opts.log_dir) if not opts.log_replay and not opts.log_stream and (opts.log_dir or opts.log_stdout): opts.log_replay = True replay_path = None # used for visualizer launch if opts.log_replay: if opts.log_dir: replay_path = os.path.join(opts.log_dir, '{0}.replay'.format(game_id)) engine_options['replay_log'] = open(replay_path, 'w') if opts.log_stdout: if 'replay_log' in engine_options and engine_options['replay_log']: engine_options['replay_log'] = Tee(sys.stdout, engine_options['replay_log']) else: engine_options['replay_log'] = sys.stdout else: engine_options['replay_log'] = None if opts.log_stream: if opts.log_dir: engine_options['stream_log'] = open(os.path.join(opts.log_dir, '{0}.stream'.format(game_id)), 'w') if opts.log_stdout: if engine_options['stream_log']: engine_options['stream_log'] = Tee(sys.stdout, engine_options['stream_log']) else: engine_options['stream_log'] = sys.stdout else: engine_options['stream_log'] = None if opts.log_input and opts.log_dir: engine_options['input_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.input'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['input_logs'] = None if opts.log_output and opts.log_dir: engine_options['output_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.output'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['output_logs'] = None if opts.log_error and opts.log_dir: if opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Tee(Comment(stderr), open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [Tee(stderr, open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w') for i in range(bot_count)] elif opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Comment(stderr)] * bot_count else: engine_options['error_logs'] = [stderr] * bot_count else: engine_options['error_logs'] = None if opts.verbose: if opts.log_stdout: engine_options['verbose_log'] = Comment(sys.stdout) else: engine_options['verbose_log'] = sys.stdout if opts.debug: engine_options['debug_log'] = sys.stdout engine_options['game_id'] = game_id if opts.rounds > 1: print('# playgame round {0}, game id {1}'.format(round, game_id)) # intercept replay log so we can add player names if opts.log_replay: intcpt_replay_io = StringIO() real_replay_io = engine_options['replay_log'] engine_options['replay_log'] = intcpt_replay_io result = run_game(game, bots, engine_options) # destroy temporary directories zip_encapsulator.close() # add player names, write to proper io, reset back to normal if opts.log_replay: replay_json = json.loads(intcpt_replay_io.getvalue()) replay_json['playernames'] = [b[2] for b in bots] real_replay_io.write(json.dumps(replay_json)) intcpt_replay_io.close() engine_options['replay_log'] = real_replay_io # close file descriptors if engine_options['stream_log']: engine_options['stream_log'].close() if engine_options['replay_log']: engine_options['replay_log'].close() if engine_options['input_logs']: for input_log in engine_options['input_logs']: input_log.close() if engine_options['output_logs']: for output_log in engine_options['output_logs']: output_log.close() if engine_options['error_logs']: for error_log in engine_options['error_logs']: error_log.close() if replay_path: if opts.nolaunch: if opts.html_file: visualizer.visualize_locally.launch(replay_path, True, opts.html_file) else: if 'game_length' in result and result['game_length'] > 1: # ANCHOR - this is kool right? if opts.html_file == None: visualizer.visualize_locally.launch(replay_path, generated_path="replay.{0}.html".format(game_id)) else: visualizer.visualize_locally.launch(replay_path, generated_path=opts.html_file)
def run(self): starttime = time() log.info("run game %d %s %s" % (self.id, self.map_name, self.players)) for i, p in enumerate(self.bots): p.write("INFO: game " + str(self.id) + " " + str(self.map_name) + " : " + str(self.players) + "\n") # finally, THE GAME ! game_result = run_game(self.ants, self.bots, self.opts) ## don't need the client threads any more, so we can kill them now for i, b in enumerate(self.bots): del (self.bots[i]) self.bots = None try: states = game_result["status"] except: log.error("broken game %d: %s" % (self.id, game_result)) return if self.ants.turn < 1: log.error("broken game %d (0 turns)" % (self.id)) return scores = game_result["score"] ranks = game_result["rank"] # count draws draws = 0 hist = [0] * len(ranks) for r in ranks: hist[r] += 1 for h in hist: if h > 0: draws += (h - 1) # save replay, add playernames to it game_result['game_id'] = self.id game_result['playernames'] = [] for i, p in enumerate(self.players): game_result['playernames'].append(p) # save to db db = game_db.GameDB() data = json.dumps(game_result) db.add_replay(self.id, data) plr = {} for i, p in enumerate(self.players): res = db.get_player((p, )) status = states[i] if len(res) > 0: status += " (rank %d, skill %2.2f)" % (res[0][4], res[0][5]) plr[p] = (scores[i], status) db.update("insert into gameindex values(?,?,?)", (None, p, self.id)) db.add_game(self.id, self.map_name, self.ants.turn, draws, json.dumps(plr)) # update trueskill if self.opts['trueskill'] == 'jskills': self.calk_ranks_js(self.players, ranks, db) elif self.opts['trueskill'] == 'php': self.calk_ranks_php(self.players, ranks, db) else: # default self.calc_ranks_py(self.players, ranks, db) # update rankings for i, p in enumerate( db.retrieve("select name from players order by skill desc", ())): db.update_player_rank(p[0], i + 1) db.con.commit() # dbg display ds = time() - starttime mins = int(ds / 60) secs = ds - mins * 60 log.info("saved game %d : %d turns %dm %2.2fs" % (self.id, self.ants.turn, mins, secs)) log.info("players: %s" % self.players) log.info("ranks : %s %s draws" % (ranks, draws)) log.info("scores : %s" % scores) log.info("status : %s" % states)
__author__ = 'gram' from engine import set_debug, place_objects, add_location, add_route, set_location, add_object, set_goal from engine import game_action, conditional_game_action, have, add_command, run_game, end_game, enable_route #from engine import post_handler debug = False # Set to true to skip having to get the bucket and chain etc chain_welded = debug bucket_filled = debug gate_unlocked = debug key_dropped = False wizard_splashed = False set_debug(debug) add_location('bedroom', 'You are in the bedroom of a wizards house - there is a wizard snoring loudly on the bed.') add_location('garden', 'You are in a beautiful garden - there is a well in front of you.') add_location('attic', 'You are in the attic of the wizards house - there is a giant welding torch in the corner.') add_location('forest', 'You are in the middle of the deep woods. only a few rays of sunlight reach the ground from here. The porch of the wizard\'s house is to your right.') add_route('bedroom', 'west', 'door', 'garden', True) add_route('bedroom', 'upstairs', 'stairway', 'attic', True) add_route('garden', 'east', 'door', 'bedroom', True) add_route('attic', 'downstairs', 'stairway', 'bedroom', True) add_route('garden', 'outside', 'gate', 'forest', False) add_route('forest', 'inside', 'gate', 'garden', True) # Locations of the objects. place_objects({ 'bottle': 'bedroom', 'bucket' : 'bedroom', 'chain' : 'garden', 'frog' : 'garden', 'cake': 'forest' }) set_location('bedroom') # Current location if the player. location = 'bedroom'
def run_rounds(arguments): """ Parses the given arguments and runs the game with them by calling the engine, then receiving the game result from the engine and passing it on to the visualizer :param arguments: A namespace, containing the arguments for the run :type arguments: Namespace """ def get_bot_paths(cmd, zip_encapsulator): """ Gets the path to a single bot. :param cmd: the name of the bot file :type cmd: string :param zip_encapsulator: a zip encapsulator (object that knows how to unzip files) :type zip_encapsulator: ZipEncapsulator :return: working_dir: the path of the bot directory filepath: the path of the bot file botname: the name of the bot file :rtype: (str, str, str) """ filepath = os.path.realpath(cmd) if filepath.endswith('.zip'): # if we get zip file - override original filepath for abstraction filepath = zip_encapsulator.unzip(filepath) working_dir = os.path.dirname(filepath) bot_name = os.path.basename(cmd).split('.')[0] return working_dir, filepath, bot_name # this split of options is not needed, but left for documentation game_options = { "map": arguments.map, "attack_radius2": arguments.attack_radius_2, "bermuda_zone_radius_2": arguments.bermuda_zone_radius_2, "bermuda_zone_active_turns": arguments.bermuda_zone_active_turns, "required_scripts_num": arguments.required_scripts_num, "load_time": arguments.load_time, "turn_time": arguments.turn_time, "recover_errors": arguments.recover_errors, "turns": arguments.turns, "cutoff_turn": arguments.cutoff_turn, "cutoff_percent": arguments.cutoff_percent, "max_points": arguments.max_points, "randomize_sail_options": arguments.randomize_sail_options, "actions_per_turn": arguments.actions_per_turn, "reload_turns": arguments.reload_turns, "defense_reload_turns": arguments.defense_reload_turns, "max_defense_turns": arguments.max_defense_turns, "treasure_spawn_turns": arguments.treasure_spawn_turns, "spawn_turns": arguments.spawn_turns, "turns_to_sober": arguments.turns_to_sober, "cloak_duration": arguments.cloak_duration, "cloak_reload_turns": arguments.cloak_reload_turns} if arguments.player_seed is not None: game_options['player_seed'] = arguments.player_seed if arguments.engine_seed is not None: game_options['engine_seed'] = arguments.engine_seed engine_options = { "show_traceback": arguments.show_traceback, "load_time": arguments.load_time, "turn_time": arguments.turn_time, "extra_time": arguments.extra_time, "map_file": arguments.map, "turns": arguments.turns, "debug_in_replay": arguments.debug_in_replay, "debug_max_length": arguments.debug_max_length, "debug_max_count": arguments.debug_max_count, "log_replay": arguments.log_replay, "log_stream": arguments.log_stream, "log_input": arguments.log_input, "log_output": arguments.log_output, "log_error": arguments.log_error, "serial": arguments.serial, "strict": arguments.strict, "capture_errors": arguments.capture_errors, "secure_jail": arguments.secure_jail, "end_wait": arguments.end_wait} for round1 in range(arguments.rounds): # initialize bots zip_encapsulator_object = ZipEncapsulator() bots = [get_bot_paths(bot, zip_encapsulator_object) for bot in arguments.bot] bot_count = len(bots) # initialize game game_id = "{0}.{1}".format(arguments.game_id, round1) if arguments.rounds > 1 else arguments.game_id with open(arguments.map, 'r') as map_file: game_options['map'] = map_file.read() if arguments.engine_seed: game_options['engine_seed'] = arguments.engine_seed + round1 game_options['bot_names'] = map(lambda some_bot: some_bot[2], bots) game_options['init_turn'] = max(arguments.first_turn, 0) if arguments.load_pickled_game: with open(arguments.load_pickled_game, 'r') as f: game = cPickle.load(f) game.init_turn = game.turn else: game = PiratesGame(game_options) # insure correct number of bots, or fill in remaining positions if game.num_players != len(bots): print("Incorrect number of bots for map. Need {0}, got {1}" .format(game.num_players, len(bots)), file=stderr) # initialize file descriptors if arguments.log_dir and not os.path.exists(arguments.log_dir): os.mkdir(arguments.log_dir) if not arguments.log_replay and not arguments.log_stream and (arguments.log_dir or arguments.log_stdout): arguments.log_replay = True replay_path = None # used for visualizer launch if arguments.log_replay: if arguments.log_dir: replay_path = os.path.join(arguments.log_dir, '{0}.replay'.format(game_id)) engine_options['replay_log'] = open(replay_path, 'w') if arguments.log_stdout: if 'replay_log' in engine_options and engine_options['replay_log']: engine_options['replay_log'] = Tee(sys.stdout, engine_options['replay_log']) else: engine_options['replay_log'] = sys.stdout else: engine_options['replay_log'] = None if arguments.log_stream: if arguments.log_dir: engine_options['stream_log'] = open(os.path.join(arguments.log_dir, '{0}.stream'.format(game_id)), 'w') if arguments.log_stdout: if engine_options['stream_log']: engine_options['stream_log'] = Tee(sys.stdout, engine_options['stream_log']) else: engine_options['stream_log'] = sys.stdout else: engine_options['stream_log'] = None if arguments.log_input and arguments.log_dir: engine_options['input_logs'] = [ open(os.path.join(arguments.log_dir, '{0}.bot{1}.input'.format(game_id, i)), 'w') for i in range(bot_count)] if arguments.log_output and arguments.log_dir: engine_options['output_logs'] = [ open(os.path.join(arguments.log_dir, '{0}.bot{1}.output'.format(game_id, i)), 'w') for i in range(bot_count)] if arguments.log_error and arguments.log_dir: if arguments.log_stderr: if arguments.log_stdout: engine_options['error_logs'] = [Tee(Comment(stderr), open( os.path.join(arguments.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [ Tee(stderr, open(os.path.join(arguments.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [ open(os.path.join(arguments.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w') for i in range(bot_count)] elif arguments.log_stderr: if arguments.log_stdout: engine_options['error_logs'] = [Comment(stderr)] * bot_count else: engine_options['error_logs'] = [stderr] * bot_count if arguments.verbose: if arguments.log_stdout: engine_options['verbose_log'] = Comment(sys.stdout) else: engine_options['verbose_log'] = sys.stdout if arguments.debug: engine_options['debug_log'] = sys.stdout engine_options['game_id'] = game_id if arguments.rounds > 1: print('# playgame round {0}, game id {1}'.format(round1, game_id)) # intercept replay log so we can add player names if arguments.log_replay: intcpt_replay_io = StringIO() real_replay_io = engine_options['replay_log'] engine_options['replay_log'] = intcpt_replay_io if arguments.dump_pickled_game: # parse the turns in which to create a pickled file, if there are so if arguments.dump_pickled_game_turns: try: pickled_game_turns = [int(turn) for turn in arguments.dump_pickled_game_turns] except ValueError: raise ValueError('Each value in -T/--dump-pickled-game-turns must be an integer!') else: raise Exception('Please supply the turns in which to dump the game, using -T!') dump_pickled_game_basename = os.path.splitext(arguments.dump_pickled_game)[0] dump_pickled_games = {} for turn in pickled_game_turns: # if turn == -1, then it means the last turn if turn == -1: dump_pickled_games[turn] = dump_pickled_game_basename + '_last.pkl' else: dump_pickled_games[turn] = dump_pickled_game_basename + '_' + str(turn) + '.pkl' engine_options['dump_pickled_games'] = dump_pickled_games # if dump_pickled_game_turns is not empty but an out name wasn't supplied elif arguments.dump_pickled_game_turns: raise Exception('Please supply a name for the pickled game file, using -s!') if arguments.regression_output_path: engine_options['regression_output_path'] = arguments.regression_output_path result = run_game(game, bots, engine_options) # destroy temporary directories zip_encapsulator_object.close() # add player names, write to proper io, reset back to normal if arguments.log_replay: replay_json = json.loads(intcpt_replay_io.getvalue()) replay_json['playernames'] = [b[2] for b in bots] real_replay_io.write(json.dumps(replay_json)) intcpt_replay_io.close() engine_options['replay_log'] = real_replay_io # close file descriptors if engine_options['stream_log']: engine_options['stream_log'].close() if engine_options['replay_log']: engine_options['replay_log'].close() if 'input_logs' in engine_options: for input_log in engine_options['input_logs']: input_log.close() if 'output_logs' in engine_options: for output_log in engine_options['output_logs']: output_log.close() if 'error_logs' in engine_options: for error_log in engine_options['error_logs']: error_log.close() if replay_path: if arguments.no_launch: if arguments.html_file: visualizer.visualize_locally.launch(replay_path, True, arguments.html_file) else: if arguments.html_file is None: visualizer.visualize_locally.launch(replay_path, generated_path="replay.{0}.html".format(game_id)) else: visualizer.visualize_locally.launch(replay_path, generated_path=arguments.html_file)
"points" : args.points, "map" : os.path.join( os.getcwd(), args.map), "log_dir" : os.path.join( os.getcwd(), args.log_path ), "arena" : os.path.join( os.getcwd(), args.arena ), "turns" : args.turns, "base_dir" : os.getcwd()} # enumerate game options game_options = {"map" : engine_options["map"], "turntime" : args.turntime, "loadtime" : args.loadtime, "bot_count" : len(args.bot_list), "base_dir" : os.getcwd()} # make file decriptors for game level logs if not os.path.exists(engine_options["log_dir"]): os.mkdir(engine_options["log_dir"]) engine_options["game_log"] = open( os.path.join( engine_options["log_dir"], "game_log.r%d.log" % 0), 'w' ) # round 0 # game = quantum.Game(game_options) game = quantum.Game(game_options) result, replay_json = engine.run_game(game, args.bot_list, engine_options) # do more logging print(result) print(replay_json) # close FDs! engine_options["game_log"].close()
def run_rounds(opts,args): def get_bot_paths(cmd, zip_encapsulator): ''' Receives a single file string from the command line and Returns a 3 list of <working_dir> <full_file_path> <file_name> ''' filepath = os.path.realpath(cmd) if filepath.endswith('.zip'): # if we get zip file - override original filepath for abstraction filepath = zip_encapsulator.unzip(filepath) working_dir = os.path.dirname(filepath) bot_name = os.path.basename(cmd).split('.')[0] return working_dir, filepath, bot_name def get_cmd_wd(cmd, exec_rel_cwd=False): ''' get the proper working directory from a command line ''' new_cmd = [] wd = None for i, part in reversed(list(enumerate(cmd.split()))): if wd == None and os.path.exists(part): wd = os.path.dirname(os.path.realpath(part)) basename = os.path.basename(part) if i == 0: if exec_rel_cwd: new_cmd.insert(0, os.path.join(".", basename)) else: new_cmd.insert(0, part) else: new_cmd.insert(0, basename) else: new_cmd.insert(0, part) return wd, ' '.join(new_cmd) def get_cmd_name(cmd): ''' get the name of a bot from the command line ''' for i, part in enumerate(reversed(cmd.split())): # if extra whatever-"-character-called in the line - remove them part = part.replace('"','') if os.path.exists(part): return os.path.basename(part) # this split of options is not needed, but left for documentation game_options = { "map": opts.map, "attack": opts.attack, "viewradius2": opts.viewradius2, "attackradius2": opts.attackradius2, "loadtime": opts.loadtime, "turntime": opts.turntime, "recover_errors": opts.recover_errors, "turns": opts.turns, "cutoff_turn": opts.cutoff_turn, "cutoff_percent": opts.cutoff_percent, "scenario": opts.scenario, "maxpoints" : opts.maxpoints, "randomize_sail_options" : opts.randomize_sail_options, "actions_per_turn" : opts.actions_per_turn, "reload_turns" : opts.reload_turns, "defense_reload_turns" : opts.defense_reload_turns, "defense_expiration_turns" : opts.defense_expiration_turns, "treasure_spawn_turns" : opts.treasure_spawn_turns, "spawn_turns" : opts.spawn_turns, "sober_turns" : opts.sober_turns, "ghostcooldown" : opts.ghostcooldown, "fogofwar" : opts.fogofwar } if opts.player_seed != None: game_options['player_seed'] = opts.player_seed if opts.engine_seed != None: game_options['engine_seed'] = opts.engine_seed engine_options = { "loadtime": opts.loadtime, "turntime": opts.turntime, "extratime": opts.extratime, "map_file": opts.map, "turns": opts.turns, "debug_in_replay": opts.debug_in_replay, "debug_max_length": opts.debug_max_length, "debug_max_count": opts.debug_max_count, "log_replay": opts.log_replay, "log_stream": opts.log_stream, "log_input": opts.log_input, "log_output": opts.log_output, "log_error": opts.log_error, "serial": opts.serial, "strict": opts.strict, "capture_errors": opts.capture_errors, "secure_jail": opts.secure_jail, "end_wait": opts.end_wait } for round in range(opts.rounds): # initialize bots zip_encapsulator = ZipEncapsulator() bots = [get_bot_paths(arg, zip_encapsulator) for arg in args] bot_count = len(bots) # initialize game game_id = "{0}.{1}".format(opts.game_id, round) if opts.rounds > 1 else opts.game_id with open(opts.map, 'r') as map_file: game_options['map'] = map_file.read() if opts.engine_seed: game_options['engine_seed'] = opts.engine_seed + round game_options['bot_names'] = map(lambda b: b[2], bots) game = Pirates(game_options) # insure correct number of bots, or fill in remaining positions if game.num_players != len(bots): print("Incorrect number of bots for map. Need {0}, got {1}" .format(game.num_players, len(bots)), file=stderr) # initialize file descriptors if opts.log_dir and not os.path.exists(opts.log_dir): os.mkdir(opts.log_dir) if not opts.log_replay and not opts.log_stream and (opts.log_dir or opts.log_stdout): opts.log_replay = True replay_path = None # used for visualizer launch if opts.log_replay: if opts.log_dir: replay_path = os.path.join(opts.log_dir, '{0}.replay'.format(game_id)) engine_options['replay_log'] = open(replay_path, 'w') if opts.log_stdout: if 'replay_log' in engine_options and engine_options['replay_log']: engine_options['replay_log'] = Tee(sys.stdout, engine_options['replay_log']) else: engine_options['replay_log'] = sys.stdout else: engine_options['replay_log'] = None if opts.log_stream: if opts.log_dir: engine_options['stream_log'] = open(os.path.join(opts.log_dir, '{0}.stream'.format(game_id)), 'w') if opts.log_stdout: if engine_options['stream_log']: engine_options['stream_log'] = Tee(sys.stdout, engine_options['stream_log']) else: engine_options['stream_log'] = sys.stdout else: engine_options['stream_log'] = None if opts.log_input and opts.log_dir: engine_options['input_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.input'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['input_logs'] = None if opts.log_output and opts.log_dir: engine_options['output_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.output'.format(game_id, i)), 'w') for i in range(bot_count)] else: engine_options['output_logs'] = None if opts.log_error and opts.log_dir: if opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Tee(Comment(stderr), open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [Tee(stderr, open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w')) for i in range(bot_count)] else: engine_options['error_logs'] = [open(os.path.join(opts.log_dir, '{0}.bot{1}.error'.format(game_id, i)), 'w') for i in range(bot_count)] elif opts.log_stderr: if opts.log_stdout: engine_options['error_logs'] = [Comment(stderr)] * bot_count else: engine_options['error_logs'] = [stderr] * bot_count else: engine_options['error_logs'] = None if opts.verbose: if opts.log_stdout: engine_options['verbose_log'] = Comment(sys.stdout) else: engine_options['verbose_log'] = sys.stdout if opts.debug: engine_options['debug_log'] = sys.stdout engine_options['game_id'] = game_id if opts.rounds > 1: print('# playgame round {0}, game id {1}'.format(round, game_id)) # intercept replay log so we can add player names if opts.log_replay: intcpt_replay_io = StringIO() real_replay_io = engine_options['replay_log'] engine_options['replay_log'] = intcpt_replay_io result = run_game(game, bots, engine_options) # destroy temporary directories zip_encapsulator.close() # add player names, write to proper io, reset back to normal if opts.log_replay: replay_json = json.loads(intcpt_replay_io.getvalue()) replay_json['playernames'] = [b[2] for b in bots] real_replay_io.write(json.dumps(replay_json)) intcpt_replay_io.close() engine_options['replay_log'] = real_replay_io # close file descriptors if engine_options['stream_log']: engine_options['stream_log'].close() if engine_options['replay_log']: engine_options['replay_log'].close() if engine_options['input_logs']: for input_log in engine_options['input_logs']: input_log.close() if engine_options['output_logs']: for output_log in engine_options['output_logs']: output_log.close() if engine_options['error_logs']: for error_log in engine_options['error_logs']: error_log.close() if replay_path: if opts.nolaunch: if opts.html_file: visualizer.visualize_locally.launch(replay_path, True, opts.html_file) else: if 'game_length' in result and result['game_length'] > 1: # ANCHOR - this is kool right? if opts.html_file == None: visualizer.visualize_locally.launch(replay_path, generated_path="replay.{0}.html".format(game_id)) else: visualizer.visualize_locally.launch(replay_path, generated_path=opts.html_file)