add new distance functions to formula AI, patch 1033 by Alesis Novik

This commit is contained in:
Jérémy Rosen 2008-03-30 21:13:49 +00:00
parent f0715e3215
commit 71a3a1b794
4 changed files with 66 additions and 0 deletions

View file

@ -624,6 +624,10 @@
[about]
title = _"Miscellaneous contributors"
[entry]
name = "Alesis Novik"
[/entry]
[entry]
name = "Andrea Palmatè (afxgroup)"
[/entry]

View file

@ -148,6 +148,33 @@ private:
const formula_ai& ai_;
};
class close_enemies_function : public function_expression {
public:
close_enemies_function(const args_list& args, const formula_ai& ai)
: function_expression("close_enemies", args, 2, 2), ai_(ai) {
}
private:
variant execute(const formula_callable& variables) const {
std::vector<variant> vars;
const gamemap::location loc = convert_variant<location_callable>(args()[0]->evaluate(variables))->loc();
int range = args()[1]->evaluate(variables).as_int();
unit_map::const_iterator un = ai_.get_info().units.begin();
unit_map::const_iterator end = ai_.get_info().units.end();
while (un != end) {
if (distance_between(loc, un->first) <= range) {
if (un->second.side() != ai_.get_info().team_num) {
vars.push_back(variant(new unit_callable(*un, ai_.current_team(), un->second.side())));
}
}
++un;
}
return variant(&vars);
}
const formula_ai& ai_;
};
class outcomes_function : public function_expression {
public:
outcomes_function(const args_list& args, const formula_ai& ai)
@ -563,6 +590,8 @@ class ai_function_symbol_table : public function_symbol_table {
return expression_ptr(new distance_to_nearest_unowned_village_function(args, ai_));
} else if(fn == "nearest_keep") {
return expression_ptr(new nearest_keep_function(args, ai_));
} else if(fn == "close_enemies") {
return expression_ptr(new close_enemies_function(args, ai_));
} else if(fn == "distance_between") {
return expression_ptr(new distance_between_function(args));
} else {

View file

@ -57,6 +57,30 @@ void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res)
res->y = a.y - (is_even(a.x) ? 1:0);
}
void get_tile_ring(const gamemap::location& a, const int r, std::vector<gamemap::location>& res)
{
if(r <= 0) {
return;
}
gamemap::location loc = a.get_direction(gamemap::location::SOUTH_WEST, r);
for(int n = 0; n != 6; ++n) {
const gamemap::location::DIRECTION dir = static_cast<gamemap::location::DIRECTION>(n);
for(int i = 0; i != r; ++i) {
res.push_back(loc);
loc = loc.get_direction(dir, 1);
}
}
}
void get_tiles_in_radius(const gamemap::location& a, const int r, std::vector<gamemap::location>& res)
{
for(int n = 0; n <= r; ++n) {
get_tile_ring(a, n, res);
}
}
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
{
// Two tiles are adjacent:

View file

@ -27,6 +27,15 @@ bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b);
//! res must point to an array of 6 location objects.
void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res);
//! Function which, given a location, will place all locations in a ring of
//! distance r in res. res must be a std::vector of location
void get_tile_ring(const gamemap::location& a, const int r, std::vector<gamemap::location>& res);
//! Function which, given a location, will place all locations in the radius of r in res
//! res must be a std::vector of location
void get_tiles_in_radius(const gamemap::location& a, const int r, std::vector<gamemap::location>& res);
//! Function which gives the number of hexes between two tiles
//! (i.e. the minimum number of hexes that have to be traversed
//! to get from one hex to the other).