mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-15 09:02:30 +00:00
Add comments to data/ai/formula/new_recruitment.fai
This commit is contained in:
parent
03e9440fd3
commit
2965da1731
@ -4,16 +4,15 @@ fai 'new_recruitment.fai'
|
||||
{ai/formula/lib/util.fai}
|
||||
{ai/formula/lib/recruitment.fai}
|
||||
|
||||
# Returns a list of terrain types of the input list locations #
|
||||
def get_terrain_types(ai*, locations)
|
||||
map( locations, 'l', fast_map[l].id ) where fast_map = location_to_terrain_map(ai);
|
||||
|
||||
|
||||
# Returns a List of important vilages which are inside locations_map #
|
||||
def get_villages_on_terrain_map( ai*, locations_map )
|
||||
filter( villages, locations_map[self] );
|
||||
|
||||
#
|
||||
for now important locations are villages only
|
||||
#
|
||||
# Returns location_map with the area around important villages set to 1000 (radius 1) #
|
||||
def mark_important_locations(ai*, location_map )
|
||||
map( location_map,
|
||||
if( tmp_villages[key],
|
||||
@ -23,6 +22,8 @@ def mark_important_locations(ai*, location_map )
|
||||
)
|
||||
where tmp_villages = tomap( get_locations_surroundings( ai, get_villages_on_terrain_map( ai, location_map ), 1 ) );
|
||||
|
||||
|
||||
# Returns a list of ALL keys(locs) of side_terrain #
|
||||
def get_important_locations(ai* )
|
||||
keys(
|
||||
map( ai.vars.side_terrain,
|
||||
@ -30,6 +31,7 @@ def get_important_locations(ai* )
|
||||
)
|
||||
);
|
||||
|
||||
# Returns a list of all enemy leaders #
|
||||
def enemy_leaders( ai* )
|
||||
sum(
|
||||
map( enemies, 'enemy',
|
||||
@ -37,6 +39,9 @@ def enemy_leaders( ai* )
|
||||
)
|
||||
);
|
||||
|
||||
# Returns a Map #
|
||||
# Key is a ememy leader #
|
||||
# Value is the summed distace to all important hexes #
|
||||
def find_enemies_part( ai*, locations_map)
|
||||
tomap(
|
||||
enemy_leaders,
|
||||
@ -50,13 +55,14 @@ def find_enemies_part( ai*, locations_map)
|
||||
)
|
||||
where enemy_leaders = enemy_leaders( ai );
|
||||
|
||||
# Returns a List of those enemy leaders wich are near to the important locations #
|
||||
def find_enemies( ai*, locations_map)
|
||||
filter( keys(enemies_part), 'leader',
|
||||
enemies_part[leader] <= average( values( enemies_part ) )
|
||||
)
|
||||
where enemies_part = find_enemies_part( ai, locations_map );
|
||||
|
||||
|
||||
# Returns a List of all units of direct_enemies. #
|
||||
def direct_enemies_units( ai* )
|
||||
sum(
|
||||
map( vars.direct_enemies, 'enemy',
|
||||
@ -64,6 +70,7 @@ def direct_enemies_units( ai* )
|
||||
)
|
||||
);
|
||||
|
||||
# Returns a list of all recruits of direct_enemies. #
|
||||
def direct_enemies_recruits( ai* )
|
||||
sum(
|
||||
map( vars.direct_enemies, 'enemy',
|
||||
@ -71,14 +78,13 @@ def direct_enemies_recruits( ai* )
|
||||
)
|
||||
);
|
||||
|
||||
#
|
||||
returns map of important locations and number of their occurences on a gamemap
|
||||
for example: [ 'forest' -> 10 ]
|
||||
#
|
||||
# returns map of important locations and number of their occurences on a gamemap #
|
||||
# for example: [ 'forest' -> 10 ] #
|
||||
# all terrains inside side_terrain are considered. #
|
||||
def important_locations_map(ai*)
|
||||
tomap(get_terrain_types(ai, get_important_locations(ai)));
|
||||
|
||||
|
||||
# Returns a map. Key is unit-id of my_recruits. Value is sum of all defenses in all important_locs. #
|
||||
def my_recruits_defense(ai*)
|
||||
tomap( map(my_recruits, id),
|
||||
map( my_recruits, 'recruit',
|
||||
@ -90,6 +96,7 @@ def my_recruits_defense(ai*)
|
||||
where important_locs = important_locations_map(ai),
|
||||
id_translator = id_to_location_map(ai);
|
||||
|
||||
# Returns a map. Key is unit-id of my_recruits. Value is sum of all movent_costs in all important_locs. #
|
||||
def my_recruits_movement_cost(ai*)
|
||||
tomap( map(my_recruits, id),
|
||||
map( my_recruits, 'recruit',
|
||||
@ -101,66 +108,66 @@ def my_recruits_movement_cost(ai*)
|
||||
where important_locs = important_locations_map(ai),
|
||||
id_translator = id_to_location_map(ai);
|
||||
|
||||
# Highest Value is set to 100. All others below 100 according to ratio #
|
||||
def locally_normalize_to_highest( input_map )
|
||||
map( input_map, if(max=0,100,(value * 100)/max) )
|
||||
where max = highest_value(input_map);
|
||||
|
||||
# Lowest value is set to 100. All others over 100 according to ratio #
|
||||
def locally_normalize_to_lowest( input_map )
|
||||
map( input_map, if(min=0,100,(value * 100)/min) )
|
||||
where min = lowest_value(input_map);
|
||||
|
||||
|
||||
|
||||
# look for who we fight against #
|
||||
# Returns a List of all enemy leaders #
|
||||
# (for some reason this function is defined twice) #
|
||||
def enemy_leaders(ai*)
|
||||
map( enemies, 'enemy_side', find(units_of_side[enemy_side], leader ) );
|
||||
|
||||
|
||||
# UNUSED FUNCTION #
|
||||
# Returns a Map. #
|
||||
# Key is a enemy #
|
||||
# Value is the distance between my leader and enemies leader #
|
||||
def distance_to_enemies(ai*)
|
||||
tomap( enemies, map( enemy_leaders(ai), distance_between( my_leader.loc, loc ) ));
|
||||
|
||||
# not used anymore
|
||||
def find_important_opponents(ai*)
|
||||
keys(filter( dist_en, value<avg ))
|
||||
where avg = (average(values(distance_to_enemies(ai)))*11)/10,
|
||||
dist_en = distance_to_enemies(ai);
|
||||
|
||||
|
||||
def current_enemies_units(ai*)
|
||||
sum(map( find_important_opponents(ai), 'enemy_side',
|
||||
units_of_side[ enemy_side ] ));
|
||||
|
||||
def current_enemies_recruits(ai*)
|
||||
sum(map( find_important_opponents(ai), 'enemy_side',
|
||||
recruits_of_side[ enemy_side ] ));
|
||||
#
|
||||
|
||||
# Returns a list of enemy-units #
|
||||
# If number of units on the map is below 5 #
|
||||
# It'll return the recruits #
|
||||
def current_enemies(ai*)
|
||||
if( en_units.size > 5, en_units, en_recruis )
|
||||
where en_units = direct_enemies_units(ai),
|
||||
en_recruis = direct_enemies_recruits(ai);
|
||||
|
||||
|
||||
# Returns a integer. #
|
||||
# Returns the sum of 12 times the maximum attack damage for all enemy_units #
|
||||
def evaluate_attacker_against_opponents(ai*, unit, enemy_units)
|
||||
sum(
|
||||
map(
|
||||
enemy_units, 'enemy_unit',
|
||||
sum(
|
||||
sum( # sum over all 4 elements (which are the same). 3 * 4 = 12. #
|
||||
map(
|
||||
[
|
||||
max_possible_damage_with_retaliation( unit, enemy_unit )
|
||||
# gives [ <attacker_melee>, <attacker_ranged>, <defender_melee>, <defender_ranged> ] #
|
||||
],
|
||||
max(
|
||||
[
|
||||
self[0],
|
||||
self[1]
|
||||
]
|
||||
)*3
|
||||
)*3 # Replaces all 4 elements in the list with 3 times the maximum of self[0] and self[1]. #
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
# Returns a integer. #
|
||||
# Returns the sum of 20 times the maximum attack damage that all enemie_units give unit. #
|
||||
# This time the atacker can defend himself. The defender will chose the attack with the best #
|
||||
# damage difference #
|
||||
def evaluate_defender_against_opponents(ai*, unit, enemy_units)
|
||||
sum(
|
||||
map(
|
||||
@ -181,16 +188,22 @@ def evaluate_defender_against_opponents(ai*, unit, enemy_units)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
# Returns a List with the attacker damages of all recruits #
|
||||
# The higher the better #
|
||||
def evaluate_recruits_offensive_combat(ai*, recruits, enemy_units)
|
||||
map( recruits, 'recruit',
|
||||
evaluate_attacker_against_opponents( ai, recruit, enemy_units )
|
||||
);
|
||||
|
||||
#Returns a List with the defender damages for all recruits #
|
||||
# The lower the better #
|
||||
def evaluate_recruits_defensive_combat(ai*, recruits, enemy_units)
|
||||
map( recruits, 'recruit',
|
||||
evaluate_defender_against_opponents( ai, recruit, enemy_units )
|
||||
);
|
||||
|
||||
# Some helper functions for map calculations #
|
||||
def combine_maps_mul( map_A, map_B )
|
||||
map( map_A, value * map_B[key] );
|
||||
|
||||
@ -203,18 +216,17 @@ def combine_maps_add( map_A, map_B )
|
||||
def combine_maps_div( map_A, map_B )
|
||||
map( map_A, value / map_B[key] );
|
||||
|
||||
#
|
||||
[ locally_normalize_to_highest(my_recruits_defense(self)),
|
||||
tomap(map(my_recruits, id),map(my_recruits, hitpoints) ),
|
||||
locally_normalize_to_lowest(my_recruits_movement_cost(self)),
|
||||
tomap(map(my_recruits, id),map(my_recruits, total_movement))]
|
||||
#
|
||||
|
||||
# Returns a map. #
|
||||
# Key is unit_id #
|
||||
# Value is (costs - avarage costs) * 80 + offset (offset is there so everything is positive) #
|
||||
# High Value means high cost compared to the avarage cost of own units #
|
||||
def consider_unit_cost(ai*)
|
||||
make_positive_only(map( cost_map, (value - average(values(cost_map))) * 80))
|
||||
where cost_map = tomap(map(my_recruits, id),map(my_recruits, cost ));
|
||||
|
||||
|
||||
# Returns a Map. Key is unit_id of my_recruits. #
|
||||
# Value is the summed defense on important terrain multiplied by hp * 15. #
|
||||
# Normalized so the maximum is 100. #
|
||||
def defense_hp_eval(ai*, recruits_id_map)
|
||||
locally_normalize_to_highest(
|
||||
debug_print('combined hp and defense ',combine_maps_mul(
|
||||
@ -226,6 +238,9 @@ def defense_hp_eval(ai*, recruits_id_map)
|
||||
))
|
||||
);
|
||||
|
||||
# Returns a Map. Key is unit_id of my_recruits. #
|
||||
# Value is how fast a unit can move through the important terrain. #
|
||||
# Normalized so the maximum is 100. #
|
||||
def movement_eval(ai*, recruits_id_map)
|
||||
locally_normalize_to_highest(
|
||||
make_positive_only(
|
||||
@ -243,6 +258,10 @@ def movement_eval(ai*, recruits_id_map)
|
||||
)
|
||||
);
|
||||
|
||||
# Returns a Map. #
|
||||
# key is Unit id of my_recruits #
|
||||
# Value is how good is the unit against all other units currently on the map. #
|
||||
# The higher the better #
|
||||
def fighting_eval(ai*, recruits_id_map)
|
||||
make_positive_only(
|
||||
combine_maps_sub(
|
||||
@ -252,6 +271,9 @@ def fighting_eval(ai*, recruits_id_map)
|
||||
)
|
||||
where current_enemies = current_enemies(ai);
|
||||
|
||||
# Returns a map #
|
||||
# Key is unit_id #
|
||||
# Value is 40 if unit is level 0 #
|
||||
def level_zero_malus(ai*)
|
||||
map( lvl_map,
|
||||
if(value = 0, 40, 0)
|
||||
@ -261,12 +283,16 @@ def level_zero_malus(ai*)
|
||||
map(my_recruits, level )
|
||||
);
|
||||
|
||||
#tmp function #
|
||||
# UNUSED FUNCTION #
|
||||
def filter_out( input_map, comparable_map )
|
||||
filter( input_map, comparable_map[key] > comp_val)
|
||||
where comp_val = average(values(comparable_map))/2;
|
||||
|
||||
|
||||
# CENTRAL EVALUATION FUNCTION #
|
||||
# calls several subroutines to calculate a final score map of my_recruits #
|
||||
# Normalizes then so the scores add up do 100 (%). #
|
||||
# Note that fighting_eval is multiplied by 5 and gets a massive weight #
|
||||
# Returns a Map with unit_id as key and score in % as value. #
|
||||
def calculate_recruits(ai*)
|
||||
change_numbers_to_percents(
|
||||
combine_maps_sub(
|
||||
@ -285,7 +311,7 @@ def calculate_recruits(ai*)
|
||||
debug_print('level_zero_malus ', level_zero_malus(ai) )
|
||||
)
|
||||
)
|
||||
) where recruits_id_map = map(my_recruits, id);
|
||||
) where recruits_id_map = map(my_recruits, id); #recruits_id_map is a list of all recruit-ids#
|
||||
|
||||
def do_recruitment( ai* )
|
||||
if( unit_to_recruit,
|
||||
@ -297,6 +323,7 @@ def do_recruitment( ai* )
|
||||
)
|
||||
where unit_to_recruit = recruit_army(self, vars.recruits_map);
|
||||
|
||||
# 'MAIN FUNCTION' #
|
||||
if( vars.side_terrain,
|
||||
if(vars.direct_enemies,
|
||||
if(vars.turn_initialized = turn,
|
||||
@ -308,7 +335,7 @@ if( vars.side_terrain,
|
||||
set_var(debug_print('recruits_map'), debug_print( 'RECRUITS ', calculate_recruits(self)) )
|
||||
]
|
||||
+
|
||||
if( turn = 0,
|
||||
if( 1,
|
||||
[
|
||||
null(
|
||||
sum(
|
||||
|
Loading…
x
Reference in New Issue
Block a user