def main(): os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "true" # cancel py-game display from environment.game import Game from agents.random_agent import RandomAgent from agents.ddqn_agent import DdqnAgent from agents.constant_agent import ConstantAgent from agents.basic_mcts_agent import BasicMCTSAgent from runnable_scripts.Utils import create_dir, ridge_plot, save_ini_file # create directory for storing the results dir_path = create_dir() # create the game with the required agents env = Game( device=torch.device("cuda" if torch.cuda.is_available() else "cpu"), agent_zombie=RandomAgent, agent_light=DdqnAgent) # env = Game(device=torch.device("cuda" if torch.cuda.is_available() else "cpu"), agent_zombie=BasicMCTSAgent, agent_light=ConstantAgent) # play the game and produce the dictionaries of the results episodes_dict, steps_dict_light, steps_dict_zombie = env.play_zero_sum_game( dir_path) # save and create results graph results_file_name = '/results_' + time.strftime('%d_%m_%Y_%H_%M') save_ini_file(dir_path, results_file_name, steps_dict_light, steps_dict_zombie, episodes_dict) ridge_plot(dir_path, results_file_name + '.xlsx') print('Eliav king')
def simulate_action(alive_zombies, agent_type, action): """ Simulating future states by 'actions' of an agent :param alive_zombies: all alive zombies at the real world :param agent_type: 'zombie' or 'light' agent :param action: array containing all the actions to simulate :return: total reward of the simulation """ new_alive_zombies = list(copy.deepcopy(alive_zombies)) # make a copy of all zombies - we do not want to make any act in real world # set action and light agents actions if agent_type == 'zombie': zombie_action = action # random sample len(actions) times from light-agent actions-space light_action = 0 # np.random.randint(0, BasicMCTSAgent.BOARD_HEIGHT * BasicMCTSAgent.BOARD_WIDTH) else: light_action = action # sample n times from zombie-agent actions-space zombie_action = np.random.randint(0, BasicMCTSAgent.BOARD_HEIGHT) # simulate and aggregate reward total_reward = 0 new_zombie = Game.create_zombie(zombie_action) new_alive_zombies.append(new_zombie) reward, final_alive_zombies = Game.calc_reward_and_move_zombies(new_alive_zombies, light_action) total_reward += reward return total_reward, final_alive_zombies
def main(): #TODO:- take input args to toggle debug mode #reads file to list so that indexing is easy filename = 'config.txt' fileList = [] try: with open(filename) as f_obj: for line in f_obj: fileList.append(line) except FileNotFoundError: msg = "Can't find file {0}.".format(filename) print(msg) exit print("\nFile read succesful...") try: #config is all information a single game requires config = Config(fileList) config.setMappings() #metaConfig is the information required to run several games in a row metaconfig = MetaConfig(fileList) if (metaconfig.totalGames > 1): cumulative = CumulativeGraph() except IndexError: print("\nIssue with config file. Exiting program... \n") exit cumulative = CumulativeGraph() for x in range(1, metaconfig.totalGames + 1): population = [] game = Game(config, 0, population) game.initialMorphGen(config) results = game.run(config) if metaconfig.plotIndiv == 1: graph = BasicGraph(results) graph.plotResults(config, metaconfig.savePlots, metaconfig.plotDirectory) if metaconfig.totalGames > 1: cumulative.addGame(results) updateConfig(config, metaconfig) if metaconfig.totalGames > 1: if int(metaconfig.mergeCumulative, 10) == 1: cumulative.plotMergedResults(metaconfig.plotIndiv, metaconfig.plotDirectory, config) if (metaconfig.savePlots == 1): cumulative.saveResults(metaconfig.plotDirectory) print( "\nExecution succesful. Deallocating memory and exiting program...\n")
def act(self, game: Game, snake_idx: int): snake = game.get_snake(snake_idx) possible_actions = snake.possible_actions() if possible_actions is None: return None grid_map = game.get_grid() busy_action = self.feel_busy(snake, game, grid_map) if busy_action is not None: return busy_action return np.random.choice(possible_actions)
def create_dummy_game(i: int = 0, overwrite: bool = True, show: bool = True): cfg = get_shared_config() ROBOT_INIT_POS = Vec2d(cfg.game.x_axis / 2, cfg.game.y_axis / 2) # Initial position of the drone spawn_f = SpawnSimple(game_config=cfg, train=True) spawn_f.add_location((1, 1)) game = Game( config=cfg, game_id=get_game_id(i, experiment_id=0), overwrite=overwrite, spawn_func=spawn_f, ) game.player = Robot(game=game) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show)
def evaluate(self): """Play the game and only record the final score.""" self.agent.training = False # Create all the games games = [] for _ in range(self.n_envs): games.append(Game()) # Reset the agent self.agent.reset(n_envs=self.n_envs, sample_game=games[0]) # Evaluate the agent on the different games step = 0 finished = [False, ] * self.n_envs progress = tqdm() while not all(finished) and step < self.max_steps: progress.update() step += 1 # Get the actions for the current states actions = self.agent(games=games) # Go over each game and progress by one for i, (g, a, f) in enumerate(zip(games, actions, finished)): if not f: # Progress the game with one step finished[i] = not g.step(a=a) progress.close() # Return the final scores of each game return [g.score for g in games]
def act(self, game: Game, snake_idx: int): snake = game.get_snake(snake_idx) possible_actions = snake.possible_actions() if self.next_action in possible_actions: self.last_action = self.next_action return self.last_action
def create_game(first_player: Player, second_player: Player, first_color: Color = Color.RED) -> Game: return Game(grid=Grid(), judge=judge, first_player=first_player, second_player=second_player, first_color=first_color)
def act(self, game: Game, snake_idx: int) -> Optional[Direction]: snake = game.get_snake(snake_idx) all_snacks = game.snakes grid_map = game.get_grid() opponent = None for i, s in enumerate(all_snacks): if i == snake_idx: continue opponent = s head = snake.get_head() # print('position of head [%d, %d] and direction: %s' % (head.x, head.y, head.direction)) fruits = game.get_fruits() direction = None for fruit in fruits: cost, path = KILabAgent.a_star_search(game, head, head.direction, fruit, grid_map) field = path[0] if not opponent.is_dead(): head_op = opponent.get_head() op_to_fruit = abs(head_op.x - fruit.x) + abs(head_op.y - fruit.y) to_fruit = abs(head.x - fruit.x) + abs(head.y - fruit.y) if snake.length() < opponent.length(): if to_fruit > op_to_fruit: f = grid_map.get_object_at(int(game.width/2), int(game.height/2)) while game.is_obstacle(f): f = grid_map.get_object_at(f.x + 1, f.y + 1) field = f delta_x = head.x - field.x delta_y = head.y - field.y if delta_y == 0: if delta_x > 0: direction = Direction.LEFT else: direction = Direction.RIGHT if delta_x == 0: if delta_y > 0: direction = Direction.UP else: direction = Direction.DOWN return direction
def get_game(): cfg = Config() cfg.game.fps = 60 cfg.game.x_axis = 1 cfg.game.y_axis = 1 cfg.update() spawn = SpawnSimple(game_config=cfg) spawn.add_location((10, 10)) # Dummy location game = Game( config=cfg, game_id=0, noise=False, overwrite=True, save_path="tests/games_db/", silent=True, spawn_func=spawn, wall_bound=True, ) game.set_player_init_pos(Vec2d(0.5, 0.5)) game.sample_target() game.reset() return game
def feel_busy(self, snake: Snake, game: Game, grid_map: GridMap): possible_actions = snake.possible_actions() head = snake.get_head() if possible_actions is None: return None actions_without_obstacle = [] for action in possible_actions: neighbor = grid_map.get_neighbor(head.x, head.y, action, game.height, game.width) if neighbor is None: continue if not Game.is_obstacle(neighbor): actions_without_obstacle.append(action) if len(actions_without_obstacle) > 0: return np.random.choice(actions_without_obstacle) else: return None
def train(self): """ Play the game while recording actions and rewards, which are used afterwards to train the agent model on. :return: Scores (per game), durations (pg), snake-length (pg), training loss """ # Create all the games games = [] for _ in range(self.n_envs): games.append(Game()) # Reset the agent self.agent.training = True self.agent.reset(n_envs=self.n_envs, sample_game=games[0]) # Evaluate the agent on the different games duration = [0, ] * self.n_envs # First iteration gets duration 0 finished = [False, ] * self.n_envs while not all(finished) and max(duration) < self.max_steps: # Get the actions for the current states actions = self.agent(games) uses_tuple = isinstance(actions[0], tuple) # Go over each game and progress by one for i, (g, a, f) in enumerate(zip(games, actions, finished)): if not f: # Progress the game with one step finished[i] = not g.step(a=a, uses_tuple=uses_tuple) # Progress duration of game duration[i] += 1 # Train the model before returning the scores loss = self.agent.train(duration=duration, max_duration=self.max_steps) # Return the final scores of each game return [g.score for g in games], duration, [len(g.snake.body) for g in games], loss
""" inspect_games.py Check if all games are created correctly. """ import os from config import Config from environment.game import Game if __name__ == '__main__': os.chdir("../..") config = Config() for g_id in [1, 2, 3]: try: game = Game( game_id=g_id, config=config, save_path="environment/games_db/", overwrite=False, silent=True, ) game.close() game.reset() game.get_blueprint() game.get_observation() game.step(0, 0) except Exception: print(f"Bug in game: {g_id}, please manually redo this one")
(last_move is not None and self._judge.is_over_after_move_in_col(grid.state, last_move)): return self._evaluate(grid.state, self._judge), 0 value = -INF if color == MAX_COLOR else INF best_move = None for move in grid.available_moves: child_value, _ = self._minmax(grid.grid_after_move(color, move), depth - 1, alpha, beta, Color(1 - color), move) if color == MAX_COLOR and child_value > value: best_move = move value = child_value alpha = max(alpha, value) elif color == MIN_COLOR and child_value < value: best_move = move value = child_value beta = min(beta, value) if alpha >= beta: break self._transposition_table[grid.state] = (depth, value, best_move) return value, best_move if __name__ == '__main__': game = Game(Grid(), Judge(), MinmaxPlayer(Color.RED, Judge(), Evaluator(), 4, 30), MinmaxPlayer(Color.BLACK, Judge(), Evaluator(), 6, 18)) print(game.play())
def create_experiment_3(overwrite: bool = True, show: bool = True): """ Experiment 3 tests both the generalization capabilities in adapting to newly spawned targets. In this scenario, new targets are spawned ones the previous are found, with the goal to find as many as possible. TRAINING During training, new targets are spawned based on the agent's current position. Each target will lay between 4 and 8 meters from the agent and will always be positioned inside of the maze. TESTING Testing is done similar as was the case for training, with the main difference that the positions of the targets are defined beforehand, this to ensure a fair comparison between the different evaluations. 10 targets are created, with the idea that it would be impossible for the drone to ever reach this many targets. """ cfg = get_shared_config() # Fixed parameters ROBOT_INIT_ANGLE = pi / 2 # Looking up ROBOT_INIT_POS = Vec2d(cfg.game.x_axis / 2, cfg.game.y_axis / 2) # Initial position of the drone # Create the training game spawn_f_train = SpawnRandom(game_config=cfg.game, train=True) game = Game( config=cfg, player_noise=0, game_id=get_game_id(0, experiment_id=3), overwrite=overwrite, spawn_func=spawn_f_train, stop_if_reached=False, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show) # Create 20 evaluation games for i in range(1, 21): spawn_f_eval = SpawnRandom(game_config=cfg.game, train=False) game = Game( config=cfg, player_noise=0, game_id=get_game_id(i, experiment_id=3), overwrite=overwrite, spawn_func=spawn_f_eval, stop_if_reached=False, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show, randomize=False)
def live_visualisation(agent: Agent = Empty(), game: Game = None): """Visualise the performance of the given agent.""" if not game: game = Game() # Regularly used constants width = game.width * game.pixels height = game.height * game.pixels # Initialise the Pyglet instance window = pyglet.window.Window(width, height, "PySnake", resizable=False, visible=True) window.set_location(100, 100) pyglet.gl.glClearColor(1, 1, 1, 1) # Draw the environment space = pymunk.Space() options = DrawOptions() # Label for the score label = pyglet.text.Label(f'{game.score}', font_size=12, color=(100, 100, 100, 100), x=window.width - 30, y=window.height - 30, anchor_x='center', anchor_y='center') # Draw a square in the environment def draw_segment(pos, i=None, color=(0, 128, 0)): """Draw square segment at position p.""" target_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) target_body.position = (pos[0] * game.pixels + game.pixels / 2, pos[1] * game.pixels + game.pixels / 2) target_shape = pymunk.Poly.create_box(body=target_body, size=(game.pixels * 0.9, game.pixels * 0.9)) target_shape.sensor = True if i is not None: target_shape.id = i target_shape.color = color space.add(target_body, target_shape) # Draw the walls for i in range(game.height): draw_segment((0, i), color=(0, 0, 0)) draw_segment((game.width - 1, i), color=(0, 0, 0)) for i in range(game.width): draw_segment((i, 0), color=(0, 0, 0)) draw_segment((i, game.height - 1), color=(0, 0, 0)) # Draw the apple draw_segment(game.apple, i=-1, color=(128, 0, 0)) # Create the Snake instance snake_i = IntegerGenerator() # Iterator for the snake segments agent.training = False agent.reset(n_envs=1, sample_game=game) def draw_snake(init=False): """Draw the snake.""" if init: for p in reversed(game.snake.body): draw_segment(p, i=snake_i()) else: draw_segment(game.snake.body[0], i=snake_i()) # Initialise the snake draw_snake(init=True) @window.event def on_draw(): window.clear() label.text = str(game.score) label.draw() space.debug_draw(options=options) # Make game keyboard sensitive if type(agent) == Empty: @window.event def on_key_press(key, _): """Called whenever a key is pressed to record manual input.""" if key == arcade.key.LEFT and game.snake.direction != RIGHT: game.snake.direction = LEFT elif key == arcade.key.RIGHT and game.snake.direction != LEFT: game.snake.direction = RIGHT elif key == arcade.key.UP and game.snake.direction != DOWN: game.snake.direction = UP elif key == arcade.key.DOWN and game.snake.direction != UP: game.snake.direction = DOWN def update_method(dt): """Update the game environment.""" # Query brain to get action for current state a = agent([game])[0] # Progress the game score_pre = game.score alive = game.step(a=a) if not alive: pyglet.app.exit() score_post = game.score eaten = score_pre != score_post # Remove the oldest added shape for shape in space.shapes: if hasattr(shape, 'id') and shape.id <= len(snake_i) - ( game.snake.length - 1): if eaten: space.remove(shape.body, shape) draw_segment(game.apple, i=-1, color=(128, 0, 0)) elif shape.id >= 0: space.remove(shape.body, shape) # Proceed the snake draw_snake() # Perform required action space.step(dt) # Run the game pyglet.clock.schedule_interval(update_method, .1) pyglet.app.run()
def act(QDKrSREt, game: Game, snake_idx: int): QDKrSREC = [] QDKrSREe = None for QDKrSREf, snake in enumerate(game.snakes): if not snake.body: continue if QDKrSREf == snake_idx: QDKrSREM = snake else: QDKrSREn = snake QDKrSREC = QDKrSREn.body QDKrSREF = QDKrSREC[0].x QDKrSREL = QDKrSREC[0].y QDKrSREm = QDKrSREM.body QDKrSREz = QDKrSREm[0].x QDKrSREG = QDKrSREm[0].y QDKrSREo = QDKrSREm[-1].x QDKrSREW = QDKrSREm[-1].x QDKrSREg = game.width QDKrSREU = game.height QDKrSREs = game.get_fruits() QDKrSREJ = QDKrSREg * 2 + QDKrSREU * 2 for QDKrSREV in QDKrSREs: QDKrSREx = QDKrSREV.x QDKrSREd = QDKrSREV.y QDKrSREN = abs(QDKrSREG - QDKrSREd) + abs(QDKrSREz - QDKrSREx) if QDKrSREN < QDKrSREJ: QDKrSREJ = QDKrSREN QDKrSREv = QDKrSREV.x QDKrSREX = QDKrSREV.y QDKrSREj = 0 for QDKrSREV in QDKrSREs: QDKrSREx = QDKrSREV.x QDKrSREd = QDKrSREV.y QDKrSREN = abs(QDKrSREG - QDKrSREd) + abs(QDKrSREz - QDKrSREx) for QDKrSREf, snake in enumerate(game.snakes): if not snake.body: continue if QDKrSREf == snake_idx: continue else: QDKrSREn = snake QDKrSREC = QDKrSREn.body QDKrSREF = QDKrSREC[0].x QDKrSREL = QDKrSREC[0].y QDKrSREy = abs(QDKrSREL - QDKrSREX) + abs(QDKrSREF - QDKrSREv) if QDKrSREy <= QDKrSREN: QDKrSREj += 0 continue else: QDKrSREN = abs(QDKrSREG - QDKrSREd) + abs(QDKrSREz - QDKrSREx) QDKrSREj += 1 if QDKrSREN < QDKrSREJ: QDKrSREJ = QDKrSREN QDKrSREv = QDKrSREV.x QDKrSREX = QDKrSREV.y if QDKrSREj == 0: for QDKrSREV in QDKrSREs: QDKrSREx = QDKrSREV.x QDKrSREd = QDKrSREV.y QDKrSREN = abs(QDKrSREG - QDKrSREd) + abs(QDKrSREz - QDKrSREx) if QDKrSREN < QDKrSREJ: QDKrSREJ = QDKrSREN QDKrSREv = QDKrSREV.x QDKrSREX = QDKrSREV.y QDKrSREP = numpy.zeros((QDKrSREg, QDKrSREU)) QDKrSREY = [n for n in range(100)] for QDKrSREA in QDKrSREm: QDKrSREP[QDKrSREA.x, QDKrSREA.y] = 1 if len(game.snakes) > 1: for QDKrSREH in QDKrSREC: QDKrSREP[QDKrSREH.x, QDKrSREH.y] = 1 for QDKrSREf, snake in enumerate(game.snakes): if not snake.body: continue if QDKrSREf == snake_idx: continue else: QDKrSREn = snake QDKrSREC = QDKrSREn.body QDKrSREF = QDKrSREC[0].x QDKrSREL = QDKrSREC[0].y for QDKrSREH in QDKrSREC: QDKrSREP[QDKrSREH.x, QDKrSREH.y] = 1 if len(QDKrSREC) >= len(QDKrSREm): for QDKrSREV in QDKrSREs: if not QDKrSREt.astar(QDKrSREP, (QDKrSREF, QDKrSREL), (QDKrSREV.x, QDKrSREV.y)): continue else: QDKrSREp = QDKrSREt.astar(QDKrSREP, (QDKrSREF, QDKrSREL), (QDKrSREV.x, QDKrSREV.y)) if len(QDKrSREp) <= 3: if len(QDKrSREp) < len(QDKrSREY): QDKrSREY = QDKrSREp QDKrSRET = QDKrSREY[-1] QDKrSREi = QDKrSRET[0] QDKrSREc = QDKrSRET[1] QDKrSREP[QDKrSREi, QDKrSREc] = 1 QDKrSREa = [n for n in range(100)] QDKrSREw = [QDKrSREu for QDKrSREu in range(QDKrSREg)] QDKrSREl = [QDKrSREI for QDKrSREI in range(QDKrSREU)] for QDKrSREu in QDKrSREw: QDKrSREP[QDKrSREu, 0] = 1 QDKrSREP[QDKrSREu, QDKrSREU - 1] = 1 for QDKrSREI in QDKrSREl: QDKrSREP[0, QDKrSREI] = 1 QDKrSREP[QDKrSREg - 1, QDKrSREI] = 1 for QDKrSREV in QDKrSREs: if not QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)): continue else: QDKrSREh = QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)) QDKrSREb = True if len(QDKrSREh) < len(QDKrSREa): QDKrSREa = QDKrSREh QDKrSREt.goal_x = QDKrSREV.x QDKrSREt.goal_y = QDKrSREV.y for QDKrSREf, snake in enumerate(game.snakes): if not snake.body: continue if QDKrSREf == snake_idx: continue else: QDKrSREn = snake QDKrSREC = QDKrSREn.body QDKrSREF = QDKrSREC[0].x QDKrSREL = QDKrSREC[0].y if not QDKrSREt.astar( QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREt.calculate_next_move( QDKrSREF, QDKrSREL, QDKrSREt.last_enemy_head_coord_x, QDKrSREt.last_enemy_head_coord_y))): continue else: if not QDKrSREt.astar( QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREt.calculate_next_move( QDKrSREF, QDKrSREL, QDKrSREt.last_enemy_head_coord_x, QDKrSREt.last_enemy_head_coord_y))): continue else: if len(QDKrSREm) > len(QDKrSREC) + 1: QDKrSREh = QDKrSREt.astar( QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREt.calculate_next_move( QDKrSREF, QDKrSREL, QDKrSREt.last_enemy_head_coord_x, QDKrSREt.last_enemy_head_coord_y))) if len(QDKrSREh) < len(QDKrSREa): print('ATTACKING!') QDKrSREa = QDKrSREh QDKrSREt.goal_x = QDKrSREF QDKrSREt.goal_y = QDKrSREL QDKrSREk = [n for n in range(100)] QDKrSREP[QDKrSREt.goal_x, QDKrSREt.goal_y] = 9 QDKrSREB = 0 if QDKrSREa != [n for n in range(100)]: for QDKrSREV in QDKrSREs: for QDKrSREO in QDKrSREa: QDKrSREP[QDKrSREO[0], QDKrSREO[1]] = 1 if QDKrSREV.x == QDKrSREt.goal_x and QDKrSREV.y == QDKrSREt.goal_y: QDKrSREB += 0 else: if QDKrSREt.astar(QDKrSREP, (QDKrSREt.goal_x, QDKrSREt.goal_y), (QDKrSREV.x, QDKrSREV.y)) == []: QDKrSREB += 0 else: if QDKrSREt.astar(QDKrSREP, (QDKrSREt.goal_x, QDKrSREt.goal_y), (QDKrSREV.x, QDKrSREV.y)) == False: QDKrSREB += 0 if QDKrSREt.astar( QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)) != False: QDKrSREh = QDKrSREt.astar( QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)) if len(QDKrSREh) < len(QDKrSREk): QDKrSREk = QDKrSREh else: continue else: QDKrSREB += 1 for QDKrSREO in QDKrSREa: QDKrSREP[QDKrSREO[0], QDKrSREO[1]] = 2 QDKrSREP[QDKrSREt.goal_x, QDKrSREt.goal_y] = 9 if QDKrSREB == 0: if QDKrSREk != [n for n in range(100)]: QDKrSREa = QDKrSREk QDKrSREB += 1 if QDKrSREB == 0: for QDKrSREu in QDKrSREw: QDKrSREP[QDKrSREu, 0] = 0 QDKrSREP[QDKrSREu, QDKrSREU - 1] = 0 for QDKrSREI in QDKrSREl: QDKrSREP[0, QDKrSREI] = 0 QDKrSREP[QDKrSREg - 1, QDKrSREI] = 0 for QDKrSREA in QDKrSREm: QDKrSREP[QDKrSREA.x, QDKrSREA.y] = 1 if len(game.snakes) > 1: for QDKrSREH in QDKrSREC: QDKrSREP[QDKrSREH.x, QDKrSREH.y] = 1 for QDKrSREV in QDKrSREs: if QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)) == False: continue else: QDKrSREh = QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREV.x, QDKrSREV.y)) QDKrSREb = True if len(QDKrSREh) < len(QDKrSREa): QDKrSREa = QDKrSREh QDKrSREt.goal_x = QDKrSREV.x QDKrSREt.goal_y = QDKrSREV.y if QDKrSREa == [n for n in range(100)]: QDKrSREP[QDKrSREo, QDKrSREW] = 0 if QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREo, QDKrSREW)) == False: print('Cant find tail!') else: QDKrSREh = QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREo, QDKrSREW)) if len(QDKrSREh) > 1: QDKrSREa = QDKrSREh print('Chasing tail!') QDKrSREP[QDKrSREo, QDKrSREW] = 1 if QDKrSREa == [n for n in range(100)]: QDKrSREa = [] if QDKrSREa == []: for QDKrSREI in QDKrSREl: for QDKrSREu in QDKrSREw: QDKrSREq = QDKrSREt.astar(QDKrSREP, (QDKrSREz, QDKrSREG), (QDKrSREu, QDKrSREI)) if QDKrSREq != False and QDKrSREq != []: print('found') if len(QDKrSREq) > len(QDKrSREa): QDKrSREa = QDKrSREq print('PATH:', QDKrSREa) for QDKrSREf, snake in enumerate(game.snakes): if not snake.body: continue if QDKrSREf == snake_idx: continue else: QDKrSREt.last_enemy_head_coord_x = QDKrSREF QDKrSREt.last_enemy_head_coord_y = QDKrSREL if QDKrSREa != []: QDKrSRtE = QDKrSREa[-1] QDKrSRtC = QDKrSRtE[0] QDKrSRte = QDKrSRtE[1] QDKrSREe = QDKrSREt.calculate_direction(QDKrSRtC, QDKrSRte, QDKrSREz, QDKrSREG) else: print() print('DEAD!') print() return QDKrSREe
def create_experiment_2(overwrite: bool = True, show: bool = True): """ Experiment 2 tests the generalization capabilities of the genomes based on their initial distance from the target. TRAINING Training is done in a maze where the robot is in the center, and the targets are positioned around the agent. Each run has a single target sampled. The targets all are positioned 6 meters from the robot's initial position. TESTING Testing is done similar as was the case for training. For testing, half of the training's initial target- orientations are used (18 instead of 36). However, each orientation now has two targets, both with a different initial position from the robot's starting position. An inner-ring has distance 4, where the outer-ring has a distance of 8. """ cfg = get_shared_config() # Fixed parameters ROBOT_INIT_ANGLE = pi / 2 # Looking up ROBOT_INIT_POS = Vec2d(cfg.game.x_axis / 2, cfg.game.y_axis / 2) # Initial position of the drone # Create the training game spawn_f_train = SpawnSimple(game_config=cfg, train=True) for i in range(0, 360, 10): # Positions circular in hops of 10 degree angle = i / 180 * pi offset_x = 6 * cos(angle) offset_y = 6 * sin(angle) spawn_f_train.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(0, experiment_id=2), overwrite=overwrite, spawn_func=spawn_f_train, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show) # Create the inner circle of the evaluation games, each of those only contains one target for i in range(1, 19): spawn_f_eval = SpawnSimple(game_config=cfg, train=False) angle = i / 9 * pi # Hops of 20° offset_x = 4 * cos(angle) offset_y = 4 * sin(angle) spawn_f_eval.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(i, experiment_id=2), overwrite=overwrite, spawn_func=spawn_f_eval, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show, randomize=False) # Create the outer circle of the evaluation games, each of those only contains one target for i in range(1, 19): spawn_f_eval = SpawnSimple(game_config=cfg, train=False) angle = i / 9 * pi # Hops of 20° offset_x = 8 * cos(angle) offset_y = 8 * sin(angle) spawn_f_eval.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(i + 100, experiment_id=2), overwrite=overwrite, spawn_func=spawn_f_eval, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show, randomize=False)
def a_star_search(game: Game, start_field: Position, start_direction: Direction, search_field: Position, grid_map: GridMap) -> Tuple[int, List[any]]: queue = KLPriorityQueue() came_from = {} cost_so_far = {} path = [] # Initialisierung g = 0 start_field_h = math.sqrt((search_field.x - start_field.x) ** 2 + (search_field.y - start_field.y) ** 2) start_field_f = g + start_field_h queue.put(start_field_f, start_field) cost_so_far[start_field] = g # print('=== Position of Start [%d, %d], Determination [%d, %d], Directopn of head: %s ===' # % (start_field.x, start_field.y, search_field.x, search_field.y, start_direction)) # Schleife while not queue.empty(): # liefert field mit wenigster F-Kosten field = queue.get() # print('Field with lowest f-cost [%d, %d]' % (field.x, field.y)) if field.same_position(search_field): break # print('Not arrive the determination [%d, %d]' % (search_field.x, search_field.y)) all_neighbors = grid_map.get_neighbors(field.x, field.y) neighbors = [] if field.same_position(start_field): if start_direction == Direction.DOWN: for neighbor in all_neighbors: if game.is_obstacle(neighbor): continue if neighbor.y < start_field.y: continue for next_n in grid_map.get_neighbors(neighbor.x, neighbor.y): if game.is_obstacle(next_n): continue neighbors.append(neighbor) if start_direction == Direction.UP: for neighbor in all_neighbors: if game.is_obstacle(neighbor): continue if neighbor.y > start_field.y: continue for next_n in grid_map.get_neighbors(neighbor.x, neighbor.y): if game.is_obstacle(next_n): continue neighbors.append(neighbor) if start_direction == Direction.LEFT: for neighbor in all_neighbors: if game.is_obstacle(neighbor): continue if neighbor.x > start_field.x: continue for next_n in grid_map.get_neighbors(neighbor.x, neighbor.y): if game.is_obstacle(next_n): continue neighbors.append(neighbor) if start_direction == Direction.RIGHT: for neighbor in all_neighbors: if game.is_obstacle(neighbor): continue if neighbor.x < start_field.x: continue for next_n in grid_map.get_neighbors(neighbor.x, neighbor.y): if game.is_obstacle(next_n): continue # if next_n not in game.get_walls(): neighbors.append(neighbor) # mögliche Nachbarn von start_field untersuchen for neighbor in neighbors: if game.is_obstacle(neighbor): continue if neighbor not in cost_so_far.keys(): # print('Add new position in {cost_so_far}: [%d, %d]' % (neighbor.x, neighbor.y)) cost_so_far[neighbor] = 10000000 g = cost_so_far[start_field] + 1 if g < cost_so_far[neighbor]: cost_so_far[neighbor] = g # print('Update g-cost to [%d] in position: [%d, %d]' % (g, neighbor.x, neighbor.y)) h = math.sqrt((search_field.x - neighbor.x) ** 2 + (search_field.y - neighbor.y) ** 2) f = g + h queue.put(f, neighbor) # print('Add neighbor (%d, %d) in queue with f = %f' % (neighbor.x, neighbor.y, f)) came_from[neighbor] = start_field # print('came_from[neighbor(%d, %d)] = start_field(%d, %d)' # % (neighbor.x, neighbor.y, start_field.x, start_field.y)) else: for neighbor in all_neighbors: if game.is_obstacle(neighbor): continue if neighbor not in cost_so_far.keys(): cost_so_far[neighbor] = 10000000 # print('Add new position in {cost_so_far}: [%d, %d]' % (neighbor.x, neighbor.y)) g = cost_so_far[field] + 1 if g < cost_so_far[neighbor]: cost_so_far[neighbor] = g # print('Update g-cost to [%d] in position: [%d, %d]' % (g, neighbor.x, neighbor.y)) h = math.sqrt((search_field.x - neighbor.x) ** 2 + (search_field.y - neighbor.y) ** 2) f = g + h queue.put(f, neighbor) # print('Add neighbor (%d, %d) in queue with f = %f' % (neighbor.x, neighbor.y, f)) came_from[neighbor] = field # print('came_from[neighbor(%d, %d)] = field(%d, %d)' # % (neighbor.x, neighbor.y, field.x, field.y)) # Berechnung des Pfades path.append(search_field) field = came_from[search_field] # print('search_field comes from [%d, %d]' % (field.x, field.y)) while not field.same_position(start_field): pre_field = came_from[field] # print('field (%d, %d) comes from pre_field (%d, %d)' % (field.x, field.y, pre_field.x, pre_field.y)) path.append(field) field = pre_field cost = cost_so_far[search_field] path = path[::-1] for i in range(len(path)): field = path[i] # print('path-%d at field [%d, %d]' % (i, field.x, field.y)) return cost, path
def create_experiment_6(overwrite: bool = True, show: bool = True): """ Experiment 6 is another 'simplified' simulation in which the agents are trained on a harder environment than they are tested on. The reason why is to keep a lower threshold for the 'solution' genomes (only interested in those). TRAINING During training, new targets are spawned based on the agent's initial position. Each target will lay between 2 and 10 meters from the agent and will always be positioned inside of the maze. TESTING Testing is done on 18 predefined targets position in a relative angle from the agent of k*20° and a distance of either 4, 6, or 8 meters (sequential alternating). """ cfg = get_shared_config() # Fixed parameters ROBOT_INIT_ANGLE = pi / 2 # Looking up ROBOT_INIT_POS = Vec2d(cfg.game.x_axis / 2, cfg.game.y_axis / 2) # Initial position of the drone # Create the training game spawn_f_train = SpawnRange(game_config=cfg.game, train=True, r_max=8, r_min=4) game = Game( config=cfg, player_noise=0, game_id=get_game_id(0, experiment_id=6), overwrite=overwrite, spawn_func=spawn_f_train, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show) # Create 18 evaluation games for i in range(1, 19): spawn_f_eval = SpawnSimple(game_config=cfg.game, train=False) angle = i / 9 * pi # Hops of 20° d = 4 if i % 3 == 0 else 6 if i % 3 == 1 else 8 offset_x = d * cos(angle) offset_y = d * sin(angle) spawn_f_eval.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(i, experiment_id=6), overwrite=overwrite, spawn_func=spawn_f_eval, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show, randomize=False)
def Te(T, game: Game, snake_idx: Tu): G = [] I = TW for Y, snake in Tb(game.snakes): if not snake.body: continue if Y == snake_idx: e = snake else: f = snake G = f.body S = G[0].x J = G[0].y P = e.body N = P[0].x L = P[0].y C = P[-1].x a = P[-1].x H = game.width k = game.height w = game.get_fruits() v = H * 2 + k * 2 for f in w: u = f.x W = f.y b = TX(L - W) + TX(N - u) if b < v: v = b X = f.x x = f.y o = 0 for f in w: u = f.x W = f.y b = TX(L - W) + TX(N - u) for Y, snake in Tb(game.snakes): if not snake.body: continue if Y == snake_idx: continue else: f = snake G = f.body S = G[0].x J = G[0].y B = TX(J - x) + TX(S - X) if B <= b: o += 0 continue else: b = TX(L - W) + TX(N - u) o += 1 if b < v: v = b X = f.x x = f.y if o == 0: for f in w: u = f.x W = f.y b = TX(L - W) + TX(N - u) if b < v: v = b X = f.x x = f.y s = Tw((H, k)) R = [n for n in Tx(100)] for s in P: s[s.x, s.y] = 1 if To(game.snakes) > 1: for e in G: s[e.x, e.y] = 1 for Y, snake in Tb(game.snakes): if not snake.body: continue if Y == snake_idx: continue else: f = snake G = f.body S = G[0].x J = G[0].y for e in G: s[e.x, e.y] = 1 if To(G) >= To(P): for f in w: if T.TJ(s, (S, J), (f.x, f.y)) == TB: continue else: i = T.TJ(s, (S, J), (f.x, f.y)) if To(i) <= 3: if To(i) < To(R): R = i z = R[-1] V = z[0] E = z[1] s[V, E] = 1 M = [n for n in Tx(100)] y = [width for width in Tx(H)] p = [height for height in Tx(k)] for w in y: s[w, 0] = 1 s[w, k - 1] = 1 for h in p: s[0, h] = 1 s[H - 1, h] = 1 for f in w: if T.TJ(s, (N, L), (f.x, f.y)) == TB: continue else: n = T.TJ(s, (N, L), (f.x, f.y)) m = Ts if To(n) < To(M): M = n T.goal_x = f.x T.goal_y = f.y for Y, snake in Tb(game.snakes): if not snake.body: continue if Y == snake_idx: continue else: f = snake G = f.body S = G[0].x J = G[0].y if T.TJ(s, (N, L), (T.TN(S, J, T.last_enemy_head_coord_x, T.last_enemy_head_coord_y))) == TB: continue else: if T.TJ(s, (N, L), (T.TN(S, J, T.last_enemy_head_coord_x, T.last_enemy_head_coord_y))) == []: continue else: if To(P) > To(G) + 1: n = T.TJ(s, (N, L), (T.TN(S, J, T.last_enemy_head_coord_x, T.last_enemy_head_coord_y))) if To(n) < To(M): TR('ATTACKING!') M = n T.goal_x = S T.goal_y = J r = [n for n in Tx(100)] s[T.goal_x, T.goal_y] = 9 U = 0 if M != [n for n in Tx(100)]: for f in w: for p in M: s[p[0], p[1]] = 1 if f.x == T.goal_x and f.y == T.goal_y: U += 0 else: if T.TJ(s, (T.goal_x, T.goal_y), (f.x, f.y)) == []: U += 0 else: if T.TJ(s, (T.goal_x, T.goal_y), (f.x, f.y)) == TB: U += 0 if T.TJ(s, (N, L), (f.x, f.y)) != TB: n = T.TJ(s, (N, L), (f.x, f.y)) if To(n) < To(r): r = n else: continue else: U += 1 for p in M: s[p[0], p[1]] = 2 s[T.goal_x, T.goal_y] = 9 if U == 0: if r != [n for n in Tx(100)]: M = r U += 1 if U == 0: for w in y: s[w, 0] = 0 s[w, k - 1] = 0 for h in p: s[0, h] = 0 s[H - 1, h] = 0 for s in P: s[s.x, s.y] = 1 if To(game.snakes) > 1: for e in G: s[e.x, e.y] = 1 for f in w: if T.TJ(s, (N, L), (f.x, f.y)) == TB: continue else: n = T.TJ(s, (N, L), (f.x, f.y)) m = Ts if To(n) < To(M): M = n T.goal_x = f.x T.goal_y = f.y if M == [n for n in Tx(100)]: s[C, a] = 0 if T.TJ(s, (N, L), (C, a)) == TB: TR('Cant find tail!') else: n = T.TJ(s, (N, L), (C, a)) if To(n) > 1: M = n TR('Chasing tail!') s[C, a] = 1 if M == [n for n in Tx(100)]: M = [] if M == []: for h in p: for w in y: c = T.TJ(s, (N, L), (w, h)) if c != TB and c != []: TR('found') if To(c) > To(M): M = c TR('PATH:', M) for Y, snake in Tb(game.snakes): if not snake.body: continue if Y == snake_idx: continue else: T.last_enemy_head_coord_x = S T.last_enemy_head_coord_y = J if M != []: j = M[-1] d = j[0] A = j[1] I = T.TP(d, A, N, L) else: TR() TR('DEAD!') TR() return I
def create_experiment_1(overwrite: bool = True, show: bool = True): """ Experiment 1 tests the generalization capabilities of the genomes based on the relative direction the target is placed. TRAINING Training is done in a maze where the robot is in the center, and the targets are positioned around the agent. Each run has a single target sampled. The targets all are positioned 6 meters from the robot's initial position. TESTING Testing is done similar as was the case for training, however, in this scenario only 20 targets are sampled (where there were 36 for training). Only 4 of these 20 sampled target positions overlap with the training set. """ cfg = get_shared_config() # Fixed parameters ROBOT_INIT_ANGLE = pi / 2 # Looking up ROBOT_INIT_POS = Vec2d(cfg.game.x_axis / 2, cfg.game.y_axis / 2) # Initial position of the drone # Create the training game spawn_f_train = SpawnSimple(game_config=cfg, train=True) for i in range(0, 360, 10): # Positions circular in hops of 10 degree angle = i / 180 * pi offset_x = 6 * cos(angle) offset_y = 6 * sin(angle) spawn_f_train.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(0, experiment_id=1), overwrite=overwrite, spawn_func=spawn_f_train, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show) # Create the evaluation games, each of those only contains one target for i in range(1, 21): spawn_f_eval = SpawnSimple(game_config=cfg, train=False) angle = i / 10 * pi offset_x = 6 * cos(angle) offset_y = 6 * sin(angle) spawn_f_eval.add_location( (ROBOT_INIT_POS[0] + offset_x, ROBOT_INIT_POS[1] + offset_y)) game = Game( config=cfg, player_noise=0, game_id=get_game_id(i, experiment_id=1), overwrite=overwrite, spawn_func=spawn_f_eval, stop_if_reached=True, wall_bound=False, ) game.player = Robot(game=game) game.set_player_init_angle(a=ROBOT_INIT_ANGLE) game.set_player_init_pos(p=ROBOT_INIT_POS) check_and_save_game(game, show=show, randomize=False)
move = random.choice(grid.available_moves) return self._traverse_from( grid.grid_after_move(current_color, move), Color(1 - current_color)) def _rollout_from(self, grid: Grid, color: Color, last_col: Union[int, None] = None) -> bool: if len(grid.available_moves) == 0 or (last_col is None and self._judge.is_over(grid.state)) or \ (last_col is not None and self._judge.is_over_after_move_in_col(grid.state, last_col)): return color != self._color move = random.choice(grid.available_moves) has_won = self._rollout_from(grid.grid_after_move(color, move), Color(1 - color), move) return has_won def _finishing_move_in(self, grid: Grid) -> Union[int, None]: for move in grid.available_moves: after_move = grid.grid_after_move(self._color, move) if self._judge.is_over_after_move_in_col(after_move.state, move): return move if __name__ == '__main__': game = Game(Grid(), Judge(), MCTSPlayer(Color.RED, Judge(), 2, 1000), MCTSPlayer(Color.BLACK, Judge(), 5, 1000)) print(game.play())