FormulaAI Functions

From The Battle for Wesnoth Wiki
Revision as of 21:50, 6 July 2008 by Dragonking (talk | contribs) (core functions)

Overview

Syntax used to explain functions usage in this document is:

<result> = <function name>( <comma-separated list of parameters> [, <comma-separated list of optional parameters] )

Function may return <result> as:

  • <variable> - any of the supported variable types
  • <boolean> - false ( 0 or null ) or true ( 1 )
  • <unit> - unit
  • <location> - place on a gamemap
  • <action> - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.
  • <result> - any of the above

Also function may return only single argument, or be able to return a whole list or a map.

There are a wide variety of functions which can be used to accomplish many different tasks. You can also define your own functions.

core functions

'abs' function

<number> = abs( <input number> )

Function returns absolute value of an <input number>, for example

abs( -5 )

will return 5.

'choose' function

<result> = choose( <input list> , [ <string> ,] <formula> )

This function evaluates <formula> for each item in the <input> (which can be a list ro a map). Will evaluate to the one item which <formula> gave the highest value. For example:

choose(my_units, level)

gives back the unit with the highest level.

Note: The implicit input when evaluating a mapping/filtering function's <formula> component will be that specific item under evaluation (in this example one of "my_units"), and it can be explicitly referenced as 'self' when necessary. Optional <string> paremater indicates what word used in <formula> is equivalent to 'self'.

When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:

choose( { 'elf' -> 10, 'dwarf' -> 20 }, value )

Will return a key-value pair { key->'dwarf', value->20 }

'dir' function

<list of names> = dir ( <input object> )

This function return list with all names of <input object's> members. For example:

dir( my_leader )

will result in output:

[ 'x', 'y', 'loc', 'id', 'leader', 'hitpoints', 'max_hitpoints', 'experience', 'max_experience', 'level',
'total_movement', 'movement_left', 'side', 'is_enemy', 'is_mine']

This command is useful in formula command line, to get information about members of different type of data. To get list of members of the ai, type:

dir( self )

'filter' function

<reult> = filter( <input>, [ <string> ,] <formula> )

This function will run <formula> on each item in the <input> (which can be a list or a map). Will evaluate to a <result> which only contains items the <formula> was true for. Optional <string> indicates what word used in <formula> is equivalent to 'self'. For example:

filter(my_units, hitpoints < max_hitpoints)

will return all of your units which have less than maximum hitpoints. For instance this could be used if looking for candidates for healing.

'find' function

<result> = find( <input>, [ <string>,] <formula> )

This function will run <formula> on each item in the <input> (which can be a list or a map) and will return a first item for which <formula> was true. Optional <string> indicates what word used in <formula> is equivalent to 'self'. For example:

filter(units, id = 'Elvish Archer' )

will return first unit with id equal to 'Elvish Archer'.

'head' function

<variable> = head( <list of variables> )

Head returns first item from the <list of variables>, for example

head( [ 5, 7, 9] )            #returns 5
head( [ 'Orc', 'Human' ] )    #returns 'Orc'

'if' function

<result> = if( <condition> , <if true> , <otherwise> )


If the <condition> parameter is true, the function will evaluate to being equal to its second input ( <if true> ), otherwise it will evaluate to being equal to its third input ( <otherwise> ). For instance, an AI that recruits Wolf Riders on the first turn, and Orcish Grunts thereafter might look like this:

move="if(turn = 1, recruit('Wolf Rider'), recruit('Orcish Grunt'))"

'keys' function

<result list> = keys( <input map> )

Extract key values from a <input map> and return them as a <result list>

keys( { 'Elvish Fighter' -> 50, 'Elvish Archer' -> 60 }

Returns

[ 'Elvish Fighter', 'Elvish Archer' ]

'map' function

<result> = map( <input> , [ <string> ,] <formula> )

This function will run <formula> on each item in the <input> (which can be a list or a map), and evaluate to a new <result> list, or a map, which contains the same number of items as in <input>, with the formulas run on each item. Optional <string> indicates what word used in <formula> is equivalent to 'self'. For example:

map( [10,20], self*self)

and

map( [10,20], 'value', value*value)

both will result in [100, 400]. Formula:

map(my_units, hitpoints) 

will give a list back with the number of hitpoints each unit has. This is more useful in conjunction with other functions.

map( { 'elf' -> 10, 'dwarf' -> 20 }, value*2 )

Above will produce { 'elf' -> 20, 'dwarf' -> 40 ). Note that in case of a map data type, 'map' function can modify only the value.

'max' function

<number> = max( <list of numbers> )

Function will return maximal number from a list,

max( [ 2, 8, -10, 3] )

will return 8.

'min' function

<number> = min( <list of numbers> )

Function will return minimal number from a list,

min( [ 3, 7, -2, 6] )

will return -2.

'size' function

<number> = size( <list of variables> )

This function returns how many variables are stored in a list:

size( [ 5, 7, 9] )                #return 3
size( [ 'Archer', 'Fighter' ] )   #return 2

'sort' function

<result list> = sort( <input list> , <formula> )

This function evaluates to a <result list> sorted according to the comparison <formula> for each item 'a' and its successor 'b'. For instance, sorting units according to hitpoints would be done by:

sort( my_units, a.hitpoints > b.hitpoints )

'sum' function

<number> = sum( <list of numbers> )

This function evaluates to the sum of the items in the <list of numbers>. For example

sum( [ 2, 5, 8] )

returns 15, and:

sum( map( my_units,  max_hitpoints - hitpoints ) )

finds the total damage your units have taken.

'switch' function

<result> = switch( <variable>, <value 1>, <outcome 1>, ... , <value N>, <outcome N> [, <default outcome> ] >

Switch funtion takes variable, and checks if it is equal to any of the specified <values>. If matching value is found, <outcome> assigned to it is returned, if not, then function returns either <default outcome> (if specified) or null.

'tolist' fuction

'tomap' function

<map> = tomap( <list A> [, <list B> ] )

When only one parameter is specified, it creates a map, with the keys of that map being the unique elements within the list. The values of the map are the number of occurrences of the corresponding key in the list. For example:

tomap( ['elf', 'human', 'dwarf', 'dwarf', 'elf', 'elf' ] )

Will result in

{ 'elf' -> 3, 'human' -> 1, 'dwarf' -> 2 }

When two lists are specified as an input, map is created with keys taken from list A, and values taken from list B:

tomap( [ 'elf', 'dwarf' ] , [ 1 , 5 ] )

will result in:

{ 'elf' -> 1, 'dwarf' -> 5 }

'values' function

<result list> = values( <input map> )

Extract values assigned to keys from a <input map> and return them as a <result list>

values( { 'Elvish Fighter' -> 50, 'Elvish Archer' -> 60 }

Returns

[ 50, 60 ]

AI specific functions

Base functions

'attack' function

<action> = attack( <attacker's position>, <destination>, <attack location> [,  <weapon> ] )

The first three parameters are locations. At the begining, unit which is standing at <attacker's position> is moved to <destination> place. Then, from that place unit is attacking unit which stands in place marked by <attack location>. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.

'fallback' function

<action> = fallback( <name> )

This function allows to chose different AI which will take control over side untill the end of current turn. For example:

fallback( 'default' )

will transfer control to the default C++ AI.

fallback('human')

will transfer control to human player.

'move' function

<action> = move( <source> , <destination> )

For example unit formula like:

move(me.loc, loc(me.loc.x, me.loc.y - 1) )

will make unit move one hex north.

'set_var' function

<action> = set_var( <key> , <value> )

This action sets new variable, for example:

set_var( 'Number one' , 1 )

Will create variable with name 'Number one' and assign 1 to it.

Evaluation

'chance to hit' function

<number> = chance_to_hit( <unit> , <location> )

This function returns how possible ( in % ) it is to hit given <unit> in a specific <location>. For example:

chance_to_hit( my_leader , my_leader.loc )

shows how easy it is to hit your leader has in a place he is currently standing on.


'max_possible_damage' function

<number> = max_possible_damage( <attacking unit> , <defending unit> )

Function returns highest possible damage that <attacking unit> can inflict to <defending unit>.

Gamemap functions

'close enemies' function

<units list> = close_enemies( <location> , <distance> )

This function gets a list of enemies in the given or smaller distance from the location. For example:

close_enemies(loc(10,10), 5)

gives back a list of enemies in the distance of 5 tiles or less from the tile (10, 10).

'distance_between' function

<number> = distance_between( <location A> , <location B> )

This function returns distance (in hexes) between <location A> and <location B>. For example:

distance_between( loc( 1, 1) , loc( 3, 3) )

will return 3.

'distance_to_nearest_unowned_village' function

<number> = distance_to_nearest_unowned_village( <location A> )

This function returns distance (in hexes) between <location A> and nearest unowned village.

'defense_on' function

<number> = defense_on( <unit> , <location> )

This function returns defense rate of given <unit> in a specific <location>. For example:

defense_on( my_leader , my_leader.loc )

shows how good defense your leader has in a place he is currently standing on.

'find_shroud' function

<locations list> = find_shroud()

This function will return a list of locations of shrouded hexes.

'is_village' function

<boolean> = is_village( <map or ai.map> , <location> )   #1
<boolean> = is_village( <map or ai.map> , <coordinate x> , <coordinate y> )   #2

The first argument is always a 'map' - member of the ai which provides information about the gamemap.

In #1 usage, we put in as a second argument location. In #2, second and third arguments are numbers: coordniates of the certain hex on a map. Function checks if that place is a village, and returns either 1 (yes, it is village) or 0 (no, it isn't village). Example of usage:

is_village( map , loc( 2, 3) )
is_village( map , 2, 3)

Both check, if hex with coordinates 2,3 is a village.

Remember, when using is_village in custom function, you either have to access map by writing 'ai.map', or specify ai as a 'default input'.

'loc' function

<location> = loc( <X number>, <Y number> )

Function will return a location (pair of numbers) from two given input arguments.

'unit_at' function

<unit> = unit_at( <location> ) 

This function takes only one argument - location, and returns unit if there is one standing in that location, or null otherwise. Example of usage:

unit_at( loc( 4, 4) )

'nearest_keep' function

<keep location> = nearest_keep( <input location> )

Function returns location of nearest keep to the specified <input location>, or null if there is no keep on the map.

'unit_moves' function

<locations list> = unit_moves( <unit location> )

Function returns list of all possible locations which unit standing at <unit location> can reach. If unit can't move, or there is no unit standing at given location, empty list is returned.

'units_can_reach' function

<units list> = units_can_reach( <possible moves list>, <location> )

Function takes as an input list of possible moves ( ai.my_moves for units that belong to AI, or ai.enemy_moves for units that belong to the opponent ) and checks which units from that list can reach <location>.

Recruitment

'recruit' function

<action> = recruit( <unit name> [, <location> ] )

This function results in recruting a unit specifed by <unit name> at first free castle hex, or at given <location>. Function:

recruit('Footpad', loc(3,3) ) 

will result in recruting Footpad at castle hex with coordinates 3,3.