def agent(obs, conf): global directions obs = Observation(obs) conf = Configuration(conf) board = np.zeros((7, 11), dtype=int) #Obstacle-ize your opponents for ind, goose in enumerate(obs.geese): if ind == obs.index or len(goose) == 0: continue for direction in range(4): moved = move(goose, direction) for part in moved: board[part//11][part%11] -= 1 #Obstacle-ize your body, except the last part if len(obs.geese[obs.index]) > 1: for k in obs.geese[obs.index][:-1]: board[k//11][k%11] -= 1 #Count food only if there's no chance an opponent will meet you there for f in obs.food: board[f//11][f%11] += (board[f//11][f%11] == 0) return directions[greedy_choose(obs.geese[obs.index][0], board)]
def rule_based_action(self, player): from kaggle_environments.envs.hungry_geese.hungry_geese import ( Observation, Configuration, Action, GreedyAgent, ) action_map = { "N": Action.NORTH, "S": Action.SOUTH, "W": Action.WEST, "E": Action.EAST, } agent = GreedyAgent(Configuration({"rows": 7, "columns": 11})) agent.last_action = ( action_map[self.ACTION[self.last_actions[player]][0]] if player in self.last_actions else None ) obs = { **self.obs_list[-1][0]["observation"], **self.obs_list[-1][player]["observation"], } action = agent(Observation(obs)) return self.ACTION.index(action)
def process_state(self, obs_dict, config_dict): observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index b_state={ 'blank': 0, # Empty cell 'x': -1, # Head of opponent player 'h': 1, # Head of current player 'b': -2, # Body cell 'f': 2, # Food } # строим доску board = b_state['blank'] * np.zeros(N_CELL).astype(int).reshape((N_ROWS, N_COLS)) # гуси geese = observation.geese for goose in geese: for i, cell in enumerate(goose): row, col = row_col(cell, configuration.columns) board[row][col] = b_state['b'] for i in range(len(geese)): if(len(geese[i]) <= 0): continue head_row, head_col = row_col(geese[i][0], configuration.columns) if player_index == i: board[head_row][head_col] = b_state['h'] else: board[head_row][head_col] = b_state['x'] # food foods = observation.food for food in foods: food_row, food_col = row_col(food, configuration.columns) board[food_row][food_col] = b_state['f'] board = self.centroid_agent(board, geese[player_index][0], configuration) return board
def local(self, observation, configuration): observation = observation if isinstance( observation, Observation) else Observation(observation) player = self._world.player(observation.index) actionsMask, actionsMapping = player.validMoves() return player.raw, actionsMask, actionsMapping
def agent(obs_dict, config_dict): global ralph_last_action #np.set_printoptions(precision=2) observation = Observation(obs_dict) configuration = Configuration(config_dict) astar = AStar(observation, configuration) path = astar.search() choice = "WEST" if (path is not None): cam = [] if (len(path.caminho) > 1): cam = path.caminho[1] else: cam = path.next_p choice = get_choice(cam, astar.start, astar.rows, astar.cols) print(choice) '''for line in astar.heu_map: print(line)''' else: if (ralph_last_action[observation.index] is not None): choice = opposite( get_choice(ralph_last_action[observation.index], astar.start, astar.rows, astar.cols)) else: coice = "WEST" print() print() print() ralph_last_action[observation.index] = astar.start return choice
def getNextBoard(self, actions): self.prev_actions = actions obs, _, done, info = self.env.step(actions) obs = Observation(obs) reward = self.getReward(obs) if done else None board = self.getBoard(obs, 0) return board, reward, done, info
def rule_based_action(self, player): from kaggle_environments.envs.hungry_geese.hungry_geese import Observation, Configuration, Action, GreedyAgent action_map = {'N': Action.NORTH, 'S': Action.SOUTH, 'W': Action.WEST, 'E': Action.EAST} agent = GreedyAgent(Configuration({'rows': 7, 'columns': 11})) agent.last_action = action_map[self.ACTION[self.last_actions[player]][0]] if player in self.last_actions else None obs = {**self.obs_list[-1][0]['observation'], **self.obs_list[-1][player]['observation']} action = agent(Observation(obs)) return self.ACTION.index(action)
def agent(obs_dict, config_dict): observation = Observation(obs_dict) player_index = observation.index geese = observation.geese food = observation.food step = observation.step current_node = Node(geese=geese, food=food, step=step, max_depth=4) return manager(current_node=current_node, max_time=.25, player_index=player_index)
def agent(observation, configuration): observation = Observation(observation) configuration = Configuration(configuration) rows, columns = configuration.rows, configuration.columns food = observation.food geese = observation.geese opponents = [ goose for index, goose in enumerate(geese) if index != observation.index and len(goose) > 0 ] # Don't move adjacent to any heads head_adjacent_positions = { opponent_head_adjacent for opponent in opponents for opponent_head in [opponent[0]] for opponent_head_adjacent in adjacent_positions(opponent_head, rows, columns) } # Don't move into any bodies bodies = {position for goose in geese for position in goose[0:-1]} # Don't move into tails of heads that are adjacent to food tails = { opponent[-1] for opponent in opponents for opponent_head in [opponent[0]] if any( adjacent_position in food # Head of opponent is adjacent to food so tail is not safe for adjacent_position in adjacent_positions(opponent_head, rows, columns) ) } # Move to the closest food position = geese[observation.index][0] actions = { action: min_distance(new_position, food, columns) for action in Action for new_position in [translate(position, action, columns, rows)] if ( new_position not in head_adjacent_positions and new_position not in bodies and new_position not in tails ) } if any(actions): return min(actions, key=actions.get).name return random_agent()
def encodedStates(): for env, world in zip(environments, worlds): if not env.done: world.update(Observation(env.state[0]['observation'])) states = [] observations = [] for env, agents in EA: for obs, agent in zip(env.state, agents): state = agent.processObservations(obs['observation'], env.configuration, obs['alive']) states.append(state) observations.append(obs) return states, observations
def agent_ORIGINAL(obs_dict, config_dict): """This agent always moves toward observation.food[0] but does not take advantage of board wrapping""" observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) food = observation.food[0] food_row, food_column = row_col(food, configuration.columns) if food_row > player_row: return Action.SOUTH.name if food_row < player_row: return Action.NORTH.name if food_column > player_column: return Action.EAST.name return Action.WEST.name
def processObservations(self, obs_dict, config_dict, alive=True): if not alive: return self._state.EmptyObservations observation = Observation(obs_dict) configuration = Configuration(config_dict) if self._agent is None: self._agent = GreedyAgent(configuration) state, validAct, actionsMapping = self._state.local(observation, configuration) self._agent.last_action = Action[self._prevAction] # sync self._actName = self._agent(observation) if self._actName not in actionsMapping: self._actName = next( (act for i, act in enumerate(actionsMapping) if 0 < validAct[i]), actionsMapping[1] ) self._actID = actionsMapping.index(self._actName) return state
def agent(obs_dict, config_dict): global ralph_last_action observation = Observation(obs_dict) configuration = Configuration(config_dict) #print("Player") # Define my player player_index = observation.index my_goose = Goose(observation.geese[player_index], configuration) player_row, player_column = my_goose.get_head_pos() #print("Enemies") # Define the enemies players enemies_indexes = [] for i in range(0, len(observation.geese)): if i != player_index: enemies_indexes.append(i) enemies_geese = [] for enemy in enemies_indexes: enemies_geese.append(Goose(observation.geese[enemy], configuration)) #print("Food") # Get the nearest food position food_row, food_column = get_min_distance_food_pos(my_goose.get_head(), observation.food, configuration.columns) #print("Possible Moves") # List the possible moves possible_moves = ['SOUTH', 'NORTH', 'WEST', 'EAST'] if (ralph_last_action[player_index] in possible_moves): possible_moves.remove(ralph_last_action[player_index]) #print("Possible Moves and colisions") moves = [] for i in range(0, len(possible_moves)): move = possible_moves[i] n_r, n_c = my_goose.get_next_position(move) if (not is_any_enemy_there(enemies_geese, n_r, n_c) and not my_goose.am_i_there(n_r, n_c) and not will_be_any_enemy_there(enemies_geese, n_r, n_c)): moves.append(move) #print("Possible Moves by food") # From the remaining possible moves, wich one get me nearest to the food? min_food_move = 0 if (len(moves) > 0): for i in range(0, len(moves)): n_r1, n_c1 = my_goose.get_next_position(moves[i]) n_r2, n_c2 = my_goose.get_next_position(moves[min_food_move]) if (get_distance(food_row, food_column, n_r1, n_c1) < get_distance( food_row, food_column, n_r2, n_c2)): min_food_move = i #print("Select Move") if (len(moves) > 0 and min_food_move is not None): return_action = moves[min_food_move] else: return_action = 'NORTH' #print("Last Move") # Refresh the last move ralph_last_action[player_index] = opposite(return_action) #print(return_action) #print() return return_action
def get_init_obs(self): return Observation(self.env.reset(self.num_agents))
def preprocess_env(self, observation, configuration): observation = Observation(observation) configuration = Configuration(configuration) self.rows, self.columns = configuration.rows, configuration.columns self.my_index = observation.index self.hunger_rate = configuration.hunger_rate self.min_food = configuration.min_food self.my_head, self.my_tail = observation.geese[ self.my_index][0], observation.geese[self.my_index][-1] self.my_body = [pos for pos in observation.geese[self.my_index][1:-1]] self.geese = [ g for i, g in enumerate(observation.geese) if i != self.my_index and len(g) > 0 ] self.geese_cells = [pos for g in self.geese for pos in g if len(g) > 0] self.occupied = [p for p in self.geese_cells] self.occupied.extend([p for p in observation.geese[self.my_index]]) self.heads = [ g[0] for i, g in enumerate(observation.geese) if i != self.my_index and len(g) > 0 ] self.bodies = [ pos for i, g in enumerate(observation.geese) for pos in g[1:-1] if i != self.my_index and len(g) > 2 ] self.tails = [ g[-1] for i, g in enumerate(observation.geese) if i != self.my_index and len(g) > 1 ] self.food = [f for f in observation.food] self.adjacent_to_heads = [ pos for head in self.heads for pos in self._adjacent_positions(head) ] self.adjacent_to_bodies = [ pos for body in self.bodies for pos in self._adjacent_positions(body) ] self.adjacent_to_tails = [ pos for tail in self.tails for pos in self._adjacent_positions(tail) ] self.adjacent_to_geese = self.adjacent_to_heads + self.adjacent_to_bodies self.danger_zone = self.adjacent_to_geese #Cell occupation self.cell_states = [ CellState.EMPTY.value for _ in range(self.rows * self.columns) ] for g in self.geese: for pos in g: self.cell_states[pos] = CellState.GOOSE.value for pos in self.heads: self.cell_states[pos] = CellState.GOOSE.value for pos in self.my_body: self.cell_states[pos] = CellState.GOOSE.value #detect dead-ends self.dead_ends = [] for pos_i, _ in enumerate(self.cell_states): if self.cell_states[pos_i] != CellState.EMPTY.value: continue adjacent = self._adjacent_positions(pos_i) adjacent_states = [ self.cell_states[adj_pos] for adj_pos in adjacent if adj_pos != self.my_head ] num_blocked = sum(adjacent_states) if num_blocked >= (CellState.GOOSE.value * 3): self.dead_ends.append(pos_i) #check for extended dead-ends new_dead_ends = [pos for pos in self.dead_ends] while new_dead_ends != []: for pos in new_dead_ends: self.cell_states[pos] = CellState.GOOSE.value self.dead_ends.append(pos) new_dead_ends = [] for pos_i, _ in enumerate(self.cell_states): if self.cell_states[pos_i] != CellState.EMPTY.value: continue adjacent = self._adjacent_positions(pos_i) adjacent_states = [ self.cell_states[adj_pos] for adj_pos in adjacent if adj_pos != self.my_head ] num_blocked = sum(adjacent_states) if num_blocked >= (CellState.GOOSE.value * 3): new_dead_ends.append(pos_i)
def straightforward_bfs(obs_dict, config_dict): observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] start_row, start_col = row_col(player_head, configuration.columns) mask = np.zeros((configuration.rows, configuration.columns)) for current_id in range(4): current_goose = observation.geese[current_id] for block in current_goose: current_row, current_col = row_col(block, configuration.columns) mask[current_row, current_col] = -1 food_coords = [] for food_id in range(configuration.min_food): food = observation.food[food_id] current_row, current_col = row_col(food, configuration.columns) mask[current_row, current_col] = 2 food_coords.append((current_row, current_col)) last_action = bfs(start_row, start_col, mask, food_coords) global LAST_ACTION up_x = start_row + 1 if start_row != 6 else 0 down_x = start_row - 1 if start_row != 0 else 6 left_y = start_col - 1 if start_col != 0 else 10 right_y = start_col + 1 if start_col != 10 else 0 step = Action.NORTH.name if last_action == 0: step = Action.SOUTH.name if LAST_ACTION == Action.NORTH.name: if mask[down_x, start_col] != -1: step = Action.NORTH.name elif mask[start_row, left_y] != -1: step = Action.WEST.name elif mask[start_row, right_y] != -1: step = Action.EAST.name if last_action == 1: step = Action.NORTH.name if LAST_ACTION == Action.SOUTH.name: if mask[up_x, start_col] != -1: step = Action.SOUTH.name elif mask[start_row, left_y] != -1: step = Action.WEST.name elif mask[start_row, right_y] != -1: step = Action.EAST.name if last_action == 2: step = Action.WEST.name if LAST_ACTION == Action.EAST.name: if mask[up_x, start_col] != -1: step = Action.SOUTH.name elif mask[down_x, start_col] != -1: step = Action.NORTH.name elif mask[start_row, right_y] != -1: step = Action.EAST.name if last_action == 3: step = Action.EAST.name if LAST_ACTION == Action.WEST.name: if mask[up_x, start_col] != -1: step = Action.SOUTH.name elif mask[down_x, start_col] != -1: step = Action.NORTH.name elif mask[start_row, left_y] != -1: step = Action.WEST.name LAST_ACTION = step return step
def agent(obs_dict, config_dict): global last_move global last_eaten global last_size global step #print ("==============================================") observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) if (len(player_goose) > last_size): last_size = len(player_goose) last_eaten = step step += 1 moves = {1: 'SOUTH', 2: 'NORTH', 3: 'EAST', 4: 'WEST'} board = np.zeros((7, 11)) # Adding food to board for food in observation.food: x, y = row_col(food, configuration.columns) #print ("Food cell on ({}, {})".format(x, y)) board[x, y] = FOOD_CELL # Adding geese to the board for i in range(4): goose = observation.geese[i] # Skip if goose is dead if len(goose) == 0: continue # If it's an opponent if i != player_index: x, y = row_col(goose[0], configuration.columns) # Add possible head movements for it for px, py in get_nearest_cells(x, y): #print ("Head possible cell on ({}, {})".format(px, py)) # If one of these head movements may lead the goose # to eat, add tail as BODY_CELL, because it won't move. if board[px, py] == FOOD_CELL: x_tail, y_tail = row_col(goose[-1], configuration.columns) #print ("Adding tail on ({}, {}) as the goose may eat".format(x_tail, y_tail)) board[x_tail, y_tail] = BODY_CELL board[px, py] = HEAD_POSSIBLE_CELL # Adds goose body without tail (tail is previously added only if goose may eat) for n in goose[:-1]: x, y = row_col(n, configuration.columns) #print ("Body cell on ({}, {})".format(x, y)) board[x, y] = BODY_CELL # Adding my head to the board x, y = row_col(player_head, configuration.columns) #print ("My head is at ({}, {})".format(x, y)) board[x, y] = MY_HEAD # Debug board #print (board) # Iterate over food and geese in order to compute distances for each one food_race = {} for food in observation.food: food_race[food] = {} for i in range(4): goose = observation.geese[i] if len(goose) == 0: continue food_race[food][i] = cell_distance(goose[0], food, configuration) # The best food is the least coveted best_food = None best_distance = float('inf') best_closest_geese = float('inf') for food in food_race: #print ("-> Food on {}".format(row_col(food, configuration.columns))) my_distance = food_race[food][player_index] #print (" - My distance is {}".format(my_distance)) closest_geese = 0 for goose_id in food_race[food]: if goose_id == player_index: continue if food_race[food][goose_id] <= my_distance: closest_geese += 1 #print (" - There are {} closest geese".format(closest_geese)) if (closest_geese < best_closest_geese): best_food = food best_distance = my_distance best_closest_geese = closest_geese #print (" * This food is better") elif (closest_geese == best_closest_geese) and (my_distance <= best_distance): best_food = food best_distance = my_distance best_closest_geese = closest_geese #print (" * This food is better") # Now that the best food has been found, check if the movement towards it is safe. # Computes every available move and then check for move priorities. if len(player_goose) > 1: food_movements = move_towards(player_head, player_goose[1], best_food, configuration) else: food_movements = move_towards(player_head, player_head, best_food, configuration) all_movements = get_all_movements(player_head, configuration) # Excluding last movement reverse food_movements = [ move for move in food_movements if move[2] != REVERSE_MOVE[last_move] ] all_movements = [ move for move in all_movements if move[2] != REVERSE_MOVE[last_move] ] #print ("-> Available food moves: {}".format(food_movements)) #print ("-> All moves: {}".format(all_movements)) # Trying to reach goal size of 4 if (len(player_goose) < 4): # 1. Food movements that are safe and not closed for food_movement in food_movements: #print ("Food movement {}".format(food_movement)) if is_safe(food_movement, board) and not is_closed(food_movement, board): #print ("It's safe! Let's move {}!".format(moves[food_movement[2]])) last_move = food_movement[2] return moves[food_movement[2]] # Move here # 2. Any movement safe and not closed for movement in all_movements: #print ("Movement {}".format(movement)) if is_safe(movement, board) and not is_closed(movement, board): #print ("It's safe! Let's move {}!".format(moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 3. Food movements half safe and not closed for food_movement in food_movements: if is_half_safe(food_movement, board) and not is_closed(food_movement, board): #print ("Food movement {} is half safe, I'm going {}!".format(food_movement, moves[food_movement[2]])) last_move = food_movement[2] return moves[food_movement[2]] # Move here # 4. Any movement half safe and not closed for movement in all_movements: if is_half_safe(movement, board) and not is_closed(movement, board): #print ("Movement {} is half safe, I'm going {}!".format(movement, moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 5. Food movements that are safe for food_movement in food_movements: #print ("Food movement {}".format(food_movement)) if is_safe(food_movement, board): #print ("It's safe! Let's move {}!".format(moves[food_movement[2]])) last_move = food_movement[2] return moves[food_movement[2]] # Move here # 6. Any movement safe for movement in all_movements: #print ("Movement {}".format(movement)) if is_safe(movement, board): #print ("It's safe! Let's move {}!".format(moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 7. Food movements half safe for food_movement in food_movements: if is_half_safe(food_movement, board): #print ("Food movement {} is half safe, I'm going {}!".format(food_movement, moves[food_movement[2]])) last_move = food_movement[2] return moves[food_movement[2]] # Move here # 8. Any movement half safe for movement in all_movements: if is_half_safe(movement, board): #print ("Movement {} is half safe, I'm going {}!".format(movement, moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # Just trying to walk in circles else: # Delete food moves food_coordinates = [] for food in food_race: x_food, y_food = row_col(food, configuration.columns) food_coordinates.append((x_food, y_food)) available_moves = [] for move in all_movements: for (x_food, y_food) in food_coordinates: if (move[0] != x_food) or (move[1] != y_food): available_moves.append(move) # 1. Run in circles if you can circle_move = CIRCLE_MOVE[last_move] for move in available_moves: if (move[2] == circle_move) and (is_safe( move, board)) and not (is_closed(move, board)): last_move = move[2] return moves[move[2]] # 2. Any movement safe and not closed for movement in all_movements: #print ("Movement {}".format(movement)) if is_safe(movement, board) and not is_closed(movement, board): #print ("It's safe! Let's move {}!".format(moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 3. Any movement half safe and not closed for movement in all_movements: if is_half_safe(movement, board) and not is_closed(movement, board): #print ("Movement {} is half safe, I'm going {}!".format(movement, moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 4. Any movement safe for movement in all_movements: #print ("Movement {}".format(movement)) if is_safe(movement, board): #print ("It's safe! Let's move {}!".format(moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # 5. Any movement half safe for movement in all_movements: if is_half_safe(movement, board): #print ("Movement {} is half safe, I'm going {}!".format(movement, moves[movement[2]])) last_move = movement[2] return moves[movement[2]] # Move here # Finally, if all moves are unsafe, randomly pick one rand_pick = np.random.randint(4) + 1 last_move = rand_pick #print ("Yeah whatever, I'm going {}".format(moves[rand_pick])) return moves[rand_pick]
def agent(obs_dict, config_dict): observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_tail = player_goose[-1] my_X, my_Y = row_col(player_head, configuration.columns) my_tail_X, my_tail_Y = row_col(player_tail, configuration.columns) mask = np.zeros((configuration.rows, configuration.columns)) global last_direction global iteration_number print("**iteration**: {}".format(iteration_number)) print("my head at {} - {}".format([my_X, my_Y], last_direction)) iteration_number+=1 food_location = [] available_steps = {} other_heads = [] # head of competitor geese body_cells = [] other_tails = [] last_direction_updated = False # add all directions possible_positions = get_nearest_cells(my_X, my_Y) for x, y in possible_positions: direct = '-' if((x-1 == my_X) or (x==0 and my_X==6)) and last_direction != 'NORTH': direct = 'SOUTH' elif((x+1 == my_X) or (x==6 and my_X==0)) and last_direction != 'SOUTH': direct = 'NORTH' elif((y-1 == my_Y) or (y==0 and my_Y==10)) and last_direction != 'WEST': direct = 'EAST' elif((y+1 == my_Y) or (y==10 and my_Y==0)) and last_direction != 'EAST': direct = 'WEST' if direct != '-': available_steps[(x,y)] = [direct,0] for food in observation.food: x,y = row_col(food, configuration.columns) mask[x, y] = 2 food_location.append([x,y]) print("food locations are {}".format(food_location)) # where other goose can come danger_area = {} for i in range(len(observation.geese)): opp_goose = observation.geese[i] if len(opp_goose) == 0: continue for ind, goose in enumerate(opp_goose): x, y = row_col(goose, configuration.columns) mask[x, y] = -1 # and mark the occupied cells if not head or tail of goose if ind != 0 and ind != len(opp_goose) - 1: body_cells.append([x,y]) if ind != 0 and ind == len(opp_goose) - 1: other_tails.append([x,y]) if (x, y) in available_steps.keys(): # let's remove all cells that are not available from available steps available_steps.pop((x,y)) if (x, y) in danger_area.keys(): # let's remove all cells that are not available from danger steps danger_area.pop((x,y)) if not len(available_steps) and not len(danger_area): #if steps is empty kill by NORTH direction print("kill") if player_head!=player_tail and (my_tail_X, my_tail_Y) in possible_positions: last_direction = get_direction((my_X, my_Y), (my_tail_X, my_tail_Y)) else: last_direction = 'NORTH' last_direction_updated = True break if last_direction_updated: break if i != player_index: x, y = row_col(opp_goose[0], configuration.columns) # add competition goose head other_heads.append([x, y]) possible_moves = get_nearest_cells(x, y) # head can move anywhere for [x, y] in possible_moves: if (x,y) in available_steps.keys() and [x,y] in food_location: danger_area[(x,y)] = available_steps[(x,y)] available_steps.pop((x, y)) #only safe moves food_location.remove([x,y]) #don't consider this food elif (x,y) in available_steps.keys() and len(available_steps)+len(danger_area) > 1: danger_area[(x,y)] = available_steps[(x,y)] available_steps.pop((x, y)) #only safe moves if last_direction_updated: break print("body cells are {}".format(body_cells)) print("available steps are {}".format(available_steps)) print("other heads at {}".format(other_heads)) print("other tails at {}".format(other_tails)) print("danger area at {}".format(danger_area)) my_head = [my_X, my_Y] if not last_direction_updated: last_direction = my_move(food_location, available_steps, other_heads, my_head, last_direction, body_cells, danger_area, mask, other_tails) last_direction_updated = True return last_direction
def encodeObservations(self, obs_dict, config_dict): observation = Observation(obs_dict) configuration = Configuration(config_dict) return self._state.local(observation, configuration)
def agent(obs_dict, config_dict): """This agent always moves toward observation.food[0] but does not take advantage of board wrapping""" observation = Observation(obs_dict) configuration = Configuration(config_dict) maze_col = configuration.columns maze_rows = configuration.rows maze = np.zeros([maze_rows, maze_col]) print("Player") # Define my player player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) start = (player_row, player_column) print(start) #Define Food hipotenuse_low = 14 closest_food = observation.food[0] for food in observation.food: food_row, food_column = row_col(food, configuration.columns) hipotenuse = sqrt((player_row - food_row)**2 + (player_column - food_column)**2) if hipotenuse < hipotenuse_low: hipotenuse_low = hipotenuse closest_food = food end = row_col(closest_food, configuration.columns) # Define the enemies players enemies_indexes = observation.geese del enemies_indexes[player_index] for enemies in enemies_indexes: for enemies_pos in enemies: enemie_row, enemie_col = row_col(enemies_pos, configuration.columns) maze[enemie_row, enemie_col] = 1 for player_pos in player_goose[1:]: player_rw, player_col = row_col(player_pos, configuration.columns) maze[player_rw, player_col] = 1 path = astar(maze, start, end, False) next_move = path[1] print(next_move) print(player_column) print(player_row) x = int(next_move[1]) - int(player_column) y = int(next_move[0]) - int(player_row) print(x, y) print(maze) if x == -1 and y == 0: print("WEST") return Action.WEST.name if x == 1 and y == 0: print("EAST") return Action.EAST.name if x == 0 and y == -1: print("NORTH") return Action.NORTH.name if x == 0 and y == 1: print("SOUTH") return Action.SOUTH.name
def agent(obs_dict, config_dict): global which_turn which_turn += 1 t0= time.clock() f = open("./myfile1.txt", "a") f.write("\n") f.write("Starting file" + "\n") observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] #player_goose is list of all bodypart positions player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) start = (player_row, player_column) f.write("Commencing turn: " + str(which_turn)) with open('./myfile2.txt', 'a') as testfile: testfile.write("Player_index: " + str(player_index) + " [0: White, 1: Blue, 2: Green, 3: Red], " + "\n") f.write("Player_index: " + str(player_index) + " [0: White, 1: Blue, 2: Green, 3: Red], " + "\n") """This agent always moves toward observation.food[0] but does not take advantage of board wrapping""" Matrix, MatrixNoFood, MatrixHeadAvoid1, MatrixHeadAvoid2 = fill_matrix(observation, configuration) f.write("Matrix filled" + "\n") [MatrixNoFood, MatrixHeadAvoid1, MatrixHeadAvoid2], start, shift = shift_matrix([MatrixNoFood, MatrixHeadAvoid1, MatrixHeadAvoid2], start) f.write("Matrix shifted" + "\n") f.write("Start coords " + str(start) + "\n") #MatrixToUse = MatrixNoFood #MatrixToUse = MatrixHeadAvoid2 #MatrixToUse = MatrixHeadAvoid1 #MatrixBackup1 = MatrixHeadAvoid1 #MatrixBackup2 = MatrixNoFood #MatrixsToUse = [MatrixHeadAvoid2, MatrixHeadAvoid1, MatrixNoFood] MatrixsToUse = [MatrixHeadAvoid1, MatrixNoFood] #will replace player_row, player_column with 2d array that has all positions filled with all player information path = path_to_closest_food(observation, configuration, MatrixsToUse, start, shift) if path == "no path": player_index = observation.index player_goose = observation.geese[player_index] player_end = player_goose[len(player_goose)-1] player_end_row, player_end_column = row_col(player_end, configuration.columns) for MatrixToUse in MatrixsToUse: if path == "no path": if start == (player_end_row, player_end_column): path = astar(MatrixToUse, start, (player_end_row+3, player_end_column+5)) else: path = astar(MatrixToUse, start, (player_end_row, player_end_column)) f.write("Path: " + str(path) + "\n") whichMove = which_direction(path) t1 = time.clock() - t0 f.write("This is turn: " + str(int(which_turn)) + " , chosen movement: " ) f.write(str(whichMove)) f.write(" which took " + str(t1) + " seconds") f.close() return whichMove
def agent(obs_dict, config_dict, gindex): ################################################# # State retrieval ################################################# #print("-----------") global last_action conf = Configuration(config_dict) obs = Observation(obs_dict) step = obs.step + 1 my_idx = gindex my_goose = obs.geese[my_idx] my_head = my_goose[0] my_row, my_col = row_col(position=my_head, columns=conf.columns) if DEBUG: print("---------- Step #" + str(step), "- Player #" + str(obs.index)) ################################################# # Map update ################################################# board = np.zeros((7, 11), dtype=int) # Add food to board for food in obs.food: food_row, food_col = row_col(position=food, columns=conf.columns) board[food_row, food_col] += FOOD_REWARD '''if DEBUG: print("food", food_row, food_col)''' # Iterate over geese to add geese data to board nb_geese = len(obs.geese) geese_lengths = [] for i in range(nb_geese): '''if DEBUG: print("--- Goose #" + str(i))''' goose = obs.geese[i] potential_food_head = None # Iterate over cells of current goose goose_len = len(goose) geese_lengths.append(goose_len) '''if DEBUG: print("--- Goose #" + str(i) + " len " + str(goose_len))''' for j in range(goose_len): '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j))''' goose_cell = goose[j] goose_row, goose_col = row_col(position=goose_cell, columns=conf.columns) # Check for food on neighbour cells when handling head if j == 0: potential_heads = get_neighbours(goose_row, goose_col) for potential_head in potential_heads: for food in obs.food: food_row, food_col = row_col(position=food, columns=conf.columns) if potential_head == (food_row, food_col): potential_food_head = potential_head # Update rewards linked to body/tail if j < goose_len - 1: # Body or head board[goose_row, goose_col] += BODY_REWARD '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j) + " add BODY_REWARD")''' else: # Tail : may not move if goose eats if potential_food_head is not None: board[goose_row, goose_col] += TAIL_REWARD '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j) + " add TAIL_REWARD")''' # Update potential villain head positions if (i != my_idx) & (goose_len > 0): if potential_food_head is not None: # Head will prolly go to the food for potential_head in potential_heads: if potential_head == potential_food_head: if (board[potential_head[0], potential_head[1]] != BODY_REWARD) & \ (board[potential_head[0], potential_head[1]] != TAIL_REWARD): board[ potential_head[0], potential_head[1]] += PROBABLE_HEAD_FOOD_REWARD '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j) + " add PROBABLE_HEAD_FOOD_REWARD")''' else: if (board[potential_head[0], potential_head[1]] != BODY_REWARD) & \ (board[potential_head[0], potential_head[1]] != TAIL_REWARD): board[potential_head[0], potential_head[ 1]] += IMPROBABLE_HEAD_FOOD_REWARD '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j) + " add IMPROBABLE_HEAD_FOOD_REWARD")''' else: # Standard potential head reward for potential_head in potential_heads: if (board[potential_head[0], potential_head[1]] != BODY_REWARD) & \ (board[potential_head[0], potential_head[1]] != TAIL_REWARD): board[potential_head[0], potential_head[1]] += POTENTIAL_HEAD_STD_REWARD '''if DEBUG: print("--- Goose #" + str(i) + " cell " + str(j) + " add POTENTIAL_HEAD_STD_REWARD")''' # Check if I'm the current longest Goose if (len(my_goose) >= max(geese_lengths) - 3) & (step > 8): # Chasing my tail as a defensive action makes sense my_tail_row, my_tail_col = row_col(position=my_goose[-1], columns=conf.columns) board[my_tail_row, my_tail_col] += TAIL_CHASE_REWARD '''if DEBUG: print("Adding TAIL_CHASE_REWARD for me")''' # Diffuse values in adjacent cells if DEBUG: print("Initial board :") print(board) new_board = board.copy() for i in range(7): for j in range(11): value = board[i, j] if value > DIFFUSE_START: # Should diffuse positive value neighbours = get_neighbours(i, j) for neighbour in neighbours: # Level 1 new_board[neighbour] += (2 * DIFFUSE_POS_REWARD) # Level 2 neighbours_lvl2 = get_neighbours(neighbour[0], neighbour[1]) for neighbour_lvl2 in neighbours_lvl2: new_board[neighbour_lvl2] += DIFFUSE_POS_REWARD elif value < -DIFFUSE_START: # Should diffuse negative value neighbours = get_neighbours(i, j) for neighbour in neighbours: # Level 1 new_board[neighbour] += (2 * DIFFUSE_NEG_REWARD) # Level 2 neighbours_lvl2 = get_neighbours(neighbour[0], neighbour[1]) for neighbour_lvl2 in neighbours_lvl2: new_board[neighbour_lvl2] += DIFFUSE_NEG_REWARD board = new_board # Add last_action data to board if last_action is not None: if last_action == Action.SOUTH.name: board[(my_row + 6) % 7, my_col] += REVERSE_LAST_REWARD elif last_action == Action.NORTH.name: board[(my_row + 8) % 7, my_col] += REVERSE_LAST_REWARD elif last_action == Action.EAST.name: board[my_row, (my_col + 10) % 11] += REVERSE_LAST_REWARD elif last_action == Action.WEST.name: board[my_row, (my_col + 12) % 11] += REVERSE_LAST_REWARD '''if DEBUG: print("Adding REVERSE_LAST_REWARD for me")''' if DEBUG: print("Final board :") print(board) ################################################# # Choose best action ################################################# chosen_action = None rewards = [] potential_next = get_neighbours(my_row, my_col) for cell in potential_next: rewards.append(board[cell]) choice = np.argmax(rewards) if choice == 0: chosen_action = Action.NORTH.name elif choice == 1: chosen_action = Action.WEST.name elif choice == 2: chosen_action = Action.SOUTH.name else: chosen_action = Action.EAST.name if DEBUG: print("chosen_action", chosen_action) last_action = chosen_action return chosen_action
def __call__(self, obs_dict, config_dict): self._world.update(Observation(obs_dict)) return self.play(obs_dict, config_dict)[0]
def agent(obs_dict, config_dict): """This agent always moves toward observation.food[0] but does not take advantage of board wrapping""" global last_move observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) possible_moves = [ Action.SOUTH.name, Action.NORTH.name, Action.WEST.name, Action.EAST.name ] possible_move = None oldFoodDistanceToMe = 9999 def getFoodsIndex(): foods = [] for i in range(len(observation.food)): food = observation.food[i] foods.append(row_col(food, configuration.columns)) return foods def getGoose(index): goose = [] for i in range(len(observation.geese[index])): goose.append( row_col(observation.geese[index][i], configuration.columns)) return goose def getGeesesIndex(): geeses = [] for geese in observation.geese: geeses.append(row_col(geese[0], configuration.columns)) return geeses def randomMove(moves): if len(moves) > 1: return moves[randint(0, len(moves) - 1)] return moves[0] def countMoves(x1, y1, x2, y2): return abs((x1 - x2) + (y1 - y2)) def willCollide(x, y, action): #print(f'Goose[{player_index} in player_row: {player_row}, player_column: {player_column} move to {action} and can collide with x: {x}, y: {y}') if action == Action.WEST.name: if player_column - 1 == y and x == player_row: return True if player_column == 0 and y == 10 and x == player_row: return True if action == Action.EAST.name: if player_column + 1 == y and x == player_row: return True if player_column == 10 and y == 0 and x == player_row: return True if action == Action.SOUTH.name: if player_row + 1 == x and y == player_column: return True if player_row == 6 and x == 0 and y == player_column: return True if action == Action.NORTH.name: if player_row - 1 == x and y == player_column: return True if player_row == 0 and x == 6 and y == player_column: return True return False def opposite(action): if action == Action.NORTH.name: return Action.SOUTH.name if action == Action.SOUTH.name: return Action.NORTH.name if action == Action.EAST.name: return Action.WEST.name if action == Action.WEST.name: return Action.EAST.name possible_moves = [ Action.SOUTH.name, Action.NORTH.name, Action.WEST.name, Action.EAST.name ] if last_move[player_index] is not None: print( f'Geese {player_index} removes opposite last move: {opposite(last_move[player_index])}' ) possible_moves.remove(opposite(last_move[player_index])) for geese_row, geese_column in getGeesesIndex(): for food_row, food_column in getFoodsIndex(): foodDistanceToMe = countMoves(food_row, food_column, player_row, player_column) if oldFoodDistanceToMe > foodDistanceToMe: oldFoodDistanceToMe = foodDistanceToMe else: continue geeseDistanceToFood = countMoves(geese_row, geese_column, food_row, food_column) if foodDistanceToMe < geeseDistanceToFood: if food_row > player_row: possible_move = Action.SOUTH.name if food_row < player_row: possible_move = Action.NORTH.name if food_column > player_column: possible_move = Action.EAST.name if food_column < player_column: possible_move = Action.WEST.name print( f'Geese {player_index} based by food, possible move: {possible_move}' ) if possible_move not in possible_moves: print( f'Geese {player_index}, possible move: {possible_move} is banned.') possible_move = randomMove(possible_moves) for i in range(len(observation.geese)): geese_index = getGoose(i) j = 0 while j < len(geese_index): collision = False x, y = geese_index[j] if i != player_index: print(f'geese {player_index} -> geese {i} part {j}') #print(f'goose[{player_index}] in {getGoose(player_index)[0]} with possible move: {possible_move} can colide with goose[{i}] in x: {x} and y: {y}') while willCollide(x, y, possible_move): collision = True print( f'goose[{player_index}] in {getGoose(player_index)[0]} with possible move: {possible_move} will colide with goose[{i}] in x: {x} and y: {y}' ) possible_moves.remove(possible_move) possible_move = randomMove(possible_moves) print(f'now goose[{player_index}] will to {possible_move}') j = 0 if not collision: j += 1 for x, y in getGoose(player_index): while willCollide(x, y, possible_move): print(f'BODY HIT!!!') possible_moves.remove(possible_move) possible_move = randomMove(possible_moves) if len(possible_moves) == 1: print( f'Geese {player_index} just remain this move: {possible_moves[0]}') possible_move = possible_moves[0] last_move[player_index] = possible_move print( f'Geese {player_index}: {getGoose(player_index)} move to {possible_move}' ) return possible_move
def agent(obs_dict, config_dict): global last_step # State retrieval observation = Observation(obs_dict) configuration = Configuration(config_dict) player_index = observation.index player_goose = observation.geese[player_index] player_head = player_goose[0] player_row, player_column = row_col(player_head, configuration.columns) # Map creation # 0 - empty cells # -1 - obstacles # -4 - possible obstacles # -2 - food # -3 - head # 1,2,3,4 - reachable on the current step cell, number is the id of the first step direction table = np.zeros((7, 11)) legend = {1: 'SOUTH', 2: 'NORTH', 3: 'EAST', 4: 'WEST'} # let's add food to the map for food in observation.food: x, y = row_col(food, configuration.columns) table[x, y] = -2 # food # let's add all cells that are forbidden for i in range(4): opp_goose = observation.geese[i] if len(opp_goose) == 0: continue is_close_to_food = False if i != player_index: x, y = row_col(opp_goose[0], configuration.columns) possible_moves = get_nearest_cells(x, y) # head can move anywhere for x, y in possible_moves: if table[x, y] == -2: is_close_to_food = True table[ x, y] = -4 # Cells where opponent might possibly go next step # usually we ignore the last tail cell but there are exceptions tail_change = -1 if obs_dict['step'] % 40 == 39: tail_change -= 1 # we assume that the goose will eat the food if is_close_to_food: tail_change += 1 if tail_change >= 0: tail_change = None for n in opp_goose[:tail_change]: x, y = row_col(n, configuration.columns) table[x, y] = -1 # forbidden cells # going back is forbidden according to the new rules x, y = row_col(player_head, configuration.columns) if last_step is not None: if last_step == 1: table[(x + 6) % 7, y] = -1 elif last_step == 2: table[(x + 8) % 7, y] = -1 elif last_step == 3: table[x, (y + 10) % 11] = -1 elif last_step == 4: table[x, (y + 12) % 11] = -1 # add head position table[x, y] = -3 # the first step toward the nearest food step = int(find_closest_food(table)) # if there is not available steps try to go to possibly dangerous cell if step not in [1, 2, 3, 4]: x, y = row_col(player_head, configuration.columns) if table[(x + 8) % 7, y] == -4: step = 1 elif table[(x + 6) % 7, y] == -4: step = 2 elif table[x, (y + 12) % 11] == -4: step = 3 elif table[x, (y + 10) % 11] == -4: step = 4 # else - do a random step and lose else: step = np.random.randint(4) + 1 last_step = step return legend[step]
def override_interpreter(state, env): configuration = Configuration(env.configuration) columns = configuration.columns rows = configuration.rows min_food = configuration.min_food state[0].observation = shared_observation = Observation(state[0].observation) hits = 0 # Reset the environment. if env.done: agent_count = len(state) heads = sample(range(columns * rows), agent_count) shared_observation["geese"] = [[head] for head in heads] food_candidates = set(range(columns * rows)).difference(heads) # Ensure we only place as many food as there are open squares min_food = min(min_food, len(food_candidates)) shared_observation["food"] = sample(food_candidates, min_food) return state geese = shared_observation.geese food = shared_observation.food # If there is no last state, reuse current state so that current action is never the opposite of the last action. last_state = env.steps[-1] if len(env.steps) > 1 else state # Apply the actions from active agents. for index, agent in enumerate(state): if agent.status != "ACTIVE": if agent.status != "INACTIVE" and agent.status != "DONE": # ERROR, INVALID, or TIMEOUT, remove the goose. geese[index] = [] continue action = Action[agent.action] # Check action direction last_agent = last_state[index] last_action = Action[last_agent["action"]] if "action" in last_agent else action if last_action == action.opposite(): env.debug_print(f"Opposite action: {agent.observation.index, action, last_action}") agent.status = "DONE" geese[index] = [] hits +=1 continue goose = geese[index] head = translate(goose[0], action, columns, rows) # Consume food or drop a tail piece. if head in food: food.remove(head) else: goose.pop() # Self collision. if head in goose: env.debug_print(f"Body Hit: {agent.observation.index, action, head, goose}") agent.status = "DONE" geese[index] = [] hits +=1 continue while len(goose) >= configuration.max_length: # Free a spot for the new head if needed goose.pop() # Add New Head to the Goose. goose.insert(0, head) # If hunger strikes remove from the tail. if len(env.steps) % configuration.hunger_rate == 0: if len(goose) > 0: goose.pop() if len(goose) == 0: env.debug_print(f"Goose Starved: {action}") agent.status = "DONE" hits +=1 continue goose_positions = histogram( position for goose in geese for position in goose ) # Check for collisions. for index, agent in enumerate(state): goose = geese[index] if len(goose) > 0: head = geese[index][0] if goose_positions[head] > 1: env.debug_print(f"Goose Collision: {agent.action}") agent.status = "DONE" geese[index] = [] hits +=1 # Add food if min_food threshold reached. needed_food = min_food - len(food) if needed_food > 0: collisions = { position for goose in geese for position in goose } available_positions = set(range(rows * columns)).difference(collisions).difference(food) # Ensure we don't sample more food than available positions. needed_food = min(needed_food, len(available_positions)) food.extend(sample(available_positions, needed_food)) # Set rewards after deleting all geese to ensure that geese don't receive a reward on the turn they perish. for index, agent in enumerate(state): if agent.status == "ACTIVE": agent.reward = (configuration.max_length + 1)*(hits+1) + len(geese[index]) - sum((len(goose) for goose in geese)) # Adding 1 to len(env.steps) ensures that if an agent gets reward 4507, it died on turn 45 with length 7. # If only one ACTIVE agent left, set it to DONE. active_agents = [a for a in state if a.status == "ACTIVE"] if len(active_agents) == 1: agent = active_agents[0] agent.status = "DONE" return state