<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.wesnoth.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Benetnash</id>
	<title>The Battle for Wesnoth Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.wesnoth.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Benetnash"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/Special:Contributions/Benetnash"/>
	<updated>2026-05-01T12:34:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=30310</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=30310"/>
		<updated>2009-04-28T19:37:33Z</updated>

		<summary type="html">&lt;p&gt;Benetnash: /* Available variables */  typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI is an attempt to develop an AI framework for Wesnoth that allows easy and fun development and modification of AIs for Wesnoth.&lt;br /&gt;
&lt;br /&gt;
Wesnoth already has support for AIs written in Python, but writing AIs in Python has a couple of problems:&lt;br /&gt;
&lt;br /&gt;
* it's still rather difficult, especially for a non-programmer, to develop an AI, even in Python&lt;br /&gt;
* Python is insecure; a malicious trojan horse Python script masquerading as an AI could do untold damage&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI aims to create a fairly simple, pure functional language which allows one to implement an AI. It also aims to allow AIs to be tweaked and modified by people with relatively little technical skill; anyone who can use WML should also be able to use the Formula AI to tweak an AI to make the AI in a scenario behave how they want.&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI is currently in an experimental stage of development. One can play with it and develop a rudimentary AI. Feedback is appreciated.&lt;br /&gt;
&lt;br /&gt;
To develop an AI using the Formula AI, set ai_algorithm=formula_ai in [side].&lt;br /&gt;
&lt;br /&gt;
== How formulas get called ==&lt;br /&gt;
&lt;br /&gt;
=== Formulas Command Line ===&lt;br /&gt;
&lt;br /&gt;
To attempt to make it convenient to debug formulas, one can run formulas from within Wesnoth, and see the results. To run a formula, just start game and type 'f'. A command textbox will appear, where you can type a formula, and the results will be printed. For instance, typing&lt;br /&gt;
&lt;br /&gt;
 8 + 4 &lt;br /&gt;
&lt;br /&gt;
will result in &amp;quot;12&amp;quot; appearing on the screen. You can now use Wesnoth like a calculator. :-)&lt;br /&gt;
&lt;br /&gt;
=== Side-wide formulas ===&lt;br /&gt;
The first way to get a formula called is to assign it to a [side] in a WML map. This formula will be called every turn, so it is best used for very simple sides (a couple of special units which should have semi-scripted moves, or a simple handling followed by calls to the standard C++ AI)&lt;br /&gt;
&lt;br /&gt;
To use the Formula AI, one should put an [ai] tag inside the [side] tag. Inside this [ai] tag, one should specify the 'move' attribute to be a formula which specifies what movement the AI will make. Each time it's the AI's move, this formula will be run, and the move it results in will be executed. Then the formula will be run again; it'll continue to be run until it stops producing a valid move, at which point the AI will end its turn. Alternatively there is a command that the formula may return which will make it end its turn immediately.&lt;br /&gt;
&lt;br /&gt;
A sample AI which does nothing but recruit Wolf Riders is as follows:&lt;br /&gt;
&lt;br /&gt;
 [side]&lt;br /&gt;
 ...&lt;br /&gt;
 ai_algorithm=formula_ai&lt;br /&gt;
   [ai]&lt;br /&gt;
   move=&amp;quot;recruit('Wolf Rider')&amp;quot;&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/side]&lt;br /&gt;
&lt;br /&gt;
=== Unit Formulas ===&lt;br /&gt;
&lt;br /&gt;
You can specify a formula for any kind of unit. This is a simple way of doing it:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
   ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Custom unit formulas are executed first at the begining of side's turn. Above formula will simply move unit one hex to the north every turn. Note how &amp;quot;me&amp;quot; keyword allows access to unit itself.&lt;br /&gt;
&lt;br /&gt;
If you need to execute unit formulas in a specific order, you can set a priority:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
   ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&lt;br /&gt;
     priority=10&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Units with highest priority get their formula executed first.&lt;br /&gt;
&lt;br /&gt;
You can also define AI unit-specific variables and use them in you formulas:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;if(attack, attack, move(me.loc, me.vars.guard_loc) )&lt;br /&gt;
        where attack = choose(filter(attacks, units = [me.loc] and distance_between(me.vars.guard_loc, target) &amp;lt;= me.vars.guard_radius and unit_at(target).side=me.vars.hostile_side-1 ), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     [vars]&lt;br /&gt;
       guard_radius=3&lt;br /&gt;
       guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
       hostile_side=1&lt;br /&gt;
     [/vars]&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
This formula will get location position from variable guard_loc and make sure that unit attacks only opponent from side 1 (value specified by hostile_side variable) which is 3 hexes (guard_radius) or less from guard_loc.&lt;br /&gt;
&lt;br /&gt;
Types of variables that are supported:&lt;br /&gt;
*number:&lt;br /&gt;
 variable=3&lt;br /&gt;
*text (important: note the ' ' within &amp;quot; &amp;quot;):&lt;br /&gt;
 name=&amp;quot;'I am variable'&amp;quot;&lt;br /&gt;
*list:&lt;br /&gt;
 number_list=[ 1, 2, 3]&lt;br /&gt;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Candidate move evaluation ===&lt;br /&gt;
==== Overview ====&lt;br /&gt;
Units in wesnoth have all sort of special abilities, special powers and special usages. Thus, it was needed to have an easy way to describe special behaviour for special units. Adding an formula to a unit only partially solves the problem. It allows easily to have special units (like ennemy heroes) have special behaviour but not normal units with special powers to to behave smartly. &lt;br /&gt;
&lt;br /&gt;
Candidate moves are a way to have formula that will&lt;br /&gt;
&lt;br /&gt;
* evaluate a given situation&lt;br /&gt;
* see if they are able to provide &amp;quot;special moves&amp;quot; for the case they know how to handle&lt;br /&gt;
* give a move to do if the situation match their condition&lt;br /&gt;
&lt;br /&gt;
==== Evaluation Algorithm ====&lt;br /&gt;
&lt;br /&gt;
Each side will have some candidate move blocks made of&lt;br /&gt;
* a name for the move&lt;br /&gt;
* a type (see below for description of the different types and how they are called)&lt;br /&gt;
* a formula returning a score for the move&lt;br /&gt;
* a formula returning the move to do&lt;br /&gt;
&lt;br /&gt;
The engine will run the following pseudo-code&lt;br /&gt;
&lt;br /&gt;
 while (a formula returned a score greatern than 0) {&lt;br /&gt;
      foreach (registered candidate move) {&lt;br /&gt;
           foreach (set of parameters for that candidate move's type) {&lt;br /&gt;
               call the evaluation formula, note the score returned&lt;br /&gt;
           }&lt;br /&gt;
      }&lt;br /&gt;
      if (the highest score returned was greater than 0) {&lt;br /&gt;
          call the candidate move that returned the highest score with the corresponding set of parameters&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
in other word, we evaluate all candidate moves, then run the candidate move with the highest score, then re-evaluate everything, until no candidate move wants to play anymore&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Syntax ====&lt;br /&gt;
to add a new candidate move you should add '''[register_candidate_move]''' blocks within the '''[ai]''' block.&lt;br /&gt;
&lt;br /&gt;
Each block will describe a candidate move and must have the following fields&lt;br /&gt;
&lt;br /&gt;
* ''name'' : the name of this candidate block&lt;br /&gt;
* ''type'' : see the paragraph about types below, this describe the implicite variables that the formulas will be called with&lt;br /&gt;
* ''evaluation'' : a formula returning an integer. This number reflects how good the move is compared to other moves. Values of zero will mean the move is not a good idea and should be skipped&lt;br /&gt;
* ''action'' : A formula that will be called if that candidate move is the best one&lt;br /&gt;
==== Candidate move types ====&lt;br /&gt;
&lt;br /&gt;
there are two types of candidate moves&lt;br /&gt;
&lt;br /&gt;
* '''attack''' : these are called once for every pair &amp;lt;me,target&amp;gt; where me is a variable set to a unit on the AI side, and target is a variable set to an ennemy unit that &amp;quot;me&amp;quot; can reach&lt;br /&gt;
* '''movement''' : these are called once for every unit on the AI side, the &amp;quot;me&amp;quot; variable is set to the corresponding unit&lt;br /&gt;
&lt;br /&gt;
=== Summary : a typical AI turn ===&lt;br /&gt;
&lt;br /&gt;
An AI turn will run the following formulas. Any formula returning an &amp;quot;end turn&amp;quot; move will (of course) finish the turn. But assuming this doesn't happen :&lt;br /&gt;
* All unit formulas are called once&lt;br /&gt;
* All candidate moves are evaluated and played&lt;br /&gt;
* All ''move='' formulas are called until they don't return valid moves&lt;br /&gt;
* If no ''move='' formula is provided, we drop automatically to C++&lt;br /&gt;
* Turn is ended.&lt;br /&gt;
&lt;br /&gt;
Note that this means that you have to explicitely call &amp;quot;fallback&amp;quot; if you want the C++ AI to finish your moves after a side-wide formula&lt;br /&gt;
&lt;br /&gt;
== Formula Basics ==&lt;br /&gt;
&lt;br /&gt;
* The Formula language supports basic arithmetic operations, such as: +, -, *, /, % and ^. It supports integers but does NOT support decimal or floating point numbers. For example:&lt;br /&gt;
&lt;br /&gt;
 4 + 8*7     #evaluates to 60&lt;br /&gt;
 (4 + 8)*7   #evaluates to 84&lt;br /&gt;
 8 % 6       #evaluates to 2&lt;br /&gt;
 5 / 2       #evaluates to 2&lt;br /&gt;
 3 ^ 2       #evaluates to 9&lt;br /&gt;
&lt;br /&gt;
* It also supports equality, = and !=, and comparison operators, &amp;lt;, &amp;gt;, &amp;lt;=, and &amp;gt;=. 'false' values are 0 (integer) and null. Other values are true. It also supports common operators such as and, or, and not:&lt;br /&gt;
&lt;br /&gt;
 2 = 4     #evaluates to 0&lt;br /&gt;
 2 &amp;lt;= 3    #evaluates to 1&lt;br /&gt;
 0 != 1    #evaluates to 1&lt;br /&gt;
 not 4     #evaluates to 0&lt;br /&gt;
 not 0     #evaluates to 1&lt;br /&gt;
 (2 &amp;lt; 4) and (3 &amp;gt; 6)    #evaluates to 1 and 0 which evaluates to 0&lt;br /&gt;
 (2 &amp;lt; 4) or (3 &amp;gt; 6)     #evaluates to 1 or 0 which evaluates to 1&lt;br /&gt;
&lt;br /&gt;
* Formula language supports also 'dice' operator 'd'. Example usage is:&lt;br /&gt;
&lt;br /&gt;
 3d5&lt;br /&gt;
&lt;br /&gt;
Which will give you one of results of rolling three five-sided dice (so random number between 3 and 15). NOTE: We encourage you to use this operator only when it is really needed. In most cases, you should not base the AI decisions on random results except for scenario replayability purposes.&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
&lt;br /&gt;
Formula System supports different types of data, which can be stored as a variables and are used in evaluations:&lt;br /&gt;
&lt;br /&gt;
* Numbers: like 0, 1, 2 etc. Floating-point numbers are not supported. 0 is equal to logical 'false', any other number is 'true'.&lt;br /&gt;
&lt;br /&gt;
* Text strings: &lt;br /&gt;
&lt;br /&gt;
 'this is a text string' &lt;br /&gt;
&lt;br /&gt;
* Lists: A list is a sequence of values. For example, ai.my_units is a list of unit objects. A list is represented as square brackets, [], surrounding a comma-seperated list. For instance: &lt;br /&gt;
&lt;br /&gt;
 [4, 8, 7] &lt;br /&gt;
&lt;br /&gt;
is a list of three numbers, and &lt;br /&gt;
&lt;br /&gt;
 []&lt;br /&gt;
&lt;br /&gt;
is a empty list. Various functions can operate on lists.&lt;br /&gt;
&lt;br /&gt;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
Some of these variables are complicated data structues, calling their name from the formula command line will allow you to easily see their content&lt;br /&gt;
&lt;br /&gt;
use the '''dir''' and '''debug_print''' to inspect the variables&lt;br /&gt;
&lt;br /&gt;
to get a coplete list, use the &lt;br /&gt;
 dir(self)&lt;br /&gt;
command&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* ''attacks'' a list of all possible attacks&lt;br /&gt;
NOTE: this variable returns a list of all possible attacks (including attack combinations - attacking a single enemy unit with several units) , which is immediately treated as list of attack orders, which is evaluated (so, evaluation of this variable results in attacks being made). If you want to get the list without such evaluation, wrap it inside the array, &amp;quot;[attacks]&amp;quot;. If you want to get the first attack, wrap it inside the array twice, &amp;quot;[[attacks[0]]&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
* ''my_attacks'' a list of all possible attacks. It returns slightly different list then ''attacks''. I.e. when only two units (attacker and dedenter) are on the board ''attacks'' return one attack, from the position with the highest defence and ''my_attacks'' returns all 6 attacks from all adjacent tiles.&lt;br /&gt;
* ''my_side'' global variables describing your own side&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''time_of_day'' the current time of day&lt;br /&gt;
* ''keeps'' all keep locations&lt;br /&gt;
* ''vars'' all localy set varables using the set_var function&lt;br /&gt;
* ''allies'' a list of all sides that are friendly&lt;br /&gt;
* ''ennemies'' a list of all sides that are enemy&lt;br /&gt;
* ''my_moves'' a list of all my moves&lt;br /&gt;
* ''enemy_moves'' a list of all enemy moves&lt;br /&gt;
* ''my_leader'' our leader unit&lt;br /&gt;
* ''my_recruits'' the list of units that can be recruited by us&lt;br /&gt;
* ''recruits_of_side'' foreach side the list of units that can be recruited&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''units_of_side'' foreach side, a list of all owned units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''enemy_units'' all units that are enemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''villages_of_side'' for each side, the list of villages owned&lt;br /&gt;
* ''enemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(ai*) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(ai*) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(ai*)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&lt;br /&gt;
&lt;br /&gt;
You can easily split your formulas between different files and include them when necessary. For example:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
  formula={my_unit_formula.fai}&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Will look for unit formula in the my_unit_formula.fai file.&lt;br /&gt;
&lt;br /&gt;
Although it is not mandatory, we advocate to use following syntax in your fai files:&lt;br /&gt;
&lt;br /&gt;
 faifile '&amp;lt;filename&amp;gt;'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
This makes formula system know which file it is working with now, and gives you improved error reporting, which is often really helpful. Valid syntax for my_unit_formula.fai would be:&lt;br /&gt;
&lt;br /&gt;
 faifile 'my_unit_formula.fai'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
== Tool Support ==&lt;br /&gt;
&lt;br /&gt;
=== ctags ===&lt;br /&gt;
&lt;br /&gt;
For some rudimentary support for exuberant ctags, add the following to .ctags (or create the file if it doesn't exist):&lt;br /&gt;
&lt;br /&gt;
 --langdef=formulaai&lt;br /&gt;
 --langmap=formulaai:.fai&lt;br /&gt;
 --regex-formulaai=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/&lt;br /&gt;
&lt;br /&gt;
This is especially nice when used with an editor or plugin with ctags support, such as Taglist for Vim.&lt;br /&gt;
&lt;br /&gt;
=== Vim ===&lt;br /&gt;
&lt;br /&gt;
====Syntax Highlighting====&lt;br /&gt;
&lt;br /&gt;
Follow these steps to enjoy vim syntax highlighting support for Formula AI.&lt;br /&gt;
&lt;br /&gt;
# Grab the Formula AI vim syntax file, [http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/tools/vim/formulaai.vim formulaai.vim].&lt;br /&gt;
# Copy formulaai.vim to .vim/syntax &lt;br /&gt;
# Add the following to .vimrc :&lt;br /&gt;
 autocmd! BufRead,BufNewFile *.fai setfiletype formulaai&lt;br /&gt;
&lt;br /&gt;
====Taglist Support====&lt;br /&gt;
&lt;br /&gt;
First you will need the very nice [http://www.vim.org/scripts/script.php?script_id=273 taglist plugin].  Follow the link for downloads and install directions if you don't already have it installed.&lt;br /&gt;
&lt;br /&gt;
Next, you'll need Formula AI support for exuberant ctags, follow the instructions in the [[#ctags|ctags]] section.  &lt;br /&gt;
&lt;br /&gt;
Once you have all that, simply add the following line to your .vimrc:&lt;br /&gt;
 &lt;br /&gt;
 let tlist_formulaai_settings = 'formulaai;d:definition'&lt;br /&gt;
&lt;br /&gt;
To test it all out, open a Formula AI script file and enter the command &lt;br /&gt;
 :Tlist&lt;br /&gt;
&lt;br /&gt;
You should now have some nice highlighting and be able to easily navigate through formula, enjoy!&lt;br /&gt;
  &lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Benetnash</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=30292</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=30292"/>
		<updated>2009-04-25T18:46:31Z</updated>

		<summary type="html">&lt;p&gt;Benetnash: /* 'calculate_outcome' function */ fixed description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Syntax used to explain functions usage in this document is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = &amp;lt;function name&amp;gt;( &amp;lt;comma-separated list of parameters&amp;gt; [, &amp;lt;comma-separated list of optional parameters] )&lt;br /&gt;
&lt;br /&gt;
Function may return &amp;lt;result&amp;gt; as:&lt;br /&gt;
* &amp;lt;variable&amp;gt; - any of the supported variable types&lt;br /&gt;
* &amp;lt;boolean&amp;gt; - false ( 0 or null ) or true ( 1 )&lt;br /&gt;
* &amp;lt;unit&amp;gt; - unit&lt;br /&gt;
* &amp;lt;location&amp;gt; - place on a gamemap&lt;br /&gt;
* &amp;lt;action&amp;gt; - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.&lt;br /&gt;
* &amp;lt;result&amp;gt; - any of the above&lt;br /&gt;
&lt;br /&gt;
Also function may return only single argument, or be able to return a whole list or a map.&lt;br /&gt;
&lt;br /&gt;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also [http://www.wesnoth.org/wiki/FormulaAI#Custom_Functions define your own functions].&lt;br /&gt;
&lt;br /&gt;
=core functions=&lt;br /&gt;
&lt;br /&gt;
=== 'abs' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = abs( &amp;lt;input number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns absolute value of an &amp;lt;input number&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 abs( -5 )&lt;br /&gt;
&lt;br /&gt;
will return 5.&lt;br /&gt;
&lt;br /&gt;
=== 'choose' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates &amp;lt;formula&amp;gt; for each item in the &amp;lt;input&amp;gt; (which can be a list ro a map). Will evaluate to the one item which &amp;lt;formula&amp;gt; gave the highest value.  For example:&lt;br /&gt;
&lt;br /&gt;
 choose(my_units, level)&lt;br /&gt;
&lt;br /&gt;
gives back the unit with the highest level.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The implicit input when evaluating a mapping/filtering function's &amp;lt;formula&amp;gt; component will be that specific item under evaluation (in this example one of &amp;quot;my_units&amp;quot;), and it can be explicitly referenced as 'self' when necessary. Optional &amp;lt;string&amp;gt; paremater indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'.&lt;br /&gt;
&lt;br /&gt;
When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:&lt;br /&gt;
&lt;br /&gt;
 choose( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value )&lt;br /&gt;
&lt;br /&gt;
Will return a key-value pair &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature}} '''you need to enable formula log (--log-info=formula_ai) to see the result of this call'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== 'debug_float' function {{DevFeature}} ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_float( &amp;lt;location&amp;gt;, [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, floats a label containing the output on the hex specified (in the same way damage is displayed)  and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_float(me.loc, me.id )&lt;br /&gt;
&lt;br /&gt;
will make a label containing the id of the unit &amp;quot;me&amp;quot; float over the unit&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Return value is also the unit id.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_float( me.loc, 'id: ', me.id )&lt;br /&gt;
&lt;br /&gt;
will make the following label&lt;br /&gt;
&lt;br /&gt;
 id: &amp;lt;unit id&lt;br /&gt;
&lt;br /&gt;
And return the unit id&lt;br /&gt;
&lt;br /&gt;
=== 'dir' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of names&amp;gt; = dir ( &amp;lt;input object&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function return list with all names of &amp;lt;input object's&amp;gt; members. For example:&lt;br /&gt;
&lt;br /&gt;
 dir( my_leader )&lt;br /&gt;
&lt;br /&gt;
will result in output:&lt;br /&gt;
&lt;br /&gt;
 [ 'x', 'y', 'loc', 'id', 'leader', 'hitpoints', 'max_hitpoints', 'experience', 'max_experience', 'level',&lt;br /&gt;
 'total_movement', 'movement_left', 'side', 'is_enemy', 'is_mine']&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
 dir( self )&lt;br /&gt;
&lt;br /&gt;
=== 'filter' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = filter( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map). Will evaluate to a &amp;lt;result&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(my_units, hitpoints &amp;lt; max_hitpoints)&lt;br /&gt;
&lt;br /&gt;
will return all of your units which have less than maximum hitpoints. For instance this could be used if looking for candidates for healing.&lt;br /&gt;
&lt;br /&gt;
=== 'find' function ===&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;result&amp;gt; = find( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt;,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map) and will return a first item for which &amp;lt;formula&amp;gt; was true. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(units, id = 'Elvish Archer' )&lt;br /&gt;
&lt;br /&gt;
will return first unit with id equal to 'Elvish Archer'.&lt;br /&gt;
&lt;br /&gt;
=== 'head' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;variable&amp;gt; = head( &amp;lt;list of variables&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Head returns first item from the &amp;lt;list of variables&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 head( [ 5, 7, 9] )            #returns 5&lt;br /&gt;
 head( [ 'Orc', 'Human' ] )    #returns 'Orc'&lt;br /&gt;
&lt;br /&gt;
=== 'if' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = if( &amp;lt;condition&amp;gt; , &amp;lt;if true&amp;gt; [, &amp;lt;condition 2&amp;gt;, &amp;lt;if true 2&amp;gt;, ... ] [, &amp;lt;otherwise&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;condition&amp;gt; parameter is true, the function will evaluate to being equal to its second input ( &amp;lt;if true&amp;gt; ), otherwise, if third imput is specified  ( &amp;lt;otherwise&amp;gt; ), it will evaluate to being equal to it, else it will evaluate to null. &lt;br /&gt;
For instance, an AI that recruits Wolf Riders on the first turn, and Orcish Grunts thereafter might look like this:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;if(turn = 1, recruit('Wolf Rider'), recruit('Orcish Grunt'))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can specify more than one pair of &amp;lt;condition&amp;gt; and &amp;lt;if true&amp;gt; paramters, for example such formulas:&lt;br /&gt;
&lt;br /&gt;
 if( var = 'first', 1, var = 'second', 2, var = 'third', 3 )&lt;br /&gt;
 if( var = 'first', 1, var = 'second', 2, var = 'third', 3, 100 )&lt;br /&gt;
&lt;br /&gt;
In case that var is equal to 'second' above will evaluate to&lt;br /&gt;
&lt;br /&gt;
 2&lt;br /&gt;
 2&lt;br /&gt;
&lt;br /&gt;
And in case of var equal to 'fifth':&lt;br /&gt;
&lt;br /&gt;
 null&lt;br /&gt;
 100&lt;br /&gt;
&lt;br /&gt;
=== 'index_of' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = index_of( &amp;lt;value&amp;gt;,&amp;lt;list&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will return the first index where &amp;lt;value&amp;gt; can be found in &amp;lt;list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will return -1 if the value is not found&lt;br /&gt;
&lt;br /&gt;
=== 'keys' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = keys( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract key values from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 keys( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter', 'Elvish Archer' ]&lt;br /&gt;
&lt;br /&gt;
=== 'map' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = map( &amp;lt;input&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map), and evaluate to a new &amp;lt;result&amp;gt; list, or a map, which contains the same number of items as in &amp;lt;input&amp;gt;, with the formulas run on each item. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 map( [10,20], self*self)&lt;br /&gt;
&lt;br /&gt;
and &lt;br /&gt;
&lt;br /&gt;
 map( [10,20], 'value', value*value)&lt;br /&gt;
&lt;br /&gt;
both will result in [100, 400]. Formula:&lt;br /&gt;
&lt;br /&gt;
 map(my_units, hitpoints) &lt;br /&gt;
&lt;br /&gt;
will give a list back with the number of hitpoints each unit has. This is more useful in conjunction with other functions.&lt;br /&gt;
&lt;br /&gt;
 map( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value*2 )&lt;br /&gt;
&lt;br /&gt;
Above will produce  [ 'elf' -&amp;gt; 20, 'dwarf' -&amp;gt; 40 ]. Note that in case of a map data type, 'map' function can modify only the value.&lt;br /&gt;
&lt;br /&gt;
 map( tomap([3,5,8,8]), value+key*100 ) &lt;br /&gt;
&lt;br /&gt;
Above will produce [3 -&amp;gt; 301, 5 -&amp;gt; 502, 8 -&amp;gt; 801]. This can be used to take a list and make a map containing pairs [element_from_that_list -&amp;gt; f(element_from_that_list,number_of_repetitions_of_that_element_in_that_list) ] where f is an arbitrary function.&lt;br /&gt;
&lt;br /&gt;
=== 'max' function ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;number&amp;gt; = max( &amp;lt;list of numbers&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function will return maximal number from a list,&lt;br /&gt;
&lt;br /&gt;
 max( [ 2, 8, -10, 3] )&lt;br /&gt;
&lt;br /&gt;
will return 8.&lt;br /&gt;
&lt;br /&gt;
=== 'min' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = min( &amp;lt;list of numbers&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function will return minimal number from a list,&lt;br /&gt;
&lt;br /&gt;
 min( [ 3, 7, -2, 6] )&lt;br /&gt;
&lt;br /&gt;
will return -2.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'size' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = size( &amp;lt;list of variables&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns how many variables are stored in a list:&lt;br /&gt;
&lt;br /&gt;
 size( [ 5, 7, 9] )                #return 3&lt;br /&gt;
 size( [ 'Archer', 'Fighter' ] )   #return 2&lt;br /&gt;
&lt;br /&gt;
=== 'sort' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = sort( &amp;lt;input list&amp;gt; , &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates to a &amp;lt;result list&amp;gt; sorted according to the comparison &amp;lt;formula&amp;gt; for each item 'a' and its successor 'b'. For instance, sorting units according to hitpoints would be done by:&lt;br /&gt;
&lt;br /&gt;
 sort( my_units, a.hitpoints &amp;gt; b.hitpoints )&lt;br /&gt;
&lt;br /&gt;
=== 'sum' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = sum( &amp;lt;list of numbers&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates to the sum of the items in the &amp;lt;list of numbers&amp;gt;. For example&lt;br /&gt;
&lt;br /&gt;
 sum( [ 2, 5, 8] )&lt;br /&gt;
&lt;br /&gt;
returns 15, and:&lt;br /&gt;
&lt;br /&gt;
 sum( map( my_units,  max_hitpoints - hitpoints ) )&lt;br /&gt;
&lt;br /&gt;
finds the total damage your units have taken.&lt;br /&gt;
&lt;br /&gt;
=== 'switch' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = switch( &amp;lt;variable&amp;gt;, &amp;lt;value 1&amp;gt;, &amp;lt;outcome 1&amp;gt;, ... , &amp;lt;value N&amp;gt;, &amp;lt;outcome N&amp;gt; [, &amp;lt;default outcome&amp;gt; ] &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Switch funtion takes variable, and checks if it is equal to any of the specified &amp;lt;values&amp;gt;. If matching value is found, &amp;lt;outcome&amp;gt; assigned to it is returned, if not, then function returns either &amp;lt;default outcome&amp;gt; (if specified) or null.&lt;br /&gt;
&lt;br /&gt;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
=== 'wave' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;value&amp;gt; = wave( &amp;lt;value&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
given a value V, returns&lt;br /&gt;
&lt;br /&gt;
  sin(2*pi/(V%1000/1000) )&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'run_file' function {{DevFeature}} ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = run_file( &amp;lt;string_file_location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Parses and runs the specified .fai file. 'def'-style functions in the file are added to the function table of the current AI.&lt;br /&gt;
File location follows the usual WML convention, for example, run_file('ai/formula/test.fai') will lead to './data/ai/formula/test.fai' being loaded.&lt;br /&gt;
&lt;br /&gt;
At the moment, this function is useful mainly for debugging from the game console.&lt;br /&gt;
&lt;br /&gt;
=== 'set_unit_var' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = set_unit_var( &amp;lt;key&amp;gt;, &amp;lt;value&amp;gt; , &amp;lt;location&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
This action creates a new variable which is attached to the unit at &amp;lt;location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'set_var' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = set_var( &amp;lt;key&amp;gt; , &amp;lt;value&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This action sets new variable, for example:&lt;br /&gt;
&lt;br /&gt;
 set_var( 'Number one' , 1 )&lt;br /&gt;
&lt;br /&gt;
Will create variable with name 'Number one' and assign 1 to it.&lt;br /&gt;
&lt;br /&gt;
== Evaluation ==&lt;br /&gt;
=== 'calculate_outcome' function ===&lt;br /&gt;
&lt;br /&gt;
 [&amp;lt;list of outcomes&amp;gt;]  = calculate_outcome(&amp;lt;attacker current location&amp;gt;, &amp;lt;attacker location&amp;gt; , &amp;lt;defender location&amp;gt; , [&amp;lt;weapon&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
returns a list of possible outcomes when unit standing at &amp;lt;attacker current location&amp;gt; attacks the unit at &amp;lt;defender location&amp;gt; from &amp;lt;attacker location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if no weapon is provided, it will return for the weapon considered the best by the C++ weapon choice algorithm (the one used to select default weapon in normal games)&lt;br /&gt;
&lt;br /&gt;
=== 'chance to hit' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = chance_to_hit( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns how possible ( in % ) it is to hit given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 chance_to_hit( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows how easy it is to hit your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'evaluate_for_position' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;variant&amp;gt; = evaluate_for_position(&amp;lt;position&amp;gt;, &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns the result of &amp;lt;formula&amp;gt; as if &amp;lt;formula&amp;gt; was evaluated with a position of &amp;lt;position&amp;gt; instead of the current position&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
=== 'outcomes' function ===&lt;br /&gt;
  [&amp;lt;list of positions&amp;gt;] = outcomes( &amp;lt;attack&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
this function take an attack (i.e a member of the &amp;quot;attacks&amp;quot; global variable) and return an array of positions&lt;br /&gt;
&lt;br /&gt;
each position has a &amp;quot;chance&amp;quot; readable member that gives the chance of this outcome of occuring&lt;br /&gt;
&lt;br /&gt;
other members of the position are not readable&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
positions are used as parameters for the '''evaluate_for_position''' function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'timeofday_modifier' function {{DevFeature}} ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = timeofday_modifier(&amp;lt;unit&amp;gt; [, &amp;lt;location&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function returns combat modifier (percentage, such as 25 for lawful unit during the day) due to time of day, taking alignment, illuminate, time of day and fearless trait into account. note: 'leadership' and 'slowed' are not taken into account.&lt;br /&gt;
&lt;br /&gt;
unit - unit for which to evaluate&lt;br /&gt;
&lt;br /&gt;
location - location for which to evaluate (optional, defaults to unit's current location)&lt;br /&gt;
&lt;br /&gt;
== Gamemap functions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'adjacent_locs' function ===&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;loc list&amp;gt; = adjacent_locs( &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns a list containing  the list of the six locations adjacent to &amp;lt;location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 'castle_locs' function ===&lt;br /&gt;
&lt;br /&gt;
 [&amp;lt;loc list&amp;gt;] = castle_locs(&amp;lt;location&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
given a hex, this function will return the list of all locations that is connected to &amp;lt;location&amp;gt; only by keeps or castle. I.e the hexes you can recruit from, assumin that you are at a keep at &amp;lt;location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 'close enemies' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;units list&amp;gt; = close_enemies( &amp;lt;location&amp;gt; , &amp;lt;distance&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function gets a list of enemies in the given or smaller distance from the location. For example:&lt;br /&gt;
&lt;br /&gt;
 close_enemies(loc(10,10), 5)&lt;br /&gt;
&lt;br /&gt;
gives back a list of enemies in the distance of 5 tiles or less from the tile (10, 10).&lt;br /&gt;
&lt;br /&gt;
=== 'distance_between' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = distance_between( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns distance (in hexes) between &amp;lt;location A&amp;gt; and &amp;lt;location B&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 distance_between( loc( 1, 1) , loc( 3, 3) )&lt;br /&gt;
&lt;br /&gt;
will return 3.&lt;br /&gt;
&lt;br /&gt;
=== 'distance_to_nearest_unowned_village' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = distance_to_nearest_unowned_village( &amp;lt;location A&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns distance (in hexes) between &amp;lt;location A&amp;gt; and nearest unowned village.&lt;br /&gt;
&lt;br /&gt;
=== 'defense_on' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = defense_on( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns defense rate of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 defense_on( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows how good defense your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
=== 'find_shroud' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;locations list&amp;gt; = find_shroud()&lt;br /&gt;
&lt;br /&gt;
This function will return a list of locations of shrouded hexes.&lt;br /&gt;
&lt;br /&gt;
=== 'is_unowned_village' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = is_unowned_village( &amp;lt;map or ai.map&amp;gt; , &amp;lt;location&amp;gt; )   #1&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = is_unowned_village( &amp;lt;map or ai.map&amp;gt; , &amp;lt;coordinate x&amp;gt; , &amp;lt;coordinate y&amp;gt; )   #2&lt;br /&gt;
&lt;br /&gt;
The first argument is always a 'map' - member of the ai which provides information about the gamemap.&lt;br /&gt;
&lt;br /&gt;
This will return true if we don't own the village (i.e it is unowned, owned by an ennemy, or owned by al allie)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== 'is_village' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = is_village( &amp;lt;map or ai.map&amp;gt; , &amp;lt;location&amp;gt; )   #1&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = is_village( &amp;lt;map or ai.map&amp;gt; , &amp;lt;coordinate x&amp;gt; , &amp;lt;coordinate y&amp;gt; )   #2&lt;br /&gt;
&lt;br /&gt;
The first argument is always a 'map' - member of the ai which provides information about the gamemap.&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
 is_village( map , loc( 2, 3) )&lt;br /&gt;
&lt;br /&gt;
 is_village( map , 2, 3)&lt;br /&gt;
&lt;br /&gt;
Both check, if hex with coordinates 2,3 is a village.&lt;br /&gt;
&lt;br /&gt;
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'.&lt;br /&gt;
&lt;br /&gt;
=== 'loc' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;location&amp;gt; = loc( &amp;lt;X number&amp;gt;, &amp;lt;Y number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function will return a location (pair of numbers) from two given input arguments.&lt;br /&gt;
&lt;br /&gt;
=== 'shortest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = shortest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; [, &amp;lt;unit location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
When only 2 parameters are specified, function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;. If optional 3rd parameter is specified, it returns list with all locations that unit standing on &amp;lt;unit location&amp;gt; would need to move through to get from &amp;lt;location A&amp;gt; to &amp;lt;location B&amp;gt;. This function takes into account zone of control of enemy units.&lt;br /&gt;
&lt;br /&gt;
=== 'simplest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = simplest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; [, &amp;lt;unit location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
When only 2 parameters are specified, function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;. If optional 3rd parameter is specified, it returns list with all locations that unit standing on &amp;lt;unit location&amp;gt; would need to move through to get from &amp;lt;location A&amp;gt; to &amp;lt;location B&amp;gt;. This function does not take into account zone of control or enemy units.&lt;br /&gt;
&lt;br /&gt;
=== 'unit_at' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = unit_at( &amp;lt;location&amp;gt; ) &lt;br /&gt;
&lt;br /&gt;
This function takes only one argument - location, and returns unit if there is one standing in that location, or null otherwise. Example of usage:&lt;br /&gt;
&lt;br /&gt;
 unit_at( loc( 4, 4) )&lt;br /&gt;
&lt;br /&gt;
=== 'nearest_keep' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;keep location&amp;gt; = nearest_keep( &amp;lt;input location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns location of nearest keep to the specified &amp;lt;input location&amp;gt;, or null if there is no keep on the map.&lt;br /&gt;
&lt;br /&gt;
=== 'nearest_loc' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;keep location&amp;gt; = nearest_keep( &amp;lt;input location&amp;gt;, &amp;lt;list of locations&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns location that is the nearest to &amp;lt;input location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'unit_moves' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;locations list&amp;gt; = unit_moves( &amp;lt;unit location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns list of all possible locations which unit standing at &amp;lt;unit location&amp;gt; can reach. If unit can't move, or there is no unit standing at given location, empty list is returned.&lt;br /&gt;
&lt;br /&gt;
=== 'units_can_reach' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;units list&amp;gt; = units_can_reach( &amp;lt;possible moves list&amp;gt;, &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
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 &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Recruitment ==&lt;br /&gt;
&lt;br /&gt;
=== 'recruit' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = recruit( &amp;lt;unit name&amp;gt; [, &amp;lt;location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function results in recruting a unit specifed by &amp;lt;unit name&amp;gt; at first free castle hex, or at given &amp;lt;location&amp;gt;. Function:&lt;br /&gt;
&lt;br /&gt;
 recruit('Footpad', loc(3,3) ) &lt;br /&gt;
&lt;br /&gt;
will result in recruting Footpad at castle hex with coordinates 3,3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Benetnash</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=30105</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=30105"/>
		<updated>2009-04-11T14:45:37Z</updated>

		<summary type="html">&lt;p&gt;Benetnash: my_attacks description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI is an attempt to develop an AI framework for Wesnoth that allows easy and fun development and modification of AIs for Wesnoth.&lt;br /&gt;
&lt;br /&gt;
Wesnoth already has support for AIs written in Python, but writing AIs in Python has a couple of problems:&lt;br /&gt;
&lt;br /&gt;
* it's still rather difficult, especially for a non-programmer, to develop an AI, even in Python&lt;br /&gt;
* Python is insecure; a malicious trojan horse Python script masquerading as an AI could do untold damage&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI aims to create a fairly simple, pure functional language which allows one to implement an AI. It also aims to allow AIs to be tweaked and modified by people with relatively little technical skill; anyone who can use WML should also be able to use the Formula AI to tweak an AI to make the AI in a scenario behave how they want.&lt;br /&gt;
&lt;br /&gt;
The Wesnoth Formula AI is currently in an experimental stage of development. One can play with it and develop a rudimentary AI. Feedback is appreciated.&lt;br /&gt;
&lt;br /&gt;
To develop an AI using the Formula AI, set ai_algorithm=formula_ai in [side].&lt;br /&gt;
&lt;br /&gt;
== How formulas get called ==&lt;br /&gt;
&lt;br /&gt;
=== Formulas Command Line ===&lt;br /&gt;
&lt;br /&gt;
To attempt to make it convenient to debug formulas, one can run formulas from within Wesnoth, and see the results. To run a formula, just start game and type 'f'. A command textbox will appear, where you can type a formula, and the results will be printed. For instance, typing&lt;br /&gt;
&lt;br /&gt;
 8 + 4 &lt;br /&gt;
&lt;br /&gt;
will result in &amp;quot;12&amp;quot; appearing on the screen. You can now use Wesnoth like a calculator. :-)&lt;br /&gt;
&lt;br /&gt;
=== Side-wide formulas ===&lt;br /&gt;
The first way to get a formula called is to assign it to a [side] in a WML map. This formula will be called every turn, so it is best used for very simple sides (a couple of special units which should have semi-scripted moves, or a simple handling followed by calls to the standard C++ AI)&lt;br /&gt;
&lt;br /&gt;
To use the Formula AI, one should put an [ai] tag inside the [side] tag. Inside this [ai] tag, one should specify the 'move' attribute to be a formula which specifies what movement the AI will make. Each time it's the AI's move, this formula will be run, and the move it results in will be executed. Then the formula will be run again; it'll continue to be run until it stops producing a valid move, at which point the AI will end its turn. Alternatively there is a command that the formula may return which will make it end its turn immediately.&lt;br /&gt;
&lt;br /&gt;
A sample AI which does nothing but recruit Wolf Riders is as follows:&lt;br /&gt;
&lt;br /&gt;
 [side]&lt;br /&gt;
 ...&lt;br /&gt;
 ai_algorithm=formula_ai&lt;br /&gt;
   [ai]&lt;br /&gt;
   move=&amp;quot;recruit('Wolf Rider')&amp;quot;&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/side]&lt;br /&gt;
&lt;br /&gt;
=== Unit Formulas ===&lt;br /&gt;
&lt;br /&gt;
You can specify a formula for any kind of unit. This is a simple way of doing it:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
   ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Custom unit formulas are executed first at the begining of side's turn. Above formula will simply move unit one hex to the north every turn. Note how &amp;quot;me&amp;quot; keyword allows access to unit itself.&lt;br /&gt;
&lt;br /&gt;
If you need to execute unit formulas in a specific order, you can set a priority:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
   ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&lt;br /&gt;
     priority=10&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Units with highest priority get their formula executed first.&lt;br /&gt;
&lt;br /&gt;
You can also define AI unit-specific variables and use them in you formulas:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
   [ai]&lt;br /&gt;
     formula=&amp;quot;if(attack, attack, move(me.loc, me.vars.guard_loc) )&lt;br /&gt;
        where attack = choose(filter(attacks, units = [me.loc] and distance_between(me.vars.guard_loc, target) &amp;lt;= me.vars.guard_radius and unit_at(target).side=me.vars.hostile_side-1 ), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     [vars]&lt;br /&gt;
       guard_radius=3&lt;br /&gt;
       guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
       hostile_side=1&lt;br /&gt;
     [/vars]&lt;br /&gt;
   [/ai]&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
This formula will get location position from variable guard_loc and make sure that unit attacks only opponent from side 1 (value specified by hostile_side variable) which is 3 hexes (guard_radius) or less from guard_loc.&lt;br /&gt;
&lt;br /&gt;
Types of variables that are supported:&lt;br /&gt;
*number:&lt;br /&gt;
 variable=3&lt;br /&gt;
*text (important: note the ' ' within &amp;quot; &amp;quot;):&lt;br /&gt;
 name=&amp;quot;'I am variable'&amp;quot;&lt;br /&gt;
*list:&lt;br /&gt;
 number_list=[ 1, 2, 3]&lt;br /&gt;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Candidate move evaluation ===&lt;br /&gt;
==== Overview ====&lt;br /&gt;
Units in wesnoth have all sort of special abilities, special powers and special usages. Thus, it was needed to have an easy way to describe special behaviour for special units. Adding an formula to a unit only partially solves the problem. It allows easily to have special units (like ennemy heroes) have special behaviour but not normal units with special powers to to behave smartly. &lt;br /&gt;
&lt;br /&gt;
Candidate moves are a way to have formula that will&lt;br /&gt;
&lt;br /&gt;
* evaluate a given situation&lt;br /&gt;
* see if they are able to provide &amp;quot;special moves&amp;quot; for the case they know how to handle&lt;br /&gt;
* give a move to do if the situation match their condition&lt;br /&gt;
&lt;br /&gt;
==== Evaluation Algorithm ====&lt;br /&gt;
&lt;br /&gt;
Each side will have some candidate move blocks made of&lt;br /&gt;
* a name for the move&lt;br /&gt;
* a type (see below for description of the different types and how they are called)&lt;br /&gt;
* a formula returning a score for the move&lt;br /&gt;
* a formula returning the move to do&lt;br /&gt;
&lt;br /&gt;
The engine will run the following pseudo-code&lt;br /&gt;
&lt;br /&gt;
 while (a formula returned a score greatern than 0) {&lt;br /&gt;
      foreach (registered candidate move) {&lt;br /&gt;
           foreach (set of parameters for that candidate move's type) {&lt;br /&gt;
               call the evaluation formula, note the score returned&lt;br /&gt;
           }&lt;br /&gt;
      }&lt;br /&gt;
      if (the highest score returned was greater than 0) {&lt;br /&gt;
          call the candidate move that returned the highest score with the corresponding set of parameters&lt;br /&gt;
      }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
in other word, we evaluate all candidate moves, then run the candidate move with the highest score, then re-evaluate everything, until no candidate move wants to play anymore&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Syntax ====&lt;br /&gt;
to add a new candidate move you should add '''[register_candidate_move]''' blocks within the '''[ai]''' block.&lt;br /&gt;
&lt;br /&gt;
Each block will describe a candidate move and must have the following fields&lt;br /&gt;
&lt;br /&gt;
* ''name'' : the name of this candidate block&lt;br /&gt;
* ''type'' : see the paragraph about types below, this describe the implicite variables that the formulas will be called with&lt;br /&gt;
* ''evaluation'' : a formula returning an integer. This number reflects how good the move is compared to other moves. Values of zero will mean the move is not a good idea and should be skipped&lt;br /&gt;
* ''action'' : A formula that will be called if that candidate move is the best one&lt;br /&gt;
==== Candidate move types ====&lt;br /&gt;
&lt;br /&gt;
there are two types of candidate moves&lt;br /&gt;
&lt;br /&gt;
* '''attack''' : these are called once for every pair &amp;lt;me,target&amp;gt; where me is a variable set to a unit on the AI side, and target is a variable set to an ennemy unit that &amp;quot;me&amp;quot; can reach&lt;br /&gt;
* '''movement''' : these are called once for every unit on the AI side, the &amp;quot;me&amp;quot; variable is set to the corresponding unit&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary : a typical AI turn ===&lt;br /&gt;
&lt;br /&gt;
An AI turn will run the following formulas. Any formula returning an &amp;quot;end turn&amp;quot; move will (of course) finish the turn. But assuming this doesn't happen :&lt;br /&gt;
* All unit formulas are called once&lt;br /&gt;
* All candidate moves are evaluated and played&lt;br /&gt;
* All ''move='' formulas are called until they don't return valid moves&lt;br /&gt;
* If no ''move='' formula is provided, we drop automatically to C++&lt;br /&gt;
* Turn is ended.&lt;br /&gt;
&lt;br /&gt;
Note that this means that you have to explicitely call &amp;quot;fallback&amp;quot; if you want the C++ AI to finish your moves after a side-wide formula&lt;br /&gt;
&lt;br /&gt;
== Formula Basics ==&lt;br /&gt;
&lt;br /&gt;
* The Formula language supports basic arithmetic operations, such as: +, -, *, /, % and ^. It supports integers but does NOT support decimal or floating point numbers. For example:&lt;br /&gt;
&lt;br /&gt;
 4 + 8*7     #evaluates to 60&lt;br /&gt;
 (4 + 8)*7   #evaluates to 84&lt;br /&gt;
 8 % 6       #evaluates to 2&lt;br /&gt;
 5 / 2       #evaluates to 2&lt;br /&gt;
 3 ^ 2       #evaluates to 9&lt;br /&gt;
&lt;br /&gt;
* It also supports equality, = and !=, and comparison operators, &amp;lt;, &amp;gt;, &amp;lt;=, and &amp;gt;=. 'false' values are 0 (integer) and null. Other values are true. It also supports common operators such as and, or, and not:&lt;br /&gt;
&lt;br /&gt;
 2 = 4     #evaluates to 0&lt;br /&gt;
 2 &amp;lt;= 3    #evaluates to 1&lt;br /&gt;
 0 != 1    #evaluates to 1&lt;br /&gt;
 not 4     #evaluates to 0&lt;br /&gt;
 not 0     #evaluates to 1&lt;br /&gt;
 (2 &amp;lt; 4) and (3 &amp;gt; 6)    #evaluates to 1 and 0 which evaluates to 0&lt;br /&gt;
 (2 &amp;lt; 4) or (3 &amp;gt; 6)     #evaluates to 1 or 0 which evaluates to 1&lt;br /&gt;
&lt;br /&gt;
* Formula language supports also 'dice' operator 'd'. Example usage is:&lt;br /&gt;
&lt;br /&gt;
 3d5&lt;br /&gt;
&lt;br /&gt;
Which will give you one of results of rolling three five-sided dice (so random number between 3 and 15). NOTE: We encourage you to use this operator only when it is really needed. In most cases, you should not base the AI decisions on random results except for scenario replayability purposes.&lt;br /&gt;
&lt;br /&gt;
== Data Types ==&lt;br /&gt;
&lt;br /&gt;
Formula System supports different types of data, which can be stored as a variables and are used in evaluations:&lt;br /&gt;
&lt;br /&gt;
* Numbers: like 0, 1, 2 etc. Floating-point numbers are not supported. 0 is equal to logical 'false', any other number is 'true'.&lt;br /&gt;
&lt;br /&gt;
* Text strings: &lt;br /&gt;
&lt;br /&gt;
 'this is a text string' &lt;br /&gt;
&lt;br /&gt;
* Lists: A list is a sequence of values. For example, ai.my_units is a list of unit objects. A list is represented as square brackets, [], surrounding a comma-seperated list. For instance: &lt;br /&gt;
&lt;br /&gt;
 [4, 8, 7] &lt;br /&gt;
&lt;br /&gt;
is a list of three numbers, and &lt;br /&gt;
&lt;br /&gt;
 []&lt;br /&gt;
&lt;br /&gt;
is a empty list. Various functions can operate on lists.&lt;br /&gt;
&lt;br /&gt;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
Some of these variables are complicated data structues, calling their name from the formula command line will allow you to easily see their content&lt;br /&gt;
&lt;br /&gt;
use the '''dir''' and '''debug_print''' to inspect the variables&lt;br /&gt;
&lt;br /&gt;
to get a coplete list, use the &lt;br /&gt;
 dir(self)&lt;br /&gt;
command&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* ''attacks'' a list of all possible attacks&lt;br /&gt;
NOTE: this variable returns a list of all possible attacks (including attack combinations - attacking a single enemy unit with several units) , which is immediately treated as list of attack orders, which is evaluated (so, evaluation of this variable results in attacks being made). If you want to get the list without such evaluation, wrap it inside the array, &amp;quot;[attacks]&amp;quot;. If you want to get the first attack, wrap it inside the array twice, &amp;quot;[[attacks[0]]&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
* ''my_attacks'' a list of all possible attacks. It returns slightly different list then ''attacks''. I.e. when only two units (attacker and dedenter) are on the board ''attacks'' return one attack, from the position with the highest defence and ''my_attacks'' returns all 6 attacks from all adjacent tiles.&lt;br /&gt;
* ''my_side'' global variables describing your own side&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''time_of_day'' the current time of day&lt;br /&gt;
* ''keeps'' all keep locations&lt;br /&gt;
* ''vars'' all localy set varables using the set_far function&lt;br /&gt;
* ''allies'' a list of all sides that are friendly&lt;br /&gt;
* ''ennemies'' a list of all sides that are enemy&lt;br /&gt;
* ''my_moves'' a list of all my moves&lt;br /&gt;
* ''enemy_moves'' a list of all enemy moves&lt;br /&gt;
* ''my_leader'' our leader unit&lt;br /&gt;
* ''my_recruits'' the list of units that can be recruited by us&lt;br /&gt;
* ''recruits_of_side'' foreach side the list of units that can be recruited&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''units_of_side'' foreach side, a list of all owned units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''enemy_units'' all units that are enemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''villages_of_side'' for each side, the list of villages owned&lt;br /&gt;
* ''enemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(ai*) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(ai*) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(ai*)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&lt;br /&gt;
&lt;br /&gt;
You can easily split your formulas between different files and include them when necessary. For example:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
  formula={my_unit_formula.fai}&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Will look for unit formula in the my_unit_formula.fai file.&lt;br /&gt;
&lt;br /&gt;
Although it is not mandatory, we advocate to use following syntax in your fai files:&lt;br /&gt;
&lt;br /&gt;
 faifile '&amp;lt;filename&amp;gt;'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
This makes formula system know which file it is working with now, and gives you improved error reporting, which is often really helpful. Valid syntax for my_unit_formula.fai would be:&lt;br /&gt;
&lt;br /&gt;
 faifile 'my_unit_formula.fai'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
== Tool Support ==&lt;br /&gt;
&lt;br /&gt;
=== ctags ===&lt;br /&gt;
&lt;br /&gt;
For some rudimentary support for exuberant ctags, add the following to .ctags (or create the file if it doesn't exist):&lt;br /&gt;
&lt;br /&gt;
 --langdef=formulaai&lt;br /&gt;
 --langmap=formulaai:.fai&lt;br /&gt;
 --regex-formulaai=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/&lt;br /&gt;
&lt;br /&gt;
This is especially nice when used with an editor or plugin with ctags support, such as Taglist for Vim.&lt;br /&gt;
&lt;br /&gt;
=== Vim ===&lt;br /&gt;
&lt;br /&gt;
====Syntax Highlighting====&lt;br /&gt;
&lt;br /&gt;
Follow these steps to enjoy vim syntax highlighting support for Formula AI.&lt;br /&gt;
&lt;br /&gt;
# Grab the Formula AI vim syntax file, [http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/tools/vim/formulaai.vim formulaai.vim].&lt;br /&gt;
# Copy formulaai.vim to .vim/syntax &lt;br /&gt;
# Add the following to .vimrc :&lt;br /&gt;
 autocmd! BufRead,BufNewFile *.fai setfiletype formulaai&lt;br /&gt;
&lt;br /&gt;
====Taglist Support====&lt;br /&gt;
&lt;br /&gt;
First you will need the very nice [http://www.vim.org/scripts/script.php?script_id=273 taglist plugin].  Follow the link for downloads and install directions if you don't already have it installed.&lt;br /&gt;
&lt;br /&gt;
Next, you'll need Formula AI support for exuberant ctags, follow the instructions in the [[#ctags|ctags]] section.  &lt;br /&gt;
&lt;br /&gt;
Once you have all that, simply add the following line to your .vimrc:&lt;br /&gt;
 &lt;br /&gt;
 let tlist_formulaai_settings = 'formulaai;d:definition'&lt;br /&gt;
&lt;br /&gt;
To test it all out, open a Formula AI script file and enter the command &lt;br /&gt;
 :Tlist&lt;br /&gt;
&lt;br /&gt;
You should now have some nice highlighting and be able to easily navigate through formula, enjoy!&lt;br /&gt;
  &lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Benetnash</name></author>
		
	</entry>
</feed>