def __init__(self, game_opts, enemies, reward_func, agent_names=None): self.game_opts = game_opts self.enemies = enemies self.reward_func = reward_func self.game = Ants(self.game_opts.as_dict()) if len(self.enemies) >= self.game.num_players: raise ValueError( 'The number of enemies should be strictly less than the number of players. Otherwise there will be no agent to play against.' ) self.num_agents = self.game.num_players - len(self.enemies) if not agent_names: self.agent_names = [f'Agent {i}' for i in range(self.num_agents)] elif len(agent_names) != self.num_agents: raise ValueError( f'len(agent_names) == {len(agent_names)} should be 0 or equal to the number of agents == {self.num_agents}.' ) else: self.agent_names = agent_names self.observation_space = gym.spaces.Box( low=0, high=1, shape=(self.num_agents, 5 + self.game.num_players, self.game.height, self.game.width), dtype=np.uint8) self.action_space = gym.spaces.Box(low=0, high=4, shape=(self.num_agents, self.game.height, self.game.width), dtype=np.uint8) self.reset(self.game)
def create_ant(self): if len(self.ants) >= self.ants_max: return if randint(0, 100) < self.probability_new_ant: ant = Ants(self.graph.nest, self.graph.nest, self.graph.nest, 0, 0, self.ant_greediness, self.ant_greediness_food) self.ants.append(ant)
def simulate_battle(map_segment, attackradius2, attack_method): # add buffer so that battles aren't affected by wrapping #buffer = int(sqrt(attackradius2)) + 1 buffer = 0 map_data = create_map_data(map_segment, buffer) game = Ants({ 'attackradius2': attackradius2, 'map': map_data, 'attack': attack_method, # the rest of these options don't matter 'loadtime': 0, 'turntime': 0, 'viewradius2': 100, 'spawnradius2': 2, 'turns': 1 }) game.do_attack() # Figure out what number we labeled each character a = 0 b = 0 #print game.player_chars if 'a' in game.player_chars: a = len(game.player_ants(game.player_chars.index('a'))) if 'b' in game.player_chars: b = len(game.player_ants(game.player_chars.index('b'))) # remove buffer and return return (create_map_output(game.map, buffer), (a,b))
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 __init__(self, id, opts, map_name, nplayers): threading.Thread.__init__(self) self.id = id self.opts = opts self.players = [] self.bot_status = [] self.map_name = map_name self.nplayers = nplayers self.bots = [] self.ants = Ants(opts)
def reset(self, init_game=None): self.reward_func.reset() self.game = init_game or Ants(self.game_opts.as_dict()) self.is_done = False self.game.start_game() for i, enemy in enumerate(self.enemies): enemy.reset() enemy.setup(self.game.get_player_start(i + self.num_agents)) enemy.update_map(self.game.get_player_state(i + self.num_agents)) obs = self._get_observations(reset=True) return obs
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 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 simulate_battle(map_segment, attackradius2, attack_method): # add buffer so that battles aren't affected by wrapping buffer = int(sqrt(attackradius2)) + 1 map_data = create_map_data(map_segment, buffer) game = Ants({ 'attackradius2': attackradius2, 'map': map_data, 'attack': attack_method, # the rest of these options don't matter 'loadtime': 0, 'turntime': 0, 'viewradius2': 100, 'spawnradius2': 2, 'turns': 1 }) game.do_attack() # remove buffer and return return create_map_output(game.map, buffer)
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)
elif Q[state + action] == bestQ: bestActions.append(a) myAction = random.choice(bestActions) enemyAction = random.choice(actions) # Simulate orders map_data = create_map_data(sp, 0) game = Ants({ 'attackradius2': attackradius2, 'map': map_data, 'attack': method, # the rest of these options don't matter 'loadtime': 0, 'turntime': 0, 'viewradius2': 100, 'spawnradius2': 2, 'turns': 1 }) a = game.player_chars.index('a') b = game.player_chars.index('b') """ Orders must be of the form: o row col direction row, col must be integers direction must be in (n,s,e,w) """ myOrders = []
def populate(self): for i in range(self.ants_init): ant = Ants(self.graph.nest, self.graph.nest, self.graph.nest, False, 0, self.ant_greediness, self.ant_greediness_food) ant.attr = i self.ants.append(ant)
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 __init__(self, argv): opts, args = main(argv) self.game = Ants(get_game_opts(opts,args)) self.agent_moves = {} self.game.start_game() # TODO: might move self.screen_shape = (self.game.height, self.game.width)
Util.set_parameters( sys.argv) # set all parameters and value from arguments command # get the instance for the run index_instance = sys.argv.index("-i") if "-i" in sys.argv else sys.argv.index( "--instance") path = sys.argv[index_instance + 1] filename = os.path.basename(path) qap = Reader(path) # construct the problem Util.get_configuration() # get the best configuration of the ant system runs = [sys.maxsize for i in range(Params.singleton.MAX_RUN)] for t in range(Params.singleton.MAX_TRY): colony = Ants(qap.matrix_A, qap.matrix_B, Params.singleton.nb_ants, qap.size) colony.init_pheromone(1 / (Params.singleton.RHO * qap.size)) run = 0 start = time.time() while not terminal_condition(run, start): construct_solutions(colony) # build the solution for each ant if Params.singleton.lcs_flag: colony.local_search() # apply the local search update_pheromone( colony) # update the pheromone depending on the ant system save_run(run, colony) # Save the current run