示例#1
0
    def evaluate_army_movement(self, ai_stat: AI_GameStatus, move: AI_Move):
        if len(ai_stat.map.army_list) == 0:
            return
        target_str = ""
        self.previous_attack_target = None
        if self.state == AI_Mazedonian.AI_State.PASSIVE:
            # for now, just move it out of the way.
            army_is_on_field = False
            if ai_stat.map.army_list[0].base_tile in ai_stat.map.own_farm_field_tiles:
                army_is_on_field = True
            if not army_is_on_field:
                has_farm = False
                for b in ai_stat.map.building_list:
                    if b.type == BuildingType.FARM:
                        has_farm = True
                if has_farm:
                    # walk to random field
                    path = []
                    idx = random.randint(0, len(ai_stat.map.own_farm_field_tiles) - 1)
                    # print(f"from: {ai_stat.map.army_list[0].base_tile.offset_coordinates} to {ai_stat.map.own_farm_field_tiles[idx].offset_coordinates}")
                    path = essentials.a_star(ai_stat.map.army_list[0].base_tile,
                                                  ai_stat.map.own_farm_field_tiles[idx],
                                                  ai_stat.map.walkable_tiles)
                    if len(path) > 1:
                        move.move_army_to = path[1].offset_coordinates
                        move.doMoveArmy = True
                        target_str = "corn field"

        #elif self.state == AI_Mazedonian.AI_State.DEFENSIVE or self.state == AI_Mazedonian.AI_State.AGGRESSIVE:
        else:
            if len(self.priolist_targets) > 0:
                if self.threshold_target_value <= self.priolist_targets[0].weighted_score:
                    # hint("on warpath: {} {}".format(self.threshold_target_value, self.priolist_targets[0].score))
                    # attack
                    start_tile = ai_stat.map.army_list[0].base_tile
                    target_tile = self.priolist_targets[0].target.base_tile
                    path = essentials.a_star(start_tile, target_tile, ai_stat.map.walkable_tiles)
                    if len(path) > 1:
                        self.previous_attack_target = self.priolist_targets[0]
                        move.move_army_to = path[1].offset_coordinates
                        move.doMoveArmy = True
                        target = self.priolist_targets[0]
                        s = "army" if type(target.target) is AI_Army else "building"
                        target_str = f"Movement: target: {s} @ loc: {target.target.offset_coordinates}"
                        if BASIC_DEBUG:
                            self._dump('moving to: {} from {} to {}'.format(str(move.move_army_to),
                                                                      start_tile.offset_coordinates,
                                                                      target_tile.offset_coordinates))
                else:
                    self._dump("targets value to low. Will not attack")
        if move.doMoveArmy:
            self._dump(target_str)
示例#2
0
 def play_players_turn(self, player: Player):
     """wrapper function, extends the main update loop"""
     # debug(f"Play move of player {player.name} [pid: {player.id}]")
     self.updata_map()
     if self.check_win_condition(player):
         self.winner = player
     self.update_player_properties(player)
     player.has_lost = self.check_lose_condition(player)
     if player.has_lost:
         self.destroy_player(player)
         return
     if player.player_type == PlayerType.HUMAN:
         ai_game_status = AI_GameStatus()
         self.construct_game_status(player, ai_game_status)
         ai_move = AI_Move()
         self.human_interface.request_move(ai_game_status, ai_move,
                                           player.id)
     else:
         ai_worker = threading.Thread(target=self.spawn_ai_thread,
                                      args=(player, ))
         ai_worker.start()
示例#3
0
    def weight_options(self, options: List[Option], ai_stat: AI_GameStatus, move: AI_Move):
        used_weights: List[str] = []
        for opt in options:                 # --------------------- Action options ----------
            opt.weighted_score = opt.score.value
            if opt.score == Priority.P_NO:  # no option (should not depend on weights) -> contain invalid info
                continue
            for w in self.weights:
                if w.condition(opt, ai_stat):
                    used_weights.append(w.condition.__name__)
                    if DETAILED_DEBUG:
                        self._dump(f"Weight w: {w.weight} applied on score: {opt.weighted_score} of {type(opt)} ")
                    opt.weighted_score = opt.weighted_score + w.weight

        used_weights.append(" | ")

        for m in self.priolist_targets:         # --------------------- Movement options ----------
            if m.score == Priority.P_NO:
                continue
            for w in self.m_weights:
                if w.condition(m, ai_stat):
                    used_weights.append(w.condition.__name__)
                    m.weighted_score = m.weighted_score + w.weight

        options.sort(key=lambda x: x.weighted_score, reverse=True)
        self.priolist_targets.sort(key=lambda x: x.weighted_score, reverse=True)

        self._dump("---")
        for opt in options:
            s = f"\tOption of type: {type(opt)}, score: {opt.weighted_score}"
            if type(opt) == RecruitmentOption or type(opt) == BuildOption:
                s = s + f", type {opt.type}"
            if type(opt) == ScoutingOption:
                s = s + f", site: {opt.site}"
            s = s + f", former priority: {opt.score}"
            self._dump(s)
        for m in self.priolist_targets:
            s = f"\tAttack Target : {'army' if type(m.target) is AI_Army else 'building'}, score: {m.weighted_score}"
            self._dump(s)
        s_tmp = ""
        for w in used_weights:
            s_tmp += w + ", "
        self._dump(s_tmp)
        # translate this into move
        best_option: Option = options[0]
        if type(best_option) == WaitOption:
            move.move_type = MoveType.DO_NOTHING
            move.str_rep_of_action = "waiting"
        elif type(best_option) == BuildOption:
            move.move_type = MoveType.DO_BUILD
            move.loc = best_option.site
            move.type = best_option.type
            for at in best_option.associated_tiles:
                move.info.append(at)
            s_tmp = f"building a {best_option.type} at {str(move.loc)} ({str(best_option.cardinal_direction)})"
            if move.type == BuildingType.FARM:
                s_tmp += f" TL: {str(best_option.threat_level)}"
            move.str_rep_of_action = s_tmp
        elif type(best_option) == RecruitmentOption:
            move.move_type = MoveType.DO_RECRUIT_UNIT
            move.type = best_option.type
            move.str_rep_of_action = f"recruiting a {best_option.type}"
        elif type(best_option) == ScoutingOption:
            move.move_type = MoveType.DO_SCOUT
            move.loc = best_option.site
            move.str_rep_of_action = "scouting at" + str(move.loc)
        elif type(best_option) == AI_Mazedonian.RaiseArmyOption:
            move.move_type = MoveType.DO_RAISE_ARMY
            move.loc = self.get_army_spawn_loc(ai_stat)
            move.str_rep_of_action = "raising new army at"
        elif type(best_option) is UpgradeOption:
            move.move_type = MoveType.DO_UPGRADE_BUILDING
            move.loc = best_option.site
            move.type = best_option.type
            move.str_rep_of_action = "upgrading hut to villa"
        else:
            error("unexpected type")

        self._dump(f"DECISION: {move.str_rep_of_action}")
示例#4
0
 def evaluate_trades(self, ai_stat: AI_GameStatus, move: AI_Move):
     for trade in ai_stat.trades:
         for decision in self.trade_decisions:
             decision(trade, ai_stat)
     move.trades = ai_stat.trades
示例#5
0
 def spawn_ai_thread(self, player):
     ai_game_status = AI_GameStatus()
     ai_move = AI_Move()
     self.construct_game_status(player, ai_game_status)
     self.ai_interface.do_a_move(ai_game_status, ai_move, player.id)
示例#6
0
    def weight_options(self, ai_stat: AI_GameStatus, move: AI_Move,
                       all_options: List[Union[BuildOption, RecruitmentOption,
                                               RaiseArmyOption, WaitOption]],
                       movement_options: List[ArmyMovementOption]):
        used_weights: List[str] = []
        for opt in all_options:  # --------------------- Action options ----------
            if opt.score == Priority.P_NO:
                continue
            opt.weighted_score = opt.score.value
            for w in self.weights:
                if w.condition(opt, ai_stat):
                    used_weights.append(w.condition.__name__)
                    opt.weighted_score = opt.weighted_score + w.weight

        used_weights.append(" | ")

        for opt in movement_options:  # --------------------- Movement options ----------
            if opt.score == Priority.P_NO:
                continue
            opt.weighted_score = opt.score.value
            for w in self.m_weights:
                if w.condition(opt, ai_stat):
                    used_weights.append(w.condition.__name__)
                    opt.weighted_score = opt.weighted_score + w.weight

        all_options.sort(key=lambda x: x.weighted_score, reverse=True)
        movement_options.sort(key=lambda x: x.weighted_score, reverse=True)

        if len(all_options) > 0:
            best_option = all_options[0]
            if type(best_option) == WaitOption:
                move.move_type = MoveType.DO_NOTHING
                move.str_rep_of_action = "waiting"
            elif type(best_option) == BuildOption:
                move.move_type = MoveType.DO_BUILD
                move.loc = best_option.site
                move.type = best_option.type
                move.str_rep_of_action = f"building a {best_option.type} at " + str(
                    move.loc)
            elif type(best_option) == UpgradeOption:
                move.move_type = MoveType.DO_UPGRADE_BUILDING
                move.loc = best_option.site
                move.type = best_option.type
                move.str_rep_of_action = f"upgrading building to {move.type}"
            elif type(best_option) == RecruitmentOption:
                move.move_type = MoveType.DO_RECRUIT_UNIT
                move.type = best_option.type
                move.str_rep_of_action = f"recruiting a {best_option.type}"
            elif type(best_option) == RaiseArmyOption:
                move.move_type = MoveType.DO_RAISE_ARMY
                move.loc = best_option.site
                move.str_rep_of_action = "raising new army at"
            else:
                error("unexpected type")
        if len(movement_options) > 0:
            best_m_option = movement_options[0]
            if best_m_option.weighted_score >= self.properties[
                    'threshold_army_movement']:
                move.move_army_to = best_m_option.next_step
                move.doMoveArmy = True

        for opt in all_options:
            s = f"Option of type {type(opt)}, score: {opt.weighted_score} ({opt.score})"
            if not (type(opt) == WaitOption or type(opt) == RaiseArmyOption):
                s = s + f" -> Type: {opt.type}"
            self._dump(s)
        for m_opt in movement_options:
            stmp = 'army' if type(m_opt.target) is AI_Army else ''
            stmp = 'building' if type(m_opt.target) is AI_Building else ''
            s = f"M-Option target: {type(m_opt)} target({stmp}), score: {m_opt.weighted_score} ({m_opt.score})"
            self._dump(s)

        s = f"DECISION: {move.str_rep_of_action}"
        if move.doMoveArmy:
            s += f" moving army to {move.move_army_to}"
        self._dump(s)