mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-27 22:45:28 +00:00
Fixed Formula AI parsing bug and cleaned up sample script
This commit is contained in:
parent
b88a607bdc
commit
2e77800a49
@ -24,42 +24,74 @@ def opening(ai*)
|
||||
recruit('Skeleton Archer', loc(11,21)) ],
|
||||
if(turn = 4, [
|
||||
recruit('Skeleton Archer', loc(11,21)) ],
|
||||
[])))); def rate_position_defensiveness(ai*,src,dst)
|
||||
units_can_reach(ai.my_moves, dst).size - units_can_reach(ai.enemy_moves, dst).size; def rate_position_danger(ai*,unit,dst)
|
||||
(100*sum(map(units_can_reach(ai.enemy_moves, dst), 'enemy', max_possible_damage(enemy, unit)*defense_on(unit, dst))))
|
||||
/ unit.hitpoints; def build_attacks(attack_move)
|
||||
[]))));
|
||||
|
||||
def rate_position_defensiveness(ai*,src,dst)
|
||||
units_can_reach(ai.my_moves, dst).size - units_can_reach(ai.enemy_moves, dst).size;
|
||||
|
||||
def rate_position_danger(ai*,unit,dst)
|
||||
(100*sum(map(units_can_reach(ai.enemy_moves, dst), 'enemy', max_possible_damage(enemy, unit)*defense_on(unit, dst)))) / unit.hitpoints;
|
||||
|
||||
def build_attacks(attack_move)
|
||||
if(attack_move,
|
||||
map(attack_move.movements, attack(src, dst, attack_move.target)),
|
||||
[]); def targets(ai)
|
||||
ai.enemy_and_unowned_villages; def distance_to_target(ai,dst)
|
||||
min(map(targets(ai), distance_between(dst, self))); def move_to_targets(ai*)
|
||||
ai.enemy_and_unowned_villages;
|
||||
|
||||
def distance_to_target(ai,dst)
|
||||
min(map(targets(ai), distance_between(dst, self)));
|
||||
|
||||
def move_to_targets(ai*)
|
||||
find(moves, src != my_leader.loc and rate_position_defensiveness(ai, src, dst) > 0)
|
||||
where moves = sort(my_moves.moves, distance_to_target(ai, a.dst) < distance_to_target(ai, b.dst)); def get_village_captures(ai)
|
||||
sum(map(ai.enemy_and_unowned_villages, 'village', map(units_can_reach(ai.my_moves, village), move(loc, village))), []); def get_village_garrisons(ai*)
|
||||
sum(map(my_villages, 'village', map(units_can_reach(ai.my_moves, village), move(loc, village))), []); def uncontended_captures(ai)
|
||||
filter(get_village_captures(ai), (src != ai.my_leader.loc) and (units_can_reach(ai.enemy_moves, dst).empty)); def move_to_keep(ai*)
|
||||
where moves = sort(my_moves.moves, distance_to_target(ai, a.dst) < distance_to_target(ai, b.dst));
|
||||
|
||||
def get_village_captures(ai)
|
||||
sum(map(ai.enemy_and_unowned_villages, 'village', map(units_can_reach(ai.my_moves, village), move(loc, village))), []);
|
||||
|
||||
def get_village_garrisons(ai*)
|
||||
sum(map(my_villages, 'village', map(units_can_reach(ai.my_moves, village), move(loc, village))), []);
|
||||
|
||||
def uncontended_captures(ai)
|
||||
filter(get_village_captures(ai), (src != ai.my_leader.loc) and (units_can_reach(ai.enemy_moves, dst).empty));
|
||||
|
||||
def move_to_keep(ai*)
|
||||
if(keep_in_range,
|
||||
move(my_leader.loc, keep_in_range),
|
||||
null())
|
||||
where keep_in_range = find(unit_moves(my_leader.loc), 'moveto', find(keeps, moveto = self)); def village_value(ai*) 400; def rate_healing(unit*)
|
||||
value * ((min(max_hitpoints - hitpoints, 8)*100)/max_hitpoints); def rate_village_garrison(ai*, move_from, village)
|
||||
where keep_in_range = find(unit_moves(my_leader.loc), 'moveto', find(keeps, moveto = self));
|
||||
|
||||
def village_value(ai*) 400;
|
||||
|
||||
def rate_healing(unit*)
|
||||
value * ((min(max_hitpoints - hitpoints, 8)*100)/max_hitpoints);
|
||||
|
||||
def rate_village_garrison(ai*, move_from, village)
|
||||
if(find(enemy_moves, dst = village),
|
||||
village_value(ai),
|
||||
0); def rate_village_capture(ai*,src,dst) village_value(ai); def
|
||||
rate_village_proximity(ai*, unit, dst)
|
||||
0);
|
||||
|
||||
def rate_village_capture(ai*,src,dst) village_value(ai);
|
||||
|
||||
def rate_village_proximity(ai*, unit, dst)
|
||||
if(distance = 1,
|
||||
0,
|
||||
village_value(ai)/(distance/unit.total_movement + 1))
|
||||
where distance = distance_to_nearest_unowned_village(dst); def rate_move(ai*,src,dst)
|
||||
where distance = distance_to_nearest_unowned_village(dst);
|
||||
|
||||
def rate_move(ai*,src,dst)
|
||||
if(is_village(map, dst),
|
||||
rate_healing(u) + if(find(my_villages, self = dst),
|
||||
rate_village_garrison(ai, src, dst),
|
||||
rate_village_capture(ai, src, dst)),
|
||||
rate_village_proximity(ai, u, dst)) - (danger*u.value)/2
|
||||
where u = unit_at(src), danger = rate_position_danger(ai, unit_at(src), dst); def rate_attack(ai*,attack)
|
||||
where u = unit_at(src), danger = rate_position_danger(ai, unit_at(src), dst);
|
||||
|
||||
def rate_attack(ai*,attack)
|
||||
if(attack,
|
||||
(attack.chance_to_kill*attack.target_value + (((attack.avg_damage_inflicted*100)/unit_at(attack.target).max_hitpoints)*attack.target_value) + sum(map(attack.movements, rate_move(ai, src, dst))))/attack.movements.size,
|
||||
null()); def get_best_move(ai*, candidate_moves)
|
||||
null());
|
||||
|
||||
def get_best_move(ai*, candidate_moves)
|
||||
if(rate_attack(ai, best_attack) >
|
||||
if(best_move, rate_move(ai, best_move.src,
|
||||
best_move.dst),
|
||||
@ -67,9 +99,16 @@ def opening(ai*)
|
||||
build_attacks(best_attack),
|
||||
[best_move])
|
||||
where best_attack = choose(attacks, rate_attack(ai, self)),
|
||||
best_move = choose(candidate_moves, rate_move(ai, src, dst)); def move_leader_to_keep(ai*)
|
||||
best_move = choose(candidate_moves, rate_move(ai, src, dst));
|
||||
|
||||
def move_leader_to_keep(ai*)
|
||||
if(dest,
|
||||
[move(my_leader.loc, dest)],
|
||||
[])
|
||||
where dest = find(unit_moves(my_leader.loc), 'dst', find(keeps, 'keep', keep = dst)); if(vars.done_opening != 1, [set_var('done_opening', 1)] + opening(self),
|
||||
if(my_leader.loc and find(keeps, self = my_leader.loc) = null(), move_leader_to_keep(self), []) + get_best_move(self, filter(my_moves.moves, src != my_leader.loc)) + [ recruit('Skeleton Archer', loc(11,21)), recruit('Dark Adept', loc(11,22)) ])
|
||||
where dest = find(unit_moves(my_leader.loc), 'dst', find(keeps, 'keep', keep = dst));
|
||||
|
||||
if(vars.done_opening != 1,
|
||||
[set_var('done_opening', 1)] + opening(self),
|
||||
if(my_leader.loc and find(keeps, self = my_leader.loc) = null(),
|
||||
move_leader_to_keep(self),
|
||||
[]) + get_best_move(self, filter(my_moves.moves, src != my_leader.loc)) + [ recruit('Skeleton Archer', loc(11,21)), recruit('Dark Adept', loc(11,22)) ])
|
||||
|
@ -51,7 +51,7 @@ token_type token_types[] = { { regex("^(not\\b|and\\b|or\\b|where\\b|d(?=[^a-zA-
|
||||
token get_token(iterator& i1, iterator i2) {
|
||||
foreach(const token_type& t, token_types) {
|
||||
boost::smatch match;
|
||||
if(boost::regex_search(i1, i2, match, t.re)) {
|
||||
if(boost::regex_search(i1, i2, match, t.re, boost::match_single_line)) {
|
||||
token res;
|
||||
res.type = t.type;
|
||||
res.begin = i1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user