def make_decision(self, player_name: str, game_state: GameState) -> CharacterDecision: """ Parameters: player_name (string): The name of your player game_state (GameState): The current game state """ self.api = API(game_state, player_name) self.my_player = game_state.get_all_players()[player_name] self.board = game_state.get_pvp_board() self.curr_pos = self.my_player.get_position() self.logger.info("In make_decision") last_action, type = self.memory.get_value("last_action", str) if last_action is not None and last_action == "PICKUP": self.memory.set_value("last_action", "EQUIP") return CharacterDecision( decision_type="EQUIP", action_position=None, action_index=self.my_player.get_free_inventory_index()) tile_items = self.board.get_tile_at(self.curr_pos).items if tile_items is not None or len(tile_items) > 0: self.memory.set_value("last_action", "PICKUP") return CharacterDecision(decision_type="PICKUP", action_position=None, action_index=0) weapon = self.my_player.get_weapon() enemies = self.api.find_enemies(self.curr_pos) if enemies is None or len(enemies) > 0: self.memory.set_value("last_action", "MOVE") return CharacterDecision( decision_type="MOVE", action_position=self.my_player.get_spawn_point(), action_index=None) enemy_pos = enemies[0].get_position() if self.curr_pos.manhattan_distance(enemy_pos) <= weapon.get_range(): self.memory.set_value("last_action", "ATTACK") return CharacterDecision(decision_type="ATTACK", action_position=enemy_pos, action_index=None) self.memory.set_value("last_action", "MOVE") decision = CharacterDecision(decision_type="MOVE", action_position=find_position_to_move( self.my_player, enemy_pos), action_index=None) return decision
def send_decision(): payload = request.get_data() player_turn = player_pb2.PlayerTurn() player_turn.ParseFromString(payload) app.logger.info( f"Received playerTurn for player: {player_turn.player_name}, turn: {player_turn.game_state.state_id}" ) game_state = GameState(player_turn.game_state) player_name = player_turn.player_name response_msg = character_pb2.CharacterDecision() try: decision = self.strategy.make_decision(player_name, game_state) except Exception as err: app.logger.info("Exception making decision:") traceback.print_exc() decision = None if decision is not None: response_msg = decision.build_proto_class_character_decision() else: # Build NONE decision if contestant code failed response_msg.decision_type = character_pb2.NONE response_msg.index = -1 if self.debug: self.atomicInt.increment() app.logger.info("Sending playerDecision") return response_msg.SerializeToString()
def make_decision(self, player_name: str, game_state: GameState) -> CharacterDecision: """ Parameters: player_name (string): The name of your player game_state (GameState): The current game state """ ######################## Initialize ######################## self.api = API(game_state, player_name) self.my_player = game_state.get_all_players()[player_name] self.current_board = game_state.get_board( self.my_player.get_position().board_id) self.curr_pos = self.my_player.get_position() self.monsters_on_board = { name: monster for name, monster in game_state.get_all_monsters().items() if monster.get_position().board_id == self.curr_pos.board_id } target_monster = None self.searching_graph = search.Graph( self.current_board, self.my_player.get_position().board_id) self.logger.info("In make_decision") # self.logger.info(helpers.TELL_ME_ME(self.my_player)) ######################## TAKE TURN HERE ######################## # self.logger.info(f"All monsters: {game_state.get_all_monsters()}") #decision = CharacterDecision( # decision_type="MOVE", # action_position=Position(self.curr_pos.x+2, self.curr_pos.y, "tb_tbdt_dt"), # action_index=None) # Combine nearby items with inventory items available_items_tiles = helpers.non_api_find_items( self.my_player, self.current_board, self.my_player.get_speed(), self.logger) available_items = self.my_player.inventory + [ tup[0] for tup in available_items_tiles ] self.logger.info(f"My Player: {self.my_player.__dict__}") self.logger.info(f"Current position: {self.curr_pos.__dict__}") self.logger.info(f"Available items around: {available_items_tiles}") self.logger.info(f"Our inventory: {self.my_player.inventory}") self.logger.info( f"Our weapon actual: {self.my_player.get_weapon().__dict__}") self.logger.info( f"Our weapon: {self.my_player.get_weapon().stats.__dict__}") self.logger.info( f"Our clothes: {self.my_player.get_clothes().stats.__dict__}") self.logger.info( f"Our shoes: {self.my_player.get_shoes().stats.__dict__}") self.logger.info(f"Our hat: {self.my_player.get_hat().stats.__dict__}") self.logger.info( f"Our accessory: {self.my_player.get_accessory().stats.__dict__}") # best item to equip here! item_index = helpers.should_we_equip(self.my_player, available_items, self.logger) self.logger.info(f"Item index: {item_index}") # Find non-consumable items droppable_items = [ (index, item) for index, item in enumerate(self.my_player.inventory) if type(item) in [Weapon, Clothes, Shoes, Hat, Accessory] ] nearby_monsters = helpers.monsters_in_range( self.my_player, list(self.monsters_on_board.values())) if item_index != -1 and item_index >= len(self.my_player.inventory): target_item, x, y = available_items_tiles[ item_index - len(self.my_player.inventory)] if x != self.curr_pos.x or y != self.curr_pos.y: pos = Position.create(x, y, self.curr_pos.board_id) decision = decision_maker.head_to(pos) else: if len(self.my_player.inventory) >= 16: self.logger.warning( "==================INVENTORY FULL??? pOG================" ) else: decision = decision_maker.pickup(self.my_player, target_item, self.current_board) elif item_index != -1: decision = decision_maker.equip_given_item(item_index) elif nearby_monsters: decision, target_monster = decision_maker.make_our_combat_decision( self.api, self.my_player, self.logger, self.monsters_on_board, self.searching_graph) elif droppable_items: index, item = droppable_items[0] decision = decision_maker.drop_item(index) #elif available_items_tiles: # decision = decision_maker.loot_items(self.api, self.my_player, self.logger, self.current_board, available_items_tiles) else: decision, target_monster = decision_maker.make_our_combat_decision( self.api, self.my_player, self.logger, self.monsters_on_board, self.searching_graph) #decision = decision_maker.make_our_weapon_decision(self.api, self.my_player, self.logger) #decision = decision_maker.head_to_portal_decision(self.api, self.my_player, self.logger) # decision_maker.head_to_portal_decision(self.api, self.my_player, self.logger) self.logger.info(f"We are doing {decision.__dict__}") try: self.logger.info( f"Position is: {decision.action_position.__dict__}") except: pass self.logger.info( f"Player experience: {self.my_player.get_total_experience()}") #try: # self.logger.info(f"====near target monsters=== {[mon.__dict__ for mon in list(self.monsters_on_board.values()) if abs(self.my_player.get_level() - mon.get_level()) < 4][:9]}") #except: # self.logger.info(f"======================log failed") ######################## Logging ######################## self.memory.set_value("last_decision", decision) self.memory.set_value("last_target_monster", target_monster) self.logger.info( f"{target_monster.__dict__ if target_monster else 'None'}") self.memory.set_value("last_current_health", self.my_player.current_health) ######################## END TURN ######################## return decision """
def make_decision(self, player_name: str, game_state: GameState) -> CharacterDecision: """ Parameters: player_name (string): The name of your player game_state (GameState): The current game state """ self.api = API(game_state, player_name) self.my_player = game_state.get_all_players()[player_name] self.board = game_state.get_pvp_board() self.curr_pos = self.my_player.get_position() self.logger.info("In make_decision") self.logger.info( f"Currently at position: ({self.curr_pos.x},{self.curr_pos.y}) on board '{self.curr_pos.board_id}'" ) last_action, type = self.memory.get_value("last_action", str) self.logger.info(f"last_action: '{last_action}'") if last_action is not None and last_action == "PICKUP": self.logger.info( "Last action was picking up, equipping picked up object") self.memory.set_value("last_action", "EQUIP") return CharacterDecision( decision_type="EQUIP", action_position=None, action_index=0 # self.my_player.get_free_inventory_index() ) tile_items = self.board.get_tile_at(self.curr_pos).get_items() if tile_items is not None and len(tile_items) > 0: self.logger.info("There are items on my tile, picking up item") self.memory.set_value("last_action", "PICKUP") return CharacterDecision(decision_type="PICKUP", action_position=None, action_index=0) weapon = self.my_player.get_weapon() enemies = self.api.find_enemies_by_distance(self.curr_pos) if enemies is None or len(enemies) == 0: self.logger.info( "There is no enemies in range, moving to spawn point") self.memory.set_value("last_action", "MOVE") return CharacterDecision( decision_type="MOVE", action_position=self.my_player.get_spawn_point(), action_index=None) enemy_pos = enemies[0].get_position() if self.curr_pos.manhattan_distance(enemy_pos) <= weapon.get_range(): self.logger.info( "There is an enemy within weapon range, attacking") self.memory.set_value("last_action", "ATTACK") return CharacterDecision(decision_type="ATTACK", action_position=enemy_pos, action_index=None) self.memory.set_value("last_action", "MOVE") self.logger.info("Moving towards the nearest enemy") decision = CharacterDecision( decision_type="MOVE", action_position=self.find_position_to_move(self.my_player, enemy_pos), action_index=None) return decision
def make_decision(self, player_name: str, game_state: GameState) -> CharacterDecision: """ Parameters: player_name (string): The name of your player game_state (GameState): The current game state """ self.logger.info( "==========================NEW TURN==========================") self.api = API(game_state, player_name) self.character = game_state.get_character(player_name) self.my_player = game_state.get_all_players()[player_name] #self.pvpboard = game_state.get_pvp_board() self.board = game_state.get_board(self.board_id) self.curr_pos = self.my_player.get_position() self.monsters = game_state.get_monsters_on_board(self.board_id) self.obstacles = self.get_obstacles(game_state) self.bad_monster_squares = self.get_monsters(game_state, self.board_id) # cycle through items items = self.my_player.get_inventory() self.logger.info("items: {}".format(items)) cur_weapon = self.my_player.get_weapon self.logger.info('performing inventory check') try: if self.character.clothes is not None: self.print_stats(self.character.clothes) except: self.logger.info("no clothes to print") pass try: if self.character.hat is not None: self.print_stats(self.character.hat) except: self.logger.info("no hat to print") pass try: if self.character.weapon is not None: self.print_stats(self.character.weapon) except: self.logger.info("no weapon to print") pass try: if self.character.shoes is not None: self.print_stats(self.character.shoes) except: self.logger.info("no shoes to print") pass try: if self.character.accessory is not None: self.print_stats(self.character.accessory) except: self.logger.info("no accessory to print") pass for i, item in reversed(list(enumerate(items))): # self.logger.info('exp change: {}, {}'.format(item.get_flat_experience_change(), item.get_percent_experience_change())) # self.logger.info('atk change: {}, {}'.format(item.get_flat_attack_change(), item.get_percent_attack_change())) # if item.get_flat_attack_change() > cur_weapon.get_flat_attack_change(): # self.logger.info('equiping item') # return CharacterDecision( # decision_type="EQUIP", # action_position=None, # action_index=i # ) try: self.logger.info("grading index {} in the inventory".format(i)) # self.logger.info(type(item)) item_type = item.__class__.__name__ # self.logger.info(item_type) if "Consumable" in item_type: #idk do we equip the consumable before we fite the guy #but also if its a health potion do it now self.logger.info( 'index {} is a consumable, eating!'.format(i)) #actually drop consumables f**k em (no wee eat them right there) return CharacterDecision(decision_type="EQUIP", action_position=None, action_index=i) # continue self.logger.info(self.print_stats(item)) stat_mod = item.get_stats() new_stats = 0 try: new_stats += stat_mod.get_flat_speed_change() * 0 except: new_stats += 0 try: new_stats += stat_mod.get_percent_speed_change() * 0 except: new_stats += 0 try: new_stats += stat_mod.get_flat_health_change() * .1 except: new_stats += 0 try: new_stats += stat_mod.get_percent_health_change() * 30 except: new_stats += 0 try: new_stats += stat_mod.get_flat_experience_change() * 10 except: new_stats += 0 try: new_stats += stat_mod.get_percent_experience_change() * 200 except: new_stats += 0 try: new_stats += stat_mod.get_flat_attack_change() * 10 except: new_stats += 0 try: new_stats += stat_mod.get_percent_attack_change() * 70 except: new_stats += 0 try: new_stats += stat_mod.get_flat_defense_change() * 2 except: new_stats += 0 try: new_stats += stat_mod.get_percent_defense_change() * 30 except: new_stats += 0 try: new_stats += stat_mod.get_flat_regen_per_turn() * 0 except: new_stats += 0 self.logger.info("got stats for index {}".format(i)) # new_stats = stat_mods.get_flat_speed_change() + stat_mods.get_percent_speed_change() + stat_mods.get_flat_health_change() + stat_mods.get_percent_health_change() + stat_mods.get_flat_defense_change() + stat_mods.get_flat_attack_change() + stat_mods.get_percent_attack_change() self.logger.info("stat check for index {} is {}".format( i, new_stats)) for typ in ["Clothes", "Hat", "Shoes", "Weapon", "Accessory"]: if typ in item_type: self.logger.info('index {} is a {}'.format(i, typ)) current_stats = self.stats[typ] self.logger.info( 'old stats: {} , new stats: {}'.format( current_stats, new_stats)) if new_stats > current_stats: self.logger.info("equipping") self.stats[typ] = new_stats return CharacterDecision(decision_type="EQUIP", action_position=None, action_index=i) else: self.logger.info( "this {} sucks, dropping it".format(typ)) return CharacterDecision(decision_type="DROP", action_position=None, action_index=i) except Exception as e: self.logger.error(e) return CharacterDecision(decision_type="DROP", action_position=None, action_index=0) # item pick up tile_items = self.board.get_tile_at(self.curr_pos).items if len(tile_items) > 0: self.memory.set_value("last_action", "PICKUP") self.logger.info("picking up item: {}".format(tile_items)) try: for i in range(len(tile_items)): self.logger.info("grading new item index {}".format(i)) if "Consumable" in tile_items[i].__class__.__name__: return CharacterDecision(decision_type="PICKUP", action_position=self.curr_pos, action_index=i) stat_mods = tile_items[i].get_stats() stat_sum = stat_mods.get_flat_speed_change( ) * 0 + stat_mods.get_percent_speed_change( ) * 0 + stat_mods.get_flat_health_change( ) * .1 + stat_mods.get_percent_health_change( ) * 30 + stat_mods.get_flat_defense_change( ) * 2 + stat_mods.get_flat_attack_change( ) * 10 + stat_mods.get_percent_attack_change( ) * 70 + stat_mods.get_percent_defense_change( ) * 30 + stat_mods.get_flat_regen_per_turn( ) * 0 + stat_mods.get_flat_experience_change( ) * 10 + stat_mods.get_percent_experience_change() * 200 self.logger.info("new item stat: " + str(stat_sum)) self.logger.info( "curr stat item: " + str(self.stats[tile_items[i].__class__.__name__])) if stat_sum > self.stats[tile_items[i].__class__.__name__]: self.logger.info( "picking up item at index {}".format(i)) return CharacterDecision(decision_type="PICKUP", action_position=self.curr_pos, action_index=i) else: self.logger.info( "skipping index {}, shitty item".format(i)) except Exception as e: self.logger.error(e) self.logger.info("picking up item at index 0") return CharacterDecision(decision_type="PICKUP", action_position=self.curr_pos, action_index=i) for d in [(1, 0), (-1, 0), (0, 1), (0, -1)]: target_pos = Position.create(self.curr_pos.x + d[0], self.curr_pos.y + d[1], self.curr_pos.get_board_id()) tile_items = self.board.get_tile_at(target_pos).items if len(tile_items) > 0: for i in range(len(tile_items)): self.logger.info("grading new item index {}".format(i)) if "Consumable" in tile_items[i].__class__.__name__: self.memory.set_value("last_action", "MOVE") self.logger.info("moving to item") return CharacterDecision(decision_type="MOVE", action_position=target_pos, action_index=0) stat_mods = tile_items[i].get_stats() stat_sum = stat_mods.get_flat_speed_change( ) * 0 + stat_mods.get_percent_speed_change( ) * 0 + stat_mods.get_flat_health_change( ) * .1 + stat_mods.get_percent_health_change( ) * 30 + stat_mods.get_flat_defense_change( ) * 2 + stat_mods.get_flat_attack_change( ) * 10 + stat_mods.get_percent_attack_change( ) * 70 + stat_mods.get_percent_defense_change( ) * 30 + stat_mods.get_flat_regen_per_turn( ) * 0 + stat_mods.get_flat_experience_change( ) * 10 + stat_mods.get_percent_experience_change() * 200 self.logger.info("new item stat: " + str(stat_sum)) self.logger.info( "curr stat item: " + str(self.stats[tile_items[i].__class__.__name__])) if stat_sum > self.stats[tile_items[i].__class__.__name__]: self.memory.set_value("last_action", "MOVE") self.logger.info("moving to item") return CharacterDecision(decision_type="MOVE", action_position=target_pos, action_index=0) else: self.logger.info( "skipping index {}, shitty item".format(i)) ## Choose weakest monster weakestMonster = self.findWeakest(self.monsters, self.curr_pos) weapon = self.my_player.get_weapon() ## Check if weakest monster is in attack range if self.curr_pos.manhattan_distance( weakestMonster.position) <= weapon.get_range(): self.logger.info("Attacking monster: " + str(weakestMonster.get_name()) + " with health " + str(weakestMonster.get_current_health()) + "/" + str(weakestMonster.get_max_health())) return CharacterDecision( decision_type="ATTACK", action_position=weakestMonster.get_position(), action_index=0) ## Move to weakest monster! self.logger.info("Chosen weakest monster: " + str(weakestMonster.get_name()) + " || location: (" + str(weakestMonster.get_position().x) + "," + str(weakestMonster.get_position().y) + ")") positionToMove = self.zhou_astar_path_to_move( self.my_player, weakestMonster.get_position()) # hard code walk back if positionToMove[0] >= 6: positionToMove[0] = 4 positionObjectToMove = self.curr_pos newPos = positionObjectToMove.create(positionToMove[0], positionToMove[1], self.board_id) self.logger.info("Location to move now: (" + str(newPos.x) + ", " + str(newPos.y) + ")") return CharacterDecision(decision_type="MOVE", action_position=newPos, action_index=0)
def make_decision(self, player_name: str, game_state: GameState) -> CharacterDecision: """ Parameters: player_name (string): The name of your player game_state (GameState): The current game state """ self.api = API(game_state, player_name) self.game_state = game_state self.my_player = game_state.get_all_players()[player_name] # self.board = game_state.get_pvp_board() self.player_board = game_state.get_board(player_name) self.curr_pos = self.my_player.get_position() self.logger.info("Version: 4.0") # Figure out role my_health = self.my_player.get_current_health() spawn_point = self.my_player.get_spawn_point() if my_health <= 10 or ( self.equal_pos(self.curr_pos, spawn_point) and my_health <= self.my_player.get_max_health() - 10): self.role = roles.GAIN_XP else: self.role = roles.GAIN_XP self.logger.info("Player at " + self.get_position_str(self.curr_pos) + " | Health: " + str(my_health) + " | XP: " + str(self.my_player.get_experience()) + " | Total XP: " + str(self.my_player.get_total_experience())) self.logger.info("ATK: {}, SPD: {}, DEF: {}".format( self.my_player.get_attack(), self.my_player.get_speed(), self.my_player.get_defense())) last_action, type = self.memory.get_value("last_action", str) last_role, type = self.memory.get_value("role", str) self.memory.set_value("role", "test_val") self.logger.info("last action " + str(last_action)) self.logger.info("last role " + str(last_role)) ### store our current stats and inven ### weapon: Weapon = self.my_player.get_weapon( ) # should always be index 0 hat: Hat = self.my_player.get_hat() # always index 1 shoes: Shoes = self.my_player.get_shoes() clothes: Clothes = self.my_player.get_clothes() # always index 2 accessory: Accessory = self.my_player.get_accessory() self.logger.info("Curr Weapon: {}".format( self.get_item_stats_str(weapon))) self.logger.info("Curr Clothes: {}".format( self.get_item_stats_str(clothes))) self.logger.info("Curr Hat: {}".format(self.get_item_stats_str(hat))) self.logger.info("Curr Shoes: {}".format( self.get_item_stats_str(shoes))) self.logger.info("Curr Accessory: {}".format( self.get_item_stats_str(accessory))) # if inventory has better weapon, equip it inven: list[Item] = self.my_player.get_inventory() self.logger.info("Have {} inventory items".format(len(inven))) best_wep_to_equip: Weapon = None best_wep_to_equip_index: int = None best_gear_to_equip: Wearable = None best_gear_to_equip_index: int = None for i, item in enumerate(inven): self.logger.info("Inven {} - {} - stats: {}".format( i, item, self.get_item_stats_str(item))) if isinstance(item, Consumable): self.logger.info("Equipping consumable") return decisions.equip_item(i) elif isinstance(item, Weapon): item_val = self.value_of_wearable(item) if item_val > self.value_of_wearable(weapon): self.logger.info( "Equipping weapon at index {} with stats: {}".format( i, self.get_item_stats_str(item))) return decisions.equip_item(i) elif item_val < self.value_of_wearable(weapon): self.logger.info("Dropping weapon at {}".format(i)) return decisions.drop_item(i) elif isinstance(item, Clothes): item_val = self.value_of_wearable(item) if (item_val > self.value_of_wearable(clothes)): self.logger.info( "Equipping clothes at index {} with stats: {}".format( i, self.get_item_stats_str(item))) return decisions.equip_item(i) elif item_val < self.value_of_wearable(clothes): self.logger.info("Dropping clothes at {}".format(i)) return decisions.drop_item(i) elif isinstance(item, Hat): item_val = self.value_of_wearable(item) if (item_val > self.value_of_wearable(hat)): self.logger.info( "Equipping hat at index {} with stats: {}".format( i, self.get_item_stats_str(item))) return decisions.equip_item(i) elif item_val < self.value_of_wearable(hat): self.logger.info("Dropping hat at {}".format(i)) return decisions.drop_item(i) elif isinstance(item, Shoes): item_val = self.value_of_wearable(item) if (item_val > self.value_of_wearable(shoes)): self.logger.info( "Equipping shoes at index {} with stats: {}".format( i, self.get_item_stats_str(item))) return decisions.equip_item(i) elif item_val < self.value_of_wearable(shoes): self.logger.info("Dropping shoes at {}".format(i)) return decisions.drop_item(i) elif isinstance(item, Accessory): item_val = self.value_of_wearable(item) if (item_val > self.value_of_wearable(accessory)): self.logger.info( "Equipping accessory at index {} with stats: {}". format(i, self.get_item_stats_str(item))) return decisions.equip_item(i) elif item_val < self.value_of_wearable(accessory): self.logger.info("Dropping accessory at {}".format(i)) return decisions.drop_item(i) # BFS search around for stuff deltas_128 = bfs_deltas[128] best_gears_found: dict[str, Wearable] = { 'weapon': None, 'clothes': None, 'shoes': None, 'hat': None, 'accessory': None, 'con': None, } best_gears_found_pos: dict[str, Position] = { 'weapon': None, 'clothes': None, 'shoes': None, 'hat': None, 'accessory': None, 'con': None, } best_gears_found_index: dict[str, Position] = { 'weapon': None, 'clothes': None, 'shoes': None, 'hat': None, 'accessory': None, 'con': None, } for delta in deltas_128: dx = delta[0] dy = delta[1] check_pos = self.create_pos(self.curr_pos.x + dx, self.curr_pos.y + dy) # self.logger.info("Checking " + self.get_position_str(check_pos)) if (check_pos.x >= self.player_board.width or check_pos.x < 0 or check_pos.y < 0 or check_pos.y >= self.player_board.height): continue # self.logger.info("in map") tile: Tile = self.player_board.get_tile_at(check_pos) items_on_tile = tile.get_items() # search for better items for i, item in enumerate(items_on_tile): self.logger.info("At " + self.get_position_str(check_pos) + ", item - " + self.get_item_stats_str(item)) if isinstance(item, Consumable): con: Consumable = item if (con.effect.turns_left > 4): best_gears_found['con'] = con best_gears_found_index['con'] = i best_gears_found_pos['con'] = check_pos elif isinstance(item, Wearable): time_to_delete = item.turns_to_deletion if (self.curr_pos.manhattan_distance(check_pos) >= time_to_delete - 2): continue if isinstance(item, Weapon): self.logger.info("Found weapon") # dont pick up weapons that take too long to retrieve # best weapon to pickup is one that deals more damage, and more damage than all weapons on map that are found item_val = self.value_of_wearable(item) if (item_val > self.value_of_wearable(weapon)): if (best_gears_found['weapon'] == None or item_val > self.value_of_wearable( best_gears_found['weapon'])): best_gears_found['weapon'] = item best_gears_found_pos['weapon'] = check_pos best_gears_found_index['weapon'] = i elif isinstance(item, Clothes): item_val = self.value_of_wearable(item) if item_val > self.value_of_wearable(clothes): if (best_gears_found['clothes'] == None or item_val > self.value_of_wearable( best_gears_found['clothes'])): best_gears_found['clothes'] = item best_gears_found_pos['clothes'] = check_pos best_gears_found_index['clothes'] = i elif isinstance(item, Shoes): item_val = self.value_of_wearable(item) if item_val > self.value_of_wearable(shoes): if (best_gears_found['shoes'] == None or item_val > self.value_of_wearable( best_gears_found['shoes'])): best_gears_found['shoes'] = item best_gears_found_pos['shoes'] = check_pos best_gears_found_index['shoes'] = i elif isinstance(item, Hat): item_val = self.value_of_wearable(item) if item_val > self.value_of_wearable(hat): if (best_gears_found['hat'] == None or item_val > self.value_of_wearable( best_gears_found['hat'])): best_gears_found['hat'] = item best_gears_found_pos['hat'] = check_pos best_gears_found_index['hat'] = i elif isinstance(item, Accessory): item_val = self.value_of_wearable(item) if item_val > self.value_of_wearable(accessory): if (best_gears_found['accessory'] == None or item_val > self.value_of_wearable( best_gears_found['accessory'])): best_gears_found['accessory'] = item best_gears_found_pos['accessory'] = check_pos best_gears_found_index['accessory'] = i gears_to_pickup = 0 for i, (k, v) in enumerate(best_gears_found.items()): item: Wearable = v if item != None: gears_to_pickup += 1 if isinstance(item, Weapon): self.logger.info("best gear: weapon, ATK {}".format( item.attack)) else: self.logger.info("best gear: {}".format( self.get_item_stats_str(item))) # analyze enemies, remove those that would kill us sorted_difficulty_enemies: list[Monster] = self.get_all_enemies( self.curr_pos) enemies: list[Monster] = [] dangerous_pos_hashes: set[int] = set() for enemy in sorted_difficulty_enemies: m_health = enemy.get_current_health() m_attack = enemy.get_attack() m_wep_attack = enemy.get_weapon().get_attack() m_defence = enemy.get_defense() p_wep_attack = weapon.get_attack() p_attack = self.my_player.get_attack() p_defence = self.my_player.get_defense() p_health = self.my_player.get_current_health() m_damage_per_turn = m_wep_attack * ((25 + m_attack) / 100) m_actual_damage_per_turn = math.ceil(m_damage_per_turn - min(p_defence, 0.8 * m_damage_per_turn)) p_damage_per_turn = p_wep_attack * ((75 + p_attack) / 100) p_actual_damage_per_turn = math.ceil(p_damage_per_turn - min(m_defence, 0.8 * p_damage_per_turn)) # self.logger.info("Monster at {} deals {} dmg/turn; atk:{}, p_def:".format(self.get_position_str(enemy.get_position()), m_actual_damage_per_turn, m_attack, p_defence)) # self.logger.info("Player deals {} dmg/turn".format(p_actual_damage_per_turn)) enemy_turns_to_win = p_health / m_actual_damage_per_turn my_turns_to_win = m_health / p_actual_damage_per_turn if (my_turns_to_win < enemy_turns_to_win - 1): enemies.append(enemy) else: if (enemy.position.manhattan_distance(self.curr_pos) > 2): dangerous_pos_hashes.add(self.hash_pos(enemy.position)) deltas = [(0, 1), (-1, 0), (0, -1), (1, 0)] # TODO: dont hardcode aggro range and the deltas to use if enemy.get_aggro_range() > 1: deltas = bfs_deltas[4] else: deltas = bfs_deltas[1] for delta in deltas: dx = delta[0] dy = delta[1] check_pos: Position = self.create_pos( enemy.position.x + dx, enemy.position.y + dy) # tile: Tile = self.player_board.get_tile_at(check_pos) dangerous_pos_hashes.add(self.hash_pos(check_pos)) if (len(enemies) == 0): self.logger.info("no killable enemies found, resting") self.role = roles.REST if (gears_to_pickup > 0): self.role = roles.PICK_UP_GEAR pass # if last_action is not None and last_action == "PICKUP": # self.memory.set_value("last_action", "EQUIP") # self.logger.info("Equipping item") # return CharacterDecision( # decision_type="EQUIP", # action_position=0, # action_index=self.my_player.get_free_inventory_index() # ) self.logger.info("Picking up maybe") tile_items = self.player_board.get_tile_at(self.curr_pos).items self.logger.info("Items on position: " + str(len(tile_items))) # if tile_items is not None or len(tile_items) > 0: # self.logger.info("Picking up item") # self.memory.set_value("last_action", "PICKUP") # return CharacterDecision( # decision_type="PICKUP", # action_position=None, # action_index=0 # ) self.logger.info("====ROLE " + self.role + "====") if (self.role == roles.REST): sp = self.my_player.get_spawn_point() path = self.get_path(self.curr_pos, sp, dangerous_pos_hashes) self.logger.info("Moving to " + self.get_position_str(path[0]) + " to get to spawn point to rest at " + self.get_position_str(sp)) path_index = min( max(self.my_player.get_speed(), 1) - 1, len(path) - 1) decision = decisions.move(path[path_index]) self.logger.info("Moving!") return decision elif (self.role == roles.PICK_UP_GEAR): target_pos = self.curr_pos target_index = 0 for i, (k, v) in enumerate(best_gears_found.items()): item: Wearable = v if item != None: target_pos = best_gears_found_pos[k] target_index = best_gears_found_index[k] break if (self.equal_pos(target_pos, self.curr_pos)): self.logger.info( "Picking up gear under player with index {}".format( target_index)) decision = decisions.pick_up_item(target_index) return decision self.logger.info("Moving to pick up gear at " + self.get_position_str(target_pos) + ", index: " + str(target_index)) path = self.get_path(self.curr_pos, target_pos, dangerous_pos_hashes) path_index = min( max(self.my_player.get_speed(), 1) - 1, len(path) - 1) decision = decisions.move(path[path_index]) return decision elif (self.role == roles.GAIN_XP): self.logger.info("Moving to enemy maybe") self.logger.info("Found " + str(len(enemies)) + " enemies") if enemies is None or len(enemies) > 0: enemy_pos = enemies[0].position self.logger.info("Closest enemy at " + self.get_position_str(enemy_pos)) if weapon.get_range() >= self.curr_pos.manhattan_distance( enemy_pos): self.logger.info("Enemy at " + self.get_position_str(enemy_pos) + " within range to attack") return decisions.attack_monster(enemies[0]) path = self.get_path(self.curr_pos, enemies[0].position, dangerous_pos_hashes) path_index = min( max(self.my_player.get_speed(), 1) - 1, len(path) - 1) next_pos = path[path_index] self.logger.info("Moving to enemy " + str(self.get_position_str(next_pos))) return decisions.move(next_pos) self.logger.info("Moving maybe") self.memory.set_value("last_action", "MOVE") move_pos = self.pick_open_spot_to_move() self.logger.info("MovePos: " + self.get_position_str(move_pos)) decision = decisions.move(move_pos) self.logger.info("Moving!") return decision