Exemplo n.º 1
0
boost::shared_ptr<attacks_vector> aspect_attacks::analyze_targets() const
{
    const move_map& srcdst = get_srcdst();
    const move_map& dstsrc = get_dstsrc();
    const move_map& enemy_srcdst = get_enemy_srcdst();
    const move_map& enemy_dstsrc = get_enemy_dstsrc();

    boost::shared_ptr<attacks_vector> res(new attacks_vector());
    unit_map& units_ = *resources::units;

    std::vector<map_location> unit_locs;
    for(unit_map::const_iterator i = units_.begin(); i != units_.end(); ++i) {
        if (i->side() == get_side() && i->attacks_left() && !(i->can_recruit() && get_passive_leader())) {
            if (!i->matches_filter(vconfig(filter_own_), i->get_location())) {
                continue;
            }
            unit_locs.push_back(i->get_location());
        }
    }

    bool used_locations[6];
    std::fill(used_locations,used_locations+6,false);

    moves_map dummy_moves;
    move_map fullmove_srcdst, fullmove_dstsrc;
    calculate_possible_moves(dummy_moves,fullmove_srcdst,fullmove_dstsrc,false,true);

    unit_stats_cache().clear();

    for(unit_map::const_iterator j = units_.begin(); j != units_.end(); ++j) {

        // Attack anyone who is on the enemy side,
        // and who is not invisible or petrified.
        if (current_team().is_enemy(j->side()) && !j->incapacitated() &&
                !j->invisible(j->get_location()))
        {
            if (!j->matches_filter(vconfig(filter_enemy_), j->get_location())) {
                continue;
            }
            map_location adjacent[6];
            get_adjacent_tiles(j->get_location(), adjacent);
            attack_analysis analysis;
            analysis.target = j->get_location();
            analysis.vulnerability = 0.0;
            analysis.support = 0.0;
            do_attack_analysis(j->get_location(), srcdst, dstsrc,
                               fullmove_srcdst, fullmove_dstsrc, enemy_srcdst, enemy_dstsrc,
                               adjacent,used_locations,unit_locs,*res,analysis, current_team());
        }
    }
    return res;
}
Exemplo n.º 2
0
std::vector<target> default_ai_context_impl::find_targets(const move_map& enemy_dstsrc)
{

	log_scope2(log_ai, "finding targets...");
	unit_map &units_ = resources::gameboard->units();
	unit_map::iterator leader = units_.find_leader(get_side());
	const gamemap &map_ = resources::gameboard->map();
	std::vector<team> teams_ = resources::gameboard->teams();
	const bool has_leader = leader != units_.end();

	std::vector<target> targets;

	//=== start getting targets

	//if enemy units are in range of the leader, then we target the enemies who are in range.
	if(has_leader) {
		double threat = power_projection(leader->get_location(), enemy_dstsrc);
		if(threat > 0.0) {
			//find the location of enemy threats
			std::set<map_location> threats;

			map_location adj[6];
			get_adjacent_tiles(leader->get_location(), adj);
			for(size_t n = 0; n != 6; ++n) {
				std::pair<move_map::const_iterator,move_map::const_iterator> itors = enemy_dstsrc.equal_range(adj[n]);
				while(itors.first != itors.second) {
					if(units_.count(itors.first->second)) {
						threats.insert(itors.first->second);
					}

					++itors.first;
				}
			}

			assert(threats.empty() == false);

			const double value = threat/double(threats.size());
			for(std::set<map_location>::const_iterator i = threats.begin(); i != threats.end(); ++i) {
				LOG_AI << "found threat target... " << *i << " with value: " << value << "\n";
				targets.push_back(target(*i,value,target::TYPE::THREAT));
			}
		}
	}

	double corner_distance = distance_between(map_location::ZERO(), map_location(map_.w(),map_.h()));
	double village_value = get_village_value();
	if(has_leader && village_value > 0.0) {
		std::map<map_location,pathfind::paths> friends_possible_moves;
		move_map friends_srcdst, friends_dstsrc;
		calculate_possible_moves(friends_possible_moves, friends_srcdst, friends_dstsrc, false, true);

		const std::vector<map_location>& villages = map_.villages();
		for(std::vector<map_location>::const_iterator t =
				villages.begin(); t != villages.end(); ++t) {

			assert(map_.on_board(*t));
			bool ally_village = false;
			for (size_t i = 0; i != teams_.size(); ++i)
			{
				if (!current_team().is_enemy(i + 1) && teams_[i].owns_village(*t)) {
					ally_village = true;
					break;
				}
			}

			if (ally_village)
			{
				//Support seems to cause the AI to just 'sit around' a lot, so
				//only turn it on if it's explicitly enabled.
				if(get_support_villages()) {
					double enemy = power_projection(*t, enemy_dstsrc);
					if (enemy > 0)
					{
						enemy *= 1.7;
						double our = power_projection(*t, friends_dstsrc);
						double value = village_value * our / enemy;
						add_target(target(*t, value, target::TYPE::SUPPORT));
					}
				}
			}
			else
			{
				double leader_distance = distance_between(*t, leader->get_location());
				double value = village_value * (1.0 - leader_distance / corner_distance);
				LOG_AI << "found village target... " << *t
					<< " with value: " << value
					<< " distance: " << leader_distance << '\n';
				targets.push_back(target(*t,value,target::TYPE::VILLAGE));
			}
		}
	}

	std::vector<goal_ptr>& goals = get_goals();

	//find the enemy leaders and explicit targets
	unit_map::const_iterator u;
	if (get_leader_value()>0.0) {
		for(u = units_.begin(); u != units_.end(); ++u) {
			//is a visible enemy leader
			if (u->can_recruit() && current_team().is_enemy(u->side())
			    && !u->invisible(u->get_location(), *resources::gameboard)) {
				assert(map_.on_board(u->get_location()));
				LOG_AI << "found enemy leader (side: " << u->side() << ") target... " << u->get_location() << " with value: " << get_leader_value() << "\n";
				targets.push_back(target(u->get_location(), get_leader_value(), target::TYPE::LEADER));
			}
		}

	}

	//explicit targets for this team
	for(std::vector<goal_ptr>::iterator j = goals.begin();
	    j != goals.end(); ++j) {

		if (!(*j)->active()) {
			continue;
		}
		(*j)->add_targets(std::back_inserter(targets));

	}

	//=== end getting targets

	std::vector<double> new_values;

	for(std::vector<target>::iterator i = targets.begin();
	    i != targets.end(); ++i) {

		new_values.push_back(i->value);

		for(std::vector<target>::const_iterator j = targets.begin(); j != targets.end(); ++j) {
			if(i->loc == j->loc) {
				continue;
			}

			const double distance = std::abs(j->loc.x - i->loc.x) +
						std::abs(j->loc.y - i->loc.y);
			new_values.back() += j->value/(distance*distance);
		}
	}

	assert(new_values.size() == targets.size());
	for(size_t n = 0; n != new_values.size(); ++n) {
		LOG_AI << "target value: " << targets[n].value << " -> " << new_values[n] << "\n";
		targets[n].value = new_values[n];
	}

	return targets;
}