<?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=Dhains</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=Dhains"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/Special:Contributions/Dhains"/>
	<updated>2026-04-09T21:20:51Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=26087</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=26087"/>
		<updated>2008-07-03T07:58:12Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Gamemap functions */&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 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&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;reult&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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
=== '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;
=== '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;
=== '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;
&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;
= 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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;
&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;
=== 'evaluate_village_possession' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = evaluate_village_possession()&lt;br /&gt;
&lt;br /&gt;
This function returns number between 0 and 100, where 0 means that all of the villages belong to the enemy, and 100 means that all of the villages belong to the AI. Value of 50 represents draw-like situation.&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;
== Gamemap functions ==&lt;br /&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_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;
=== '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;
=== '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;
=== 'unit_chooser' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = unit_chooser( &amp;lt;map with unit names and weights&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes a map of unit names and attached to these names numbers - representing how should 'ideal army' look like - and as a result it recruits one unit which is most needed, according to the input map. For example:&lt;br /&gt;
&lt;br /&gt;
 unit_chooser( { 'Elvish Fighter' -&amp;gt; 60, 'Elvish Archer' -&amp;gt; 30, 'Elvish Shaman' -&amp;gt; 10 } )&lt;br /&gt;
&lt;br /&gt;
We 'inform' the function that our army should consist of 60% fighters, 30% archers and 10% shamans, function checks the current ratio of the units and choses one unit that is most needed at the moment.&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25799</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25799"/>
		<updated>2008-05-26T17:59:30Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* WML Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI &amp;amp; WML  ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the purpose of some formula is, i.e. we might have special formula for recruitment, candidate moves selection, etc.  We also wish to return an integer which would be an evaluation for the proposed move.&lt;br /&gt;
  &lt;br /&gt;
The following syntax is proposed to accomplish this:&lt;br /&gt;
&lt;br /&gt;
 [register_candidate_move]&lt;br /&gt;
  name= &amp;lt;name of move&amp;gt;&lt;br /&gt;
  type= movement/recruitment/etc&lt;br /&gt;
  action= &amp;lt;action returning formula&amp;gt;&lt;br /&gt;
  evaluation= &amp;lt;int returning formula&amp;gt;&lt;br /&gt;
 [/register_candidate_move]&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25798</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25798"/>
		<updated>2008-05-26T17:59:17Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* WML Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI &amp;amp; WML  ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the purpose of some formula is, i.e. we might have special formula for recruitment, candidate moves selection, etc.  We also wish to return an integer which would be an evaluation for the proposed move.&lt;br /&gt;
  &lt;br /&gt;
The following syntax is proposed to accomplish this:&lt;br /&gt;
&lt;br /&gt;
 [register_candidate_move]&lt;br /&gt;
  name= &amp;lt;name of move&amp;gt;&lt;br /&gt;
  type= movement/recruitment/etc&lt;br /&gt;
  result= &amp;lt;action returning formula&amp;gt;&lt;br /&gt;
  evaluation= &amp;lt;int returning formula&amp;gt;&lt;br /&gt;
 [/register_candidate_move]&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25797</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25797"/>
		<updated>2008-05-26T17:49:18Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* WML Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI &amp;amp; WML  ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the purpose of some formula is, i.e. we might have special formula for recruitment, candidate moves selection, etc.  We also wish to return an integer which would be an evaluation for the proposed move.&lt;br /&gt;
  &lt;br /&gt;
The following syntax is proposed to accomplish this:&lt;br /&gt;
&lt;br /&gt;
 [register_candidate_move]&lt;br /&gt;
  name= &amp;lt;name of move&amp;gt;&lt;br /&gt;
  type= movement/recruitment/etc&lt;br /&gt;
  evaluation= &amp;lt;int returning formula&amp;gt;&lt;br /&gt;
  result= &amp;lt;action returning formula&amp;gt;&lt;br /&gt;
 [/register_candidate_move]&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25726</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25726"/>
		<updated>2008-05-19T16:38:21Z</updated>

		<summary type="html">&lt;p&gt;Dhains: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
==Project Progess==&lt;br /&gt;
&lt;br /&gt;
[[GsocAIProjectProgress]]&lt;br /&gt;
&lt;br /&gt;
==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature.  Terrain information is now available to Formula AI using 'map.terrain' from within Formula AI.  This allowed implementation of the 'woodchopper' feature requested on the forums.&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365], [http://svn.gna.org/viewcvs/wesnoth?rev=25455&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
Various bug fixes: [http://svn.gna.org/viewcvs/wesnoth?rev=25452&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25460</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25460"/>
		<updated>2008-04-30T19:01:48Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* AI API: Formula AI -&amp;gt; WML -&amp;gt; AI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI &amp;amp; WML  ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the purpose of some formula is, i.e. we might have special formula for recruitment, candidate moves selection, etc.  We also wish to return an integer which would be an evaluation for the proposed move.&lt;br /&gt;
  &lt;br /&gt;
The following syntax is proposed to accomplish this:&lt;br /&gt;
&lt;br /&gt;
 [register_candidate_move]&lt;br /&gt;
  type= movement/recruitment/etc&lt;br /&gt;
  evaluation= &amp;lt;int returning formula&amp;gt;&lt;br /&gt;
  result= &amp;lt;action returning formula&amp;gt;&lt;br /&gt;
 [/register_candidate_move]&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25459</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25459"/>
		<updated>2008-04-30T19:01:08Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* WML Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the purpose of some formula is, i.e. we might have special formula for recruitment, candidate moves selection, etc.  We also wish to return an integer which would be an evaluation for the proposed move.&lt;br /&gt;
  &lt;br /&gt;
The following syntax is proposed to accomplish this:&lt;br /&gt;
&lt;br /&gt;
 [register_candidate_move]&lt;br /&gt;
  type= movement/recruitment/etc&lt;br /&gt;
  evaluation= &amp;lt;int returning formula&amp;gt;&lt;br /&gt;
  result= &amp;lt;action returning formula&amp;gt;&lt;br /&gt;
 [/register_candidate_move]&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25458</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25458"/>
		<updated>2008-04-30T18:48:24Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* WML Tags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
==== WML Tags ====&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the prupose of some formula is, i.e. we might have special formula for recruitment, evaluation functions, candidate move selection, etc.  Additional formula inclusion tags will be used to classify these different formula function types&lt;br /&gt;
&lt;br /&gt;
* formula_recruit : this tag will specify a formula to be used for recruitment&lt;br /&gt;
* formula_eval : This tag specifies evaluation functions &lt;br /&gt;
* move: formula_move : Candidate moves (?), we might not need this, it may be OK to just use the normal formula tag&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25457</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25457"/>
		<updated>2008-04-30T18:48:06Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* AI API: Formula AI -&amp;gt; WML -&amp;gt; AI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers and AI designers.&lt;br /&gt;
&lt;br /&gt;
== WML Tags ==&lt;br /&gt;
&lt;br /&gt;
Currently formula can be included with formula=.  The AI will need to know what the prupose of some formula is, i.e. we might have special formula for recruitment, evaluation functions, candidate move selection, etc.  Additional formula inclusion tags will be used to classify these different formula function types&lt;br /&gt;
&lt;br /&gt;
* formula_recruit : this tag will specify a formula to be used for recruitment&lt;br /&gt;
* formula_eval : This tag specifies evaluation functions &lt;br /&gt;
* move: formula_move : Candidate moves (?), we might not need this, it may be OK to just use the normal formula tag&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25445</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25445"/>
		<updated>2008-04-29T15:19:53Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Basic Idea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules are sufficient for many situations, but they cannot predict everything.  There will always be some area of incomplete knowledge, i.e. we cannot code into the deterministic rules complete knowledge of the game and every situation the AI will ever face.  In fact, experienced players may even be able to infer some of the deterministic rules and use this knowledge to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers.&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25444</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25444"/>
		<updated>2008-04-29T15:17:57Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Basic Idea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event, the AI had no knowledge of an enemy tactic or unit and a certain unit which the Formula AI ranked very high begins to be massacred due to this incomplete knowledge.  The weight associated with that particular unit can now be adjusted to some value &amp;lt; 1 by the AI.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers.&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25441</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25441"/>
		<updated>2008-04-28T18:49:39Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
The success/failure of a move will also be an important component.  This might also change depending on the scenario.  One possible idea is to also write this in Formula AI, thus allowing it easily to be changed on a scenario by scenario basis.  The basic idea is that after a move is taken, the new situation is evaluated and a score is given.  We might even be able to use the already defined eval functions to produce this score, but we want to come up with a delta value, i.e. the difference of the score before the move and after the move.  Then this delta value will be applied to the weight associated with the move as such:&lt;br /&gt;
&lt;br /&gt;
weight_new = weight_old + delta * alpha&lt;br /&gt;
&lt;br /&gt;
Where alpha is our step size as discussed earlier.  In this way, a negative delta will cause the weight to decrease since the move resulted in a poorer game state and vice versa for a good move.  Again, it's important to stress the importance of the alpha size and delta values to be calculated carefully.  A poor move might be better in the long run (or a very good move might look bad due to a bad RNG round) and we don't want to punish moves too severely for causing a negative delta.  On the other hand, we don't want to adjust weights too slowly.&lt;br /&gt;
&lt;br /&gt;
The other nice thing is the learning system  can be turned off quite easily, perhaps for an initial experimentation stage, difficulty setting,  or if the scenario designer wishes the AI to strictly followed a supplied FormulaAI script, by simply using a flag to determine if the weights should be calculated or not.  Since they are initialized to 1, it's a trivial thing to turn this system on and off.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers.&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25440</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25440"/>
		<updated>2008-04-28T18:39:17Z</updated>

		<summary type="html">&lt;p&gt;Dhains: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
== AI API ==&lt;br /&gt;
=== AI API: Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how Formula AI should be written (Formula AI scripts, Formula AI libraries, etc.)&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; WML -&amp;gt; AI ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the formula AI will be included in WML and how the WML will be processed.  This layer should be transparent to the AI itself, but will be the one mainly used by scenario designers.&lt;br /&gt;
&lt;br /&gt;
=== AI API: Formula AI -&amp;gt; C++ ===&lt;br /&gt;
&lt;br /&gt;
Here we define how the Formula AI interfaces with the C++ part (i.e. how should moves be supplied, how the moves will be selected and weights applied)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25439</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25439"/>
		<updated>2008-04-28T18:32:20Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* AI: C++ &amp;lt;-&amp;gt; Formula AI Interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
== AI API: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25438</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25438"/>
		<updated>2008-04-28T18:31:59Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If this move is chosen and executed and is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once or perhaps an epic failure one time (i.e. loss of a key team member, something fairly catastrophic).  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25437</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25437"/>
		<updated>2008-04-28T18:28:20Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions that come up from this idea:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
# ) How do we evaluate the success/failure of a move?&lt;br /&gt;
# ) How much should we adjust the weights based on this evaluation?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purpose of associating weights to moves.  &lt;br /&gt;
&lt;br /&gt;
The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the overall team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a high chance of being selected.  If the move is found to be successful, the associated weight will be increased.  If the move is deemed to be a failure, the weight will be further decreased.  In this way, we won't throw out very strong moves based on one failure.  To offset the chance of a very strong move being chosen, it most have been found to be a failure more then once.  This makes the learning system somewhat robust in terms of flukes in the RNG, etc.  &lt;br /&gt;
&lt;br /&gt;
3., 4.) This brings up another question(s), how to adjust the weights.  We don't want to adjust the weights too fast, or simple RNG fluke could make it so that a strong, viable move is never chosen.  We don't want to adjust to small, or the learning system will not be effective over a single scenario.  We can call this weight step size alpha, and finding a good alpha value as well as functions to evaluate the success and failure of the moves are additional questions to be answered.  In my AI experience, finding a good alpha value is more or less a trial and error process.  We can make a close initial guess, but play testing and fine tuning will most likely be necessary to find the optimal alpha.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25436</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25436"/>
		<updated>2008-04-28T18:20:01Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Basic Idea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is aless complex then a full fledged AI and the learning system may not be as necessary as it will be in a full fledged AI, but recruitment serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions which are to be answered:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purposes of these moves.  The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a chance of being selected.  If the move is found to be successful, the associated weight will be increased.  The next section will give move technical details on how this is to be implemented.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25435</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25435"/>
		<updated>2008-04-28T18:19:10Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Basic Idea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  The learning system will give the AI the ability to tweak it's strategy on the fly to cope with player strategies that the deterministic rules cannot deal with.  Recruitment is a little less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full AI, but serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions which are to be answered:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purposes of these moves.  The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a chance of being selected.  If the move is found to be successful, the associated weight will be increased.  The next section will give move technical details on how this is to be implemented.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25434</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25434"/>
		<updated>2008-04-28T18:17:10Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  Recruitment is a little less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full AI, but serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions which are to be answered:&lt;br /&gt;
&lt;br /&gt;
# ) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# ) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
&lt;br /&gt;
1.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
2.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purposes of these moves.  The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a chance of being selected.  If the move is found to be successful, the associated weight will be increased.  The next section will give move technical details on how this is to be implemented.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25433</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25433"/>
		<updated>2008-04-28T18:16:30Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Basic Idea */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose due fog of war or some other event the AI had no knowledge of certain players tactics or units and a certain unit which the Formula AI ranked very high begins to be massacred.  Now the weight associated with that particular unit can be adjusted to some value &amp;lt; 1.  This will decrease the chance of the AI choosing these units, even though the FormulaAI scores them fairly high.&lt;br /&gt;
&lt;br /&gt;
The point of this learning system is that deterministic rules maybe good for many situations, but they cannot predict everything.  In fact, experienced players may infer some of the deterministic rules and use them to their advantage.  Recruitment is a little less complex then a full fledged AI and the learning system may not be as necessary as it will be in a full AI, but serves as a useful illustration.&lt;br /&gt;
&lt;br /&gt;
=== Questions ===&lt;br /&gt;
&lt;br /&gt;
Some of the main questions which are to be answered:&lt;br /&gt;
&lt;br /&gt;
# A.) How does the FormulaAI provide the move and evals to the C++ learning system?&lt;br /&gt;
# B.) How will the C++ learning system evaluate game state and know if it is in a similar situation to one it has been in before (i.e. how does it know which weights to associate to which moves)?&lt;br /&gt;
&lt;br /&gt;
A.) For this I think the formulaAI can provide a list of &amp;lt;move,score&amp;gt; pairs.  This provides a simple way for the AI to choose a move, simply pick the move with the highest associated score.  This also makes it easy to apply weights, before choosing a particular move, it will apply the weight associated to each move to it's associated score.  This leads to the second question, how will the AI know if a certain move is the same as one it has seen previously?&lt;br /&gt;
&lt;br /&gt;
B.) The search space is too complex to keep any kind of state table.  I think the best way to associate weights to moves is to 'categorize' the moves.  For instance, in the recruitment example the categorization is easy, we simply categorize each recruitment move by the unit  that move recruits.  The C++ learning system can then keep a list of the categories and the associated weights.&lt;br /&gt;
&lt;br /&gt;
For the more complex examples of non-recruitment moves, I think we can extend this idea of categorization.  A very simple high level move categorization is: attack, move, defend.  We might be able to further categorize attack moves by tuples (attacking unit, defending unit, terrain).  Move moves might be categorized by the tuple (moving unit, terrain), etc.&lt;br /&gt;
&lt;br /&gt;
I think this idea will allow us to associate weights with moves via these categories.  There will always be a finite number of these tuples and we need not track the entire state of the space for the purposes of these moves.  The deterministic eval functions which associate the initial scores to moves are what evaluate the state space in terms of the team goals, etc.  Even if a &amp;lt; 1 weight is associated with a move, if the eval functions determine the move to be the best move by a large margin, it still has a chance of being selected.  If the move is found to be successful, the associated weight will be increased.  The next section will give move technical details on how this is to be implemented.&lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25432</id>
		<title>GsocAIProjectProgress</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=GsocAIProjectProgress&amp;diff=25432"/>
		<updated>2008-04-28T17:53:42Z</updated>

		<summary type="html">&lt;p&gt;Dhains: New page: GSOC AI Project Progress   == Basic Idea ==  The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these m...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GSOC AI Project Progress &lt;br /&gt;
&lt;br /&gt;
== Basic Idea ==&lt;br /&gt;
&lt;br /&gt;
The basic idea is to develop libraries of FormulaAI moves based on eval functions.  The C++ part will then be able to adjust weights on these moves to 'tweak' them in each scenario.&lt;br /&gt;
&lt;br /&gt;
For example, consider a recruitment example:&lt;br /&gt;
&lt;br /&gt;
Eval functions in FormulaAI will be provided which will associate a 'score' to each unit the AI can recruit.  Based on these scores, the AI will recruit particular units.  Along with each of these 'scores' is an associated weight, originally set to 1.  Now suppose to do fog of war or some other event the AI had no knowledge of certain players tactics.  &lt;br /&gt;
&lt;br /&gt;
== AI: C++ &amp;lt;-&amp;gt; Formula AI Interface ==&lt;br /&gt;
&lt;br /&gt;
Here we define the API for the AI (i.e. C++ &amp;lt;-&amp;gt; FormulaAI interface)&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25431</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25431"/>
		<updated>2008-04-28T17:43:34Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* About Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[GsocAIProject]]&lt;br /&gt;
&lt;br /&gt;
==Project Progess==&lt;br /&gt;
&lt;br /&gt;
[[GsocAIProjectProgress]]&lt;br /&gt;
&lt;br /&gt;
==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature.  Terrain information is now available to Formula AI using 'map.terrain' from within Formula AI.  This allowed implementation of the 'woodchopper' feature requested on the forums.&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365], [http://svn.gna.org/viewcvs/wesnoth?rev=25455&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
Various bug fixes: [http://svn.gna.org/viewcvs/wesnoth?rev=25452&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25430</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25430"/>
		<updated>2008-04-28T17:42:58Z</updated>

		<summary type="html">&lt;p&gt;Dhains: added link to project page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[GsocAIProject]]&lt;br /&gt;
&lt;br /&gt;
==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature.  Terrain information is now available to Formula AI using 'map.terrain' from within Formula AI.  This allowed implementation of the 'woodchopper' feature requested on the forums.&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365], [http://svn.gna.org/viewcvs/wesnoth?rev=25455&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
Various bug fixes: [http://svn.gna.org/viewcvs/wesnoth?rev=25452&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25061</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25061"/>
		<updated>2008-04-03T07:02:40Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Terrain Knowledge */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature.  Terrain information is now available to Formula AI using 'map.terrain' from within Formula AI.  This allowed implementation of the 'woodchopper' feature requested on the forums.&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365], [http://svn.gna.org/viewcvs/wesnoth?rev=25455&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
Various bug fixes: [http://svn.gna.org/viewcvs/wesnoth?rev=25452&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25060</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25060"/>
		<updated>2008-04-03T04:39:03Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* My Contribs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365], [http://svn.gna.org/viewcvs/wesnoth?rev=25455&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
Various bug fixes: [http://svn.gna.org/viewcvs/wesnoth?rev=25452&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25022</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25022"/>
		<updated>2008-03-31T19:26:45Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Rulebases - Formula AI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment Rulebases === &lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
=== Team Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
=== Unit Rulebases ===&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25017</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25017"/>
		<updated>2008-03-31T19:22:12Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* My Contribs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal by implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25016</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25016"/>
		<updated>2008-03-31T19:21:06Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* My Contribs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal and implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
==== Terrain Knowledge ====&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
==== Formula AI Scripts ====&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves and Eval functions ====&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25014</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25014"/>
		<updated>2008-03-31T19:19:07Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* My Contribs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal and implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Exposed terrain, nearest_loc function, woodchopper example - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Documentation can be found on the [[FormulaAI|FormulaAI]] wiki page and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25013</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25013"/>
		<updated>2008-03-31T19:18:17Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* My Contribs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal and implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Expose terrain, nearest_loc, woodchopper - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Some documentation can be found on the [[FormulaAI|FormulaAI]] and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are now supported.  Documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25012</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=25012"/>
		<updated>2008-03-31T19:14:49Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added contibs section to show patches/commits&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
=== My Contribs ===&lt;br /&gt;
&lt;br /&gt;
Since I have been active with Wesnoth development for the past few weeks, I have submitted several patches and gained SVN access.  Since then, I have been focusing on getting Formula AI to a point where I can begin development of the ideas set forth in this proposal and implementing necessary features:&lt;br /&gt;
&lt;br /&gt;
These checkins exposed map and terrain features to Formula AI, a much needed feature, and implemented the 'woodchopper' feature requested on the forums:&lt;br /&gt;
&lt;br /&gt;
* Expose terrain, nearest_loc, woodchopper - [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365]&lt;br /&gt;
&lt;br /&gt;
Some documentation can be found on the [[FormulaAI|FormulaAI]] and also on the [http://www.wesnoth.org/forum/viewtopic.php?f=10&amp;amp;t=20471&amp;amp;st=0&amp;amp;sk=t&amp;amp;sd=a&amp;amp;start=15 Woodchopper forum thread]&lt;br /&gt;
&lt;br /&gt;
The overall goal of the following checkins was to create and support a new way of writing Formula AI, i.e. formula AI script files to allow reuse and support building of pluggable Formula libraries:&lt;br /&gt;
&lt;br /&gt;
* Created def keyword for custom functions: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=24993]&lt;br /&gt;
* Formula Script support: [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25052]&lt;br /&gt;
* Cleaned up Formula AI script read method : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25094]&lt;br /&gt;
* Fixed Parsing Bug in Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25099]&lt;br /&gt;
* Added Comment Support to Formula AI : [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25136]&lt;br /&gt;
* Checked in Vim Syntax Highlighting: [http://svn.gna.org/viewcvs/wesnoth?rev=25178&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
These files are now working...documentation can be found on the [[FormulaAI|FormulaAI]] page.&lt;br /&gt;
&lt;br /&gt;
The following checkins are to support the building of candidate move lists and evaluation functions (work in progress):&lt;br /&gt;
&lt;br /&gt;
* Initial support for candidate move lists [http://svn.gna.org/viewcvs/wesnoth?view=rev&amp;amp;rev=25365],[http://svn.gna.org/viewcvs/wesnoth?rev=25217&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
Initial Patches: [https://gna.org/patch/?1014], [https://gna.org/patch/?1016].&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24996</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24996"/>
		<updated>2008-03-31T18:23:40Z</updated>

		<summary type="html">&lt;p&gt;Dhains: grammar edit&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;nearest location&amp;gt; = nearest_loc(&amp;lt;location&amp;gt;, &amp;lt;list of locations&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns the closest location in &amp;lt;list of locations&amp;gt; which is closest in distance to &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 &lt;br /&gt;
 nearest_loc(me.loc, map(filter(terrain.map,id = &amp;quot;hills&amp;quot;),loc))&lt;br /&gt;
&lt;br /&gt;
will return the location of the hex with a hills terrain which is closest to current unit.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= Formula AI Scripts =&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are a way to separate Formula AI from WML files.  As the complexity of the AI rules grow, so will the formula.  Embedding formula in WML can create bloated cfg files and make it cumbersome to reuse AI scripts.  By using Formula AI scripts, the formula AI is independent of the WML files and can be included in WML very easily.&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
Formula AI files end with a .fai extension.  They may contain any number of custom functions created by the def keyword and end with a single executable Formula.  Each function definition is separated by a semi-colon.  As an example, a formula will be converted to a formula script.  Here is the formula as it would appear in WML:&lt;br /&gt;
&lt;br /&gt;
   formula=&amp;quot;move(me.loc, nearest_loc(me.loc, map(filter(map.terrain,id=me.vars.terrain_type),loc)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The same formula will now be converted to a formula AI script file.  Comments are added and a function is defined to return a list of locations for each hex of a terrain type:&lt;br /&gt;
&lt;br /&gt;
   {Return a list of locations with terrain of type terrain_type}&lt;br /&gt;
   def get_terrain_locs(terrain_type)&lt;br /&gt;
        map(filter(map.terrain,id=terrain_type),loc);&lt;br /&gt;
   {Move unit to closest terrain of type terrain_type}&lt;br /&gt;
   move(me.loc, nearest_loc(me.loc, get_terrain_locs(me.vars.terrain_type)&lt;br /&gt;
&lt;br /&gt;
If this example is saved to the file 'move_to_terrain.fai', to include in WML:&lt;br /&gt;
&lt;br /&gt;
    [unit]&lt;br /&gt;
        x,y=16,7&lt;br /&gt;
        type=&amp;quot;Walking Corpse&amp;quot;&lt;br /&gt;
        generate_description=yes&lt;br /&gt;
        formula=&amp;quot;{move_to_terrain.fai}&amp;quot;&lt;br /&gt;
        [ai_vars]&lt;br /&gt;
             terrain_type='forest'&lt;br /&gt;
        [/ai_vars]&lt;br /&gt;
    [/unit]&lt;br /&gt;
&lt;br /&gt;
While this example is fairly trivial, it does illustrate how formula scripts can be used to remove formula from WML.  This not only makes the WML easier to read for those unfamiliar with Formula AI, but also allows reusability of predefined behaviors and supports the construction of a repository of Formula AI behaviors which can easily be plugged into WML.&lt;br /&gt;
&lt;br /&gt;
It also creates a more convenient method of building complex behaviors for the Formula AI developer, especially in conjunction with the Formula AI support for developer [[#ctags|tools]].&lt;br /&gt;
&lt;br /&gt;
= Tool Support =&lt;br /&gt;
&lt;br /&gt;
== ctags ==&lt;br /&gt;
&lt;br /&gt;
For some rudimentary Formula AI script 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 scripts.&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24995</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24995"/>
		<updated>2008-03-31T18:21:39Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added section describing Formula AI scripts&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;nearest location&amp;gt; = nearest_loc(&amp;lt;location&amp;gt;, &amp;lt;list of locations&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns the closest location in &amp;lt;list of locations&amp;gt; which is closest in distance to &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 &lt;br /&gt;
 nearest_loc(me.loc, map(filter(terrain.map,id = &amp;quot;hills&amp;quot;),loc))&lt;br /&gt;
&lt;br /&gt;
will return the location of the hex with a hills terrain which is closest to current unit.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= Formula AI Scripts =&lt;br /&gt;
&lt;br /&gt;
Formula AI scripts are a way to separate Formula AI from WML files.  As the complexity of the AI rules grow, so will the formula.  Embedding formula in WML can create bloated cfg files and make it cumbersome to reuse AI scripts.  By using Formula AI scripts, the formula AI is independent of the WML files and can be included in WML very easily.&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
Formula AI files end with .fai extension.  They may contain any number of custom functions created by the def keyword and end with a single executable Formula.  Each function definition is separated by a semi-colon.  As an example, a formula will be converted to a formula script.  Here is the formula as it would appear in WML:&lt;br /&gt;
&lt;br /&gt;
   formula=&amp;quot;move(me.loc, nearest_loc(me.loc, map(filter(map.terrain,id=me.vars.terrain_type),loc)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The same formula will now be converted to a formula AI script file.  Comments are added and a function is defined to return the location list of a terrain type:&lt;br /&gt;
&lt;br /&gt;
   {Return a list of locations with terrain of type terrain_type}&lt;br /&gt;
   def get_terrain_locs(terrain_type)&lt;br /&gt;
        map(filter(map.terrain,id=terrain_type),loc);&lt;br /&gt;
   {Move unit to closest terrain of type terrain_type}&lt;br /&gt;
   move(me.loc, nearest_loc(me.loc, get_terrain_locs(me.vars.terrain_type)&lt;br /&gt;
&lt;br /&gt;
If this example is saved to the file 'move_to_terrain.fai', to include in WML:&lt;br /&gt;
&lt;br /&gt;
    [unit]&lt;br /&gt;
        x,y=16,7&lt;br /&gt;
        type=&amp;quot;Walking Corpse&amp;quot;&lt;br /&gt;
        generate_description=yes&lt;br /&gt;
        formula=&amp;quot;{move_to_terrain.fai}&amp;quot;&lt;br /&gt;
        [ai_vars]&lt;br /&gt;
             terrain_type='forest'&lt;br /&gt;
        [/ai_vars]&lt;br /&gt;
    [/unit]&lt;br /&gt;
&lt;br /&gt;
While this example is fairly trivial, it does illustrate how formula scripts can be used to remove formula from WML.  This not only makes the WML easier to read for those unfamiliar with Formula AI, but also allows reusability of predefined behaviors and supports the construction of a repository of Formula AI behaviors which can easily be plugged into WML.&lt;br /&gt;
&lt;br /&gt;
It also creates a more convenient method of building complex behaviors for the Formula AI developer, especially in conjunction with the Formula AI support for developer [[#ctags|tools]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Tool Support =&lt;br /&gt;
&lt;br /&gt;
== ctags ==&lt;br /&gt;
&lt;br /&gt;
For some rudimentary Formula AI script 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 scripts.&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24970</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24970"/>
		<updated>2008-03-31T17:40:35Z</updated>

		<summary type="html">&lt;p&gt;Dhains: clarified example for nearest_loc function&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;nearest location&amp;gt; = nearest_loc(&amp;lt;location&amp;gt;, &amp;lt;list of locations&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns the closest location in &amp;lt;list of locations&amp;gt; which is closest in distance to &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 &lt;br /&gt;
 nearest_loc(me.loc, map(filter(terrain.map,id = &amp;quot;hills&amp;quot;),loc))&lt;br /&gt;
&lt;br /&gt;
will return the location of the hex with a hills terrain which is closest to current unit.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24969</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24969"/>
		<updated>2008-03-31T17:38:40Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added help for nearest_loc function&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;nearest location&amp;gt; = nearest_loc(&amp;lt;location&amp;gt;, &amp;lt;list of locations&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns the closest location in &amp;lt;list of locations&amp;gt; which is closest in distance to &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 &lt;br /&gt;
 nearest_loc(me.loc, map(filter(terrain.map,id = &amp;quot;hills&amp;quot;),loc))&lt;br /&gt;
&lt;br /&gt;
will return the location of the nearest hex with a hills terrain.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24717</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24717"/>
		<updated>2008-03-27T02:20:39Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added Tools support section and entries for ctags and vim&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&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>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24643</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24643"/>
		<updated>2008-03-26T05:42:13Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added documentation on comments&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;
== Approach ==&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;
== Formula 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;
== 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).&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;
== 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;
&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. 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.&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 [[#Custom Functions|define your own 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;
==== '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;
==== '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;
==== 'choose' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&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 list&amp;gt;. 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;
==== '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;
==== '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;
==== 'evaluate_for_position' function ====&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 which will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'default' )&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI.&lt;br /&gt;
&lt;br /&gt;
==== 'filter' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;reult list&amp;gt; = filter( &amp;lt;input list&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 list&amp;gt;. Will evaluate to a &amp;lt;result list&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. 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;reult&amp;gt; = find( &amp;lt;input list&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 list&amp;gt; and will return a first item for which &amp;lt;formula&amp;gt; was true. 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;
==== '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;
==== '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;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 it will evaluate to being equal to its third input ( &amp;lt;otherwise&amp;gt; ). &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;
==== '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;
==== 'map' function ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = map( &amp;lt;input list&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 list&amp;gt;, and evaluate to a new &amp;lt;result list&amp;gt; which contains the same number of items as in &amp;lt;input list&amp;gt;, with the formulas run on each item. For example:&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;
==== '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;
==== '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;
==== '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;
==== '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;
For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(me.loc, loc(me.loc.x, me.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make unit move one hex north.&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;
==== '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;
==== '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;
==== '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;
==== '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;
=== 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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24640</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24640"/>
		<updated>2008-03-26T02:21:07Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Formula AI - Rulebases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Rulebases - Formula AI==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24639</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24639"/>
		<updated>2008-03-26T02:19:25Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Some major changes to coincide with official GSoC Application&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science and entered a PhD graduate program focusing on AI research.  I use C++ primarily for research and have been a teaching assistant for our undergraduate C++ course.  I have approximately 4/5 years of C++ experience and some Python experience.&lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Formula AI - Rulebases==&lt;br /&gt;
&lt;br /&gt;
Rulebases contain the FormulaAI rules the AI can use to form scripts. The rulebases developed for this project will form a repository of strategies and behaviors that designers can simply plug into a WML file to create a highly effective AI without ever touching FormulaAI or the underlying learning processes. Of course, if a designer desires a new strategy they can write custom FormulaAI rules.&lt;br /&gt;
&lt;br /&gt;
I plan to involve the community in this portion of the project to identify the common strategies used by players and desired by scenario and MP bot designers. The how to play series will also serve as a useful guide. I foresee three categories of rulebases the designer can choose from to customize the AI for a particular scenario or deathmatch.&lt;br /&gt;
&lt;br /&gt;
* RECRUITMENT RULEBASES&lt;br /&gt;
&lt;br /&gt;
These rulebases will cover strategies to recruit units. A default recruitment strategy will be provided that selects the best units for the desired scenario goal.&lt;br /&gt;
&lt;br /&gt;
* TEAM RULEBASES&lt;br /&gt;
&lt;br /&gt;
Team rulebases will govern team strategies and will supply the majority of rules the AI can use when creating a script. Developed rulebases cover the majority of scenario and MP objectives, such as 'Escort unit x to hex y', 'Assassinate enemy leader', etc.&lt;br /&gt;
&lt;br /&gt;
* UNIT RULEBASES&lt;br /&gt;
&lt;br /&gt;
Unit rulebases provide rules for unit specific behavior. Some of these rulebases will be associated to units by default, for instance a 'healing' rule for healing units, 'backstab' to thieves, etc.&lt;br /&gt;
&lt;br /&gt;
A variety of rulebases to customize unit behavior to a scenario storyline will also be available, such as 'Hatred towards faction x' and can be applied to single units or groups.&lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
== Adaptation and Learning - C++ ==&lt;br /&gt;
&lt;br /&gt;
The C++ portion of the project allows the AI to learn and adapt. Once the candidate moves are determined, the AI will rank the moves based on evaluation functions. The actual evaluation functions will be written in Formula AI, the C++ code should never have to be touch for customization or extension purposes.&lt;br /&gt;
&lt;br /&gt;
There will be two evaluation functions: A team evaluation function, in which the impact of each move on the overall team strategy is evaluated and a unit evaluation function, in which the impact of a move on unit involved is evaluated. The results these functions determine the final evaluation of a move. Once all moves are evaluated, the script is formed based on these evaluations (i.e. best moves first).&lt;br /&gt;
&lt;br /&gt;
At the end of turn, the success of each move is used to adjust a weight associated with that move. The weights are incorporated into the evaluation of moves during the next turn (e.g. weight * (unit_eval(formula) + team_eval(formula))). In this way, the AI can learn from it's mistakes and exploit holes in an opponent's strategy found by successful moves.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24638</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24638"/>
		<updated>2008-03-26T02:12:33Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science (where I achieved a perfect 4.0 gpa) and entered a PhD graduate program for computer science focusing on AI research.  My research to this point has been focused on machine learning and evolutionary computing techniques for parameter optimization, but many of the techniques have a wide variety of applications.  I use C++ primarily for my research and have been a teaching assistant for our undergraduate C++ course. &lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Designing an AI for playing games is a challenge.  Techniques such as minimax and alpha-beta pruning are useful in games such as chess or backgammon, but the complexity of Wesnoth's gamestate space precludes many of these approaches.&lt;br /&gt;
&lt;br /&gt;
A common method to overcome this problem is to use scripting.  Manually designed rules are created to determine the course of action, for instance if the AI should attack or defend.  While these methods are effective it is generally not enough to provide challenging play, especially to experienced players.  Players can 'outsmart' a scripted AI simply by exploiting the predictability inherent to scripting.&lt;br /&gt;
&lt;br /&gt;
An ideal AI is one which exhibits human-like behavoir. One which can adapt its strategy to cover holes exploited by players. One which has the ability of surprise, to make the player feel as if he is playing a thinking, cunning opponent instead of just 'trying to beat the computer'. Such an AI is not a pipe dream and even more to the point, is quite feasible from a technical standpoint.&lt;br /&gt;
&lt;br /&gt;
This is a proposal to implement such an AI. I propose to use dynamic scripting to combine manually designed rulebases and online learning to create a customizable, extensible and adaptive AI. his type of dynamic planning has already proven successful in creating adaptive, formidable A.I. in games such as F.E.A.R. and Neverwinter Nights [1,2].&lt;br /&gt;
&lt;br /&gt;
The rulebases will be implemented in FormulaAI while the reinforcement learning portion will be handled by C++. This accomplishes two goals: 1, the AI can easily be customized and extended without touching the C++ code and with no knowledge of the reinforcement learning process and 2, the learning process can easily be 'switched off', perhaps as a difficulty setting or to force strict adherence to a script.&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself (using dynamic scripting) as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be two types of rulebases: team rulebases and unit rulebases.  A team rulebase will contain formulas which more or less correspond to scenario objectives (or deathmatch, MP, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the AI to win the round.  Unit rulebases, cover unit specific behavior such as 'Hatred towards faction X', 'Hide and Ambush' or 'Healing unit'.  These rulebases can be applied to specific units or classes of units to allow them to use unit specific strategies and techniques.  This allows for an easily customizable AI for scenario designers, MP bots for co-op campaign play, death matches, etc.  &lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
&lt;br /&gt;
Along with the rulebases defined above also comes evaluation functions appropriate to each rulebase.  These will be included with the formula scripts for each rulebase and will be transparent to the designer unless he or she wishes to modify them to fine tune the behavior.  These evaluation functions will be used to determine the probability of a particular move.&lt;br /&gt;
&lt;br /&gt;
I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the team goal (this one will come from the team formula) and another on the unit level (from the unit formulas).  Both evaluation functions will be evaluated on the candidate moves and a combination of the results will be used to determine the final probability of a move being chosen (This is the method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
Finally, I would like to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
This can be accomplished by Dynamic Scripting, a proven (and relatively cutting edge) technique.  Actually, everything described thus far is the general dynamic scripting as I would apply it to Wesnoth.  The adaptability comes into play with the following addition.&lt;br /&gt;
&lt;br /&gt;
As described above, each unit will have some probability associated with it assigned by the evaluation functions.  The evaluation functions themselves are defined in the formula scripts and as such cannot be modified directly by the AI (at least for now).  However we can assign a weight (initially set to 1) to each probability and allow the AI to modify this weight as it determines whether moves are successful or not.  In this way, we give the AI ability to adapt it's techniques and an easy way to turn the learning portion off (set the weights to 1, don't allow change) for experimentation and perhaps adjust the difficulty setting.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24347</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24347"/>
		<updated>2008-03-23T07:51:53Z</updated>

		<summary type="html">&lt;p&gt;Dhains: More personal info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==About Me==&lt;br /&gt;
&lt;br /&gt;
I am currently a full-time graduate student living in Colorado, US.  I've been coding since I was about 12, initially writing text based adventures for myself and my friends to play, moving on to RPGs using some primitive sprite based graphics and completed a mini RPG in high school, complete with graphics and music I wrote on my keyboard.&lt;br /&gt;
&lt;br /&gt;
Since then, I have graduated from Pennsylvania State University with a bachelors degree in computer science (where I achieved a perfect 4.0 gpa) and entered a PhD graduate program for computer science focusing on AI research.  My research to this point has been focused on machine learning and evolutionary computing techniques for parameter optimization, but many of the techniques have a wide variety of applications.  I use C++ primarily for my research and have been a teaching assistant for our undergraduate C++ course. &lt;br /&gt;
&lt;br /&gt;
===Contact Information===&lt;br /&gt;
&lt;br /&gt;
* IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
* Forum id: rende&lt;br /&gt;
&lt;br /&gt;
* Gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
* preferred email: dhains__A!T__ gmail.com&lt;br /&gt;
&lt;br /&gt;
I'll be adding more to this page as I have the time.  Please feel free to contact me if you have any questions.&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of a single large database of moves, scenario AIs, MP bots, death match AI's, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself (using dynamic scripting) as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be two types of rulebases: team rulebases and unit rulebases.  A team rulebase will contain formulas which more or less correspond to scenario objectives (or deathmatch, MP, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the AI to win the round.  Unit rulebases, cover unit specific behavior such as 'Hatred towards faction X', 'Hide and Ambush' or 'Healing unit'.  These rulebases can be applied to specific units or classes of units to allow them to use unit specific strategies and techniques.  This allows for an easily customizable AI for scenario designers, MP bots for co-op campaign play, death matches, etc.  &lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
&lt;br /&gt;
Along with the rulebases defined above also comes evaluation functions appropriate to each rulebase.  These will be included with the formula scripts for each rulebase and will be transparent to the designer unless he or she wishes to modify them to fine tune the behavior.  These evaluation functions will be used to determine the probability of a particular move.&lt;br /&gt;
&lt;br /&gt;
I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the team goal (this one will come from the team formula) and another on the unit level (from the unit formulas).  Both evaluation functions will be evaluated on the candidate moves and a combination of the results will be used to determine the final probability of a move being chosen (This is the method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
Finally, I would like to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
This can be accomplished by Dynamic Scripting, a proven (and relatively cutting edge) technique.  Actually, everything described thus far is the general dynamic scripting as I would apply it to Wesnoth.  The adaptability comes into play with the following addition.&lt;br /&gt;
&lt;br /&gt;
As described above, each unit will have some probability associated with it assigned by the evaluation functions.  The evaluation functions themselves are defined in the formula scripts and as such cannot be modified directly by the AI (at least for now).  However we can assign a weight (initially set to 1) to each probability and allow the AI to modify this weight as it determines whether moves are successful or not.  In this way, we give the AI ability to adapt it's techniques and an easy way to turn the learning portion off (set the weights to 1, don't allow change) for experimentation and perhaps adjust the difficulty setting.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24344</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24344"/>
		<updated>2008-03-23T07:35:10Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added a bit more detail&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of a single large database of moves, scenario AIs, MP bots, death match AI's, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself (using dynamic scripting) as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be two types of rulebases: team rulebases and unit rulebases.  A team rulebase will contain formulas which more or less correspond to scenario objectives (or deathmatch, MP, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the AI to win the round.  Unit rulebases, cover unit specific behavior such as 'Hatred towards faction X', 'Hide and Ambush' or 'Healing unit'.  These rulebases can be applied to specific units or classes of units to allow them to use unit specific strategies and techniques.  This allows for an easily customizable AI for scenario designers, MP bots for co-op campaign play, death matches, etc.  &lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
&lt;br /&gt;
Along with the rulebases defined above also comes evaluation functions appropriate to each rulebase.  These will be included with the formula scripts for each rulebase and will be transparent to the designer unless he or she wishes to modify them to fine tune the behavior.  These evaluation functions will be used to determine the probability of a particular move.&lt;br /&gt;
&lt;br /&gt;
I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the team goal (this one will come from the team formula) and another on the unit level (from the unit formulas).  Both evaluation functions will be evaluated on the candidate moves and a combination of the results will be used to determine the final probability of a move being chosen (This is the method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
Finally, I would like to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
This can be accomplished by Dynamic Scripting, a proven (and relatively cutting edge) technique.  Actually, everything described thus far is the general dynamic scripting as I would apply it to Wesnoth.  The adaptability comes into play with the following addition.&lt;br /&gt;
&lt;br /&gt;
As described above, each unit will have some probability associated with it assigned by the evaluation functions.  The evaluation functions themselves are defined in the formula scripts and as such cannot be modified directly by the AI (at least for now).  However we can assign a weight (initially set to 1) to each probability and allow the AI to modify this weight as it determines whether moves are successful or not.  In this way, we give the AI ability to adapt it's techniques and an easy way to turn the learning portion off (set the weights to 1, don't allow change) for experimentation and perhaps adjust the difficulty setting.&lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24343</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24343"/>
		<updated>2008-03-23T07:23:05Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Evaluation Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of a single large database of moves, scenario AIs, MP bots, death match AI's, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself (using dynamic scripting) as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be two types of rulebases: team rulebases and unit rulebases.  A team rulebase will contain formulas which more or less correspond to scenario objectives (or deathmatch, MP, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the AI to win the round.  Unit rulebases, cover unit specific behavior such as 'Hatred towards faction X', 'Hide and Ambush' or 'Healing unit'.  These rulebases can be applied to specific units or classes of units to allow them to use unit specific strategies and techniques.  This allows for an easily customizable AI for scenario designers, MP bots for co-op campaign play, death matches, etc.  &lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
&lt;br /&gt;
Along with the rulebases defined above also comes evaluation functions appropriate to each rulebase.  These will be included with the formula scripts for each rulebase and will be transparent to the designer unless he or she wishes to modify them to fine tune the behavior.  These evaluation functions will be used to determine the probability of a particular move.&lt;br /&gt;
&lt;br /&gt;
I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the team goal (this one will come from the team formula) and another on the unit level (from the unit formulas).  Both evaluation functions will be evaluated on the candidate moves and a combination of the results will be used to determine the final probability of a move being chosen (This is the method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
I was hoping to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
One method that seems quite suitable is dynamic scripting.  Each move in the rulebase has an associated weight which influences the probability of a given rule being used.  As a game progresses, the weights are updated automatically according to the success or failure of past moves of the current game (or campaign) according to both and individuals state (unit eval function) and the overall game state (team eval function).  This would allow the AI to adapt to a player's tactics and encourage the player to develop diverse strategies for use in campaign mode. &lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24342</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24342"/>
		<updated>2008-03-23T07:12:03Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Updated rulebases with a clearer definition&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of a single large database of moves, scenario AIs, MP bots, death match AI's, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself (using dynamic scripting) as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be two types of rulebases: team rulebases and unit rulebases.  A team rulebase will contain formulas which more or less correspond to scenario objectives (or deathmatch, MP, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the AI to win the round.  Unit rulebases, cover unit specific behavior such as 'Hatred towards faction X', 'Hide and Ambush' or 'Healing unit'.  These rulebases can be applied to specific units or classes of units to allow them to use unit specific strategies and techniques.  This allows for an easily customizable AI for scenario designers, MP bots for co-op campaign play, death matches, etc.  &lt;br /&gt;
&lt;br /&gt;
For example, a scenario designer might want to create a scenario in which a group of orcs, goblins and ogres must escort an orcish leader across a map to hex 5,10.  The storyline might dictate that the goblins and ogres are only helping the orcs for a chance to kill elves, which the player has the ability to recruit.  The scenario designer could implement this quite easily in their cfg file for that scenario with something like &lt;br /&gt;
&lt;br /&gt;
   [ai]&lt;br /&gt;
      [team_formula]&lt;br /&gt;
        rulebase = &amp;quot;escort&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Orcish Leader&amp;quot;, 5, 10&lt;br /&gt;
      [\team_formula]&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;goblins&amp;quot;, &amp;quot;ogres&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;faction_hatred&amp;quot;&lt;br /&gt;
        parameters = &amp;quot;Elves&amp;quot;&lt;br /&gt;
      [\unit_faction]&lt;br /&gt;
   [\ai]&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, by creating multiple team strategies associated to different units, e.g. suppose in the above example the AI also had a renegade faction of elvish rangers along for the ride, hellbent on destroying the human leader and don't really care about escorting the orcish leader.  The designer might create an entirely new side, but if he or she wanted all the units on a single side, he might add the following to the above ai section. &lt;br /&gt;
&lt;br /&gt;
      [unit_formula]&lt;br /&gt;
        apply_to_units = &amp;quot;Elvish Ranger&amp;quot;, &amp;quot;Elvish Avenger&amp;quot;&lt;br /&gt;
        rulebase = &amp;quot;hide_and_ambush&amp;quot;  # Make elves stay hidden if possible until they attack&lt;br /&gt;
        [team_formula]  # This will override the &amp;quot;escort&amp;quot; team formula&lt;br /&gt;
          rulebase = &amp;quot;assassinate&amp;quot;&lt;br /&gt;
          parameters = &amp;quot;Human Leader&amp;quot;&lt;br /&gt;
         [\team_formula]&lt;br /&gt;
      [\unit_formula]&lt;br /&gt;
&lt;br /&gt;
The AI designer can go deeper or shallower if necessary.  An adequate default AI with appropriate unit rulebases and a 'kill all' team rulebase will be the default if none are specified.  If the provided rulebases do not cover some specific behavior, the designer of course may implement his own rulebase by creating a custom formula script or by altering the evaluation functions of the existing rulebases.&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
So once the global, recruitment and unit rulebases have been defined, the Formula AI in these rulebases forms a pool of candidate moves for the AI to follow.  These moves will have a probability defined to them by the evaluation functions and these probabilities will be used in determining what action to take.&lt;br /&gt;
&lt;br /&gt;
Following the concept of team and unit behaviors, I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the tam goal and another on the unit level.  A combination of the result of both of these eval functions will used to determine the final probability of a move being chosen (This is also the same method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
I was hoping to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
One method that seems quite suitable is dynamic scripting.  Each move in the rulebase has an associated weight which influences the probability of a given rule being used.  As a game progresses, the weights are updated automatically according to the success or failure of past moves of the current game (or campaign) according to both and individuals state (unit eval function) and the overall game state (team eval function).  This would allow the AI to adapt to a player's tactics and encourage the player to develop diverse strategies for use in campaign mode. &lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24341</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24341"/>
		<updated>2008-03-23T06:30:54Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of a single large database of moves, scenario AIs, MP bots, death match AI's, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).&lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be team rulebases, which more or less correspond to scenario objectives (or deathmatch, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the entire force to win the round.  There will also be unit rulebases, which can be associated with particular units, such as a 'Hatred towards faction X' behavior.  The rulebases will be as general and parameterized, to allow for as much reuse as possible. &lt;br /&gt;
&lt;br /&gt;
This allow for an easily customizable AI for scenario designers, MP bots (perhaps for co-op campaign play), death matches, etc.  For example, a scenario designer could simply select a team and recruitment rulebase appropriate to his scenario (probably specified in WML) and associate his Orcs with a hatred vs elves unit rulebase.  This would give the designer's wolf riders a behavior biased towards aggressively attacking elves, but the overall team strategy will still be accomplished.&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, perhaps by creating multiple team strategies associated to different units, i.e. Most units could be assigned candidate moves from a 'defend leader' team rulebase while camouflaged units could follow an 'assassinate leader' team rulebase, and since they are camouflaged units they might also be associated with a 'hide &amp;amp; attack' unit rulebase.  The scenario designer could accomplish this in a few lines of WML and have some really cool results, i.e. the AI puts up a solid strong, ZoC defense but is also circling around a camo squad to ambush to opposing the leader.  And of course, the whole time the AI is learning and adapting on it's own to the opposing strategies.&lt;br /&gt;
&lt;br /&gt;
I think coming up with the specific rulebases and such will really start rolling after a fair amount of interaction with the community, specifically players and scenario designers.&lt;br /&gt;
&lt;br /&gt;
===Rulebase Categories===&lt;br /&gt;
====Recruitment Rulebases====&lt;br /&gt;
Rulebases to govern the recruitment process, this may just be one parameterized rulebase to begin with, but most likely several rulebases for different recruiting strategies.&lt;br /&gt;
&lt;br /&gt;
====Team Rulebases====&lt;br /&gt;
These will be more general rules for which all units would abide (We could create an easy way for certain units to ignore any team rulebase, or to follow another to setup a renegade faction within a computer controlled side, for instance a band of outlaws (thugs, poachers) which are helping the computer controlled side fight but simply for the sake of killing elves and have no care for the overall objective of the AI.)  Mostly, the provided rulebases in this category will cover the most common scenarios and deathmatch games, i.e. kill opponents leader, defend for x turns, escort x to hex y, kill at all cost, etc.&lt;br /&gt;
&lt;br /&gt;
====Unit Rulebases====&lt;br /&gt;
These are rulebases which can be associated to units.  Scenario designers can apply some unit rulebases to all units in scenario and then customize specific units on a case by case basis if needed, to say setup faction behaviors between certain units.  This could not be just aggressive but also perhaps a healing unit prefers to heal units of it's own faction.  Healing units could be associated with a general unit rulebase which tells them to heal wounded units and could be even further customized with a heal elves over dwarves behavior.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
So once the global, recruitment and unit rulebases have been defined, the Formula AI in these rulebases forms a pool of candidate moves for the AI to follow.  These moves will have a probability defined to them by the evaluation functions and these probabilities will be used in determining what action to take.&lt;br /&gt;
&lt;br /&gt;
Following the concept of team and unit behaviors, I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the tam goal and another on the unit level.  A combination of the result of both of these eval functions will used to determine the final probability of a move being chosen (This is also the same method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
I was hoping to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
One method that seems quite suitable is dynamic scripting.  Each move in the rulebase has an associated weight which influences the probability of a given rule being used.  As a game progresses, the weights are updated automatically according to the success or failure of past moves of the current game (or campaign) according to both and individuals state (unit eval function) and the overall game state (team eval function).  This would allow the AI to adapt to a player's tactics and encourage the player to develop diverse strategies for use in campaign mode. &lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24340</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24340"/>
		<updated>2008-03-23T06:28:49Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
gna! username: dhains&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of large database of moves, MP bots, death match AI's, scenario AIs, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).  &lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be team rulebases, which more or less correspond to scenario objectives (or deathmatch, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the entire force to win the round.  There will also be unit rulebases, which can be associated with particular units, such as a 'Hatred towards faction X' behavior.  The rulebases will be as general and parameterized, to allow for as much reuse as possible. &lt;br /&gt;
&lt;br /&gt;
This allow for an easily customizable AI for scenario designers, MP bots (perhaps for co-op campaign play), death matches, etc.  For example, a scenario designer could simply select a team and recruitment rulebase appropriate to his scenario (probably specified in WML) and associate his Orcs with a hatred vs elves unit rulebase.  This would give the designer's wolf riders a behavior biased towards aggressively attacking elves, but the overall team strategy will still be accomplished.&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, perhaps by creating multiple team strategies associated to different units, i.e. Most units could be assigned candidate moves from a 'defend leader' team rulebase while camouflaged units could follow an 'assassinate leader' team rulebase, and since they are camouflaged units they might also be associated with a 'hide &amp;amp; attack' unit rulebase.  The scenario designer could accomplish this in a few lines of WML and have some really cool results, i.e. the AI puts up a solid strong, ZoC defense but is also circling around a camo squad to ambush to opposing the leader.  And of course, the whole time the AI is learning and adapting on it's own to the opposing strategies.&lt;br /&gt;
&lt;br /&gt;
I think coming up with the specific rulebases and such will really start rolling after a fair amount of interaction with the community, specifically players and scenario designers.&lt;br /&gt;
&lt;br /&gt;
===Rulebase Categories===&lt;br /&gt;
====Recruitment Rulebases====&lt;br /&gt;
Rulebases to govern the recruitment process, this may just be one parameterized rulebase to begin with, but most likely several rulebases for different recruiting strategies.&lt;br /&gt;
&lt;br /&gt;
====Team Rulebases====&lt;br /&gt;
These will be more general rules for which all units would abide (We could create an easy way for certain units to ignore any team rulebase, or to follow another to setup a renegade faction within a computer controlled side, for instance a band of outlaws (thugs, poachers) which are helping the computer controlled side fight but simply for the sake of killing elves and have no care for the overall objective of the AI.)  Mostly, the provided rulebases in this category will cover the most common scenarios and deathmatch games, i.e. kill opponents leader, defend for x turns, escort x to hex y, kill at all cost, etc.&lt;br /&gt;
&lt;br /&gt;
====Unit Rulebases====&lt;br /&gt;
These are rulebases which can be associated to units.  Scenario designers can apply some unit rulebases to all units in scenario and then customize specific units on a case by case basis if needed, to say setup faction behaviors between certain units.  This could not be just aggressive but also perhaps a healing unit prefers to heal units of it's own faction.  Healing units could be associated with a general unit rulebase which tells them to heal wounded units and could be even further customized with a heal elves over dwarves behavior.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
So once the global, recruitment and unit rulebases have been defined, the Formula AI in these rulebases forms a pool of candidate moves for the AI to follow.  These moves will have a probability defined to them by the evaluation functions and these probabilities will be used in determining what action to take.&lt;br /&gt;
&lt;br /&gt;
Following the concept of team and unit behaviors, I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the tam goal and another on the unit level.  A combination of the result of both of these eval functions will used to determine the final probability of a move being chosen (This is also the same method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
I was hoping to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
One method that seems quite suitable is dynamic scripting.  Each move in the rulebase has an associated weight which influences the probability of a given rule being used.  As a game progresses, the weights are updated automatically according to the success or failure of past moves of the current game (or campaign) according to both and individuals state (unit eval function) and the overall game state (team eval function).  This would allow the AI to adapt to a player's tactics and encourage the player to develop diverse strategies for use in campaign mode. &lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24339</id>
		<title>FormulaAIandDynamicScripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAIandDynamicScripting&amp;diff=24339"/>
		<updated>2008-03-23T06:28:19Z</updated>

		<summary type="html">&lt;p&gt;Dhains: /* Me */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Me==&lt;br /&gt;
&lt;br /&gt;
IRC: barbarianhero&lt;br /&gt;
Forum id: Rende&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&lt;br /&gt;
Many types of AI techniques to provide intelligent strategies in games revolve around the concept of search and evaluation.  The problem with search is it can simply take too long.  Anyone who has played a chess AI knows of the delays between moves due to this search and eval procedure.  These delays would interrupt the flow of game play in Wesnoth, so the approach used in Dynamic Scripting can be applied to heavily cut down on the search portion by coding domain knowledge of the game into sets of moves known as rulebases.  Evaluation and selection of exactly what moves to make is still up to the AI, but we can cut the computational costs significantly by providing a pool of candidate moves. &lt;br /&gt;
&lt;br /&gt;
By using modular rulebases instead of large database of moves, MP bots, death match AI's, scenario AIs, etc. can be designed easily by plugging together appropriate rulebases as described below.  The designer can achieve a high level of customization and still have an intelligent, adaptive AI as a result.  The dynamic scripting technique has been applied successfully in creating an aftermarket AI to control characters in Neverwinter Nights.  A party consisting of a variety of character classes was able to adapt and cooperate to defeat an opposing force.  It is not much of a stretch to see how this technique could be applied to Wesnoth.  There are quite a few more characters to be controlled, but the choice of actions is less (e.g. they don't have a plethora of items and spells at their disposal on top of moving and attacking).  &lt;br /&gt;
&lt;br /&gt;
==Formula AI==&lt;br /&gt;
&lt;br /&gt;
Formula AI will be used for designing the AI rulebases described below.  A rulebase can be thought of as a set of candidate moves written in Formula AI which accomplish some particular behavior or strategy.  Much of the work will be defining what behaviors/strategies are required and implementing the appropriate moves in Formula AI.  I believe there will be some back and forth between implementing rulebases in FormulaAI and extending Formula AI when additional functionality needs to be added.  These two things will probably be a majority of the project.&lt;br /&gt;
&lt;br /&gt;
==Rulebases==&lt;br /&gt;
&lt;br /&gt;
Think of a rulebase as a collection of moves which coordinate some type of behavior (i.e. assassinate opposing leader, defend castle with ZoC, etc.).  The moves in each rulebase are not necessarily the moves which are taken at any given point in a game but rather they create a pool of candidate moves the AI can choose from.  Exactly what move is chosen from this pool of candidate moves depends on an evaluation function which assigns probabilities to each move.  These probabilities can be altered by the AI itself as it plays through a game, thus providing the AI the ability to adapt to an opponents strategy. &lt;br /&gt;
&lt;br /&gt;
There will be team rulebases, which more or less correspond to scenario objectives (or deathmatch, etc.) such as 'Escort unit X to Hex Y'.  These moves will be used to govern the overall behavior of the entire force to win the round.  There will also be unit rulebases, which can be associated with particular units, such as a 'Hatred towards faction X' behavior.  The rulebases will be as general and parameterized, to allow for as much reuse as possible. &lt;br /&gt;
&lt;br /&gt;
This allow for an easily customizable AI for scenario designers, MP bots (perhaps for co-op campaign play), death matches, etc.  For example, a scenario designer could simply select a team and recruitment rulebase appropriate to his scenario (probably specified in WML) and associate his Orcs with a hatred vs elves unit rulebase.  This would give the designer's wolf riders a behavior biased towards aggressively attacking elves, but the overall team strategy will still be accomplished.&lt;br /&gt;
&lt;br /&gt;
Of course the designer could make things a bit more complicated, perhaps by creating multiple team strategies associated to different units, i.e. Most units could be assigned candidate moves from a 'defend leader' team rulebase while camouflaged units could follow an 'assassinate leader' team rulebase, and since they are camouflaged units they might also be associated with a 'hide &amp;amp; attack' unit rulebase.  The scenario designer could accomplish this in a few lines of WML and have some really cool results, i.e. the AI puts up a solid strong, ZoC defense but is also circling around a camo squad to ambush to opposing the leader.  And of course, the whole time the AI is learning and adapting on it's own to the opposing strategies.&lt;br /&gt;
&lt;br /&gt;
I think coming up with the specific rulebases and such will really start rolling after a fair amount of interaction with the community, specifically players and scenario designers.&lt;br /&gt;
&lt;br /&gt;
===Rulebase Categories===&lt;br /&gt;
====Recruitment Rulebases====&lt;br /&gt;
Rulebases to govern the recruitment process, this may just be one parameterized rulebase to begin with, but most likely several rulebases for different recruiting strategies.&lt;br /&gt;
&lt;br /&gt;
====Team Rulebases====&lt;br /&gt;
These will be more general rules for which all units would abide (We could create an easy way for certain units to ignore any team rulebase, or to follow another to setup a renegade faction within a computer controlled side, for instance a band of outlaws (thugs, poachers) which are helping the computer controlled side fight but simply for the sake of killing elves and have no care for the overall objective of the AI.)  Mostly, the provided rulebases in this category will cover the most common scenarios and deathmatch games, i.e. kill opponents leader, defend for x turns, escort x to hex y, kill at all cost, etc.&lt;br /&gt;
&lt;br /&gt;
====Unit Rulebases====&lt;br /&gt;
These are rulebases which can be associated to units.  Scenario designers can apply some unit rulebases to all units in scenario and then customize specific units on a case by case basis if needed, to say setup faction behaviors between certain units.  This could not be just aggressive but also perhaps a healing unit prefers to heal units of it's own faction.  Healing units could be associated with a general unit rulebase which tells them to heal wounded units and could be even further customized with a heal elves over dwarves behavior.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Evaluation Functions==&lt;br /&gt;
So once the global, recruitment and unit rulebases have been defined, the Formula AI in these rulebases forms a pool of candidate moves for the AI to follow.  These moves will have a probability defined to them by the evaluation functions and these probabilities will be used in determining what action to take.&lt;br /&gt;
&lt;br /&gt;
Following the concept of team and unit behaviors, I expect to have two evaluation functions, one for evaluating a move based on the overall impact on the tam goal and another on the unit level.  A combination of the result of both of these eval functions will used to determine the final probability of a move being chosen (This is also the same method used in Dynamic Scripting).&lt;br /&gt;
&lt;br /&gt;
==Dynamic Scripting==&lt;br /&gt;
&lt;br /&gt;
I was hoping to apply some machine learning concepts to the AI, specifically online learning.  Online learning allows the AI to adapt it's strategy to fix holes being exploited by the human player and over all to perform more intelligently, giving the player a feeling he or she is playing against a thinking, clever opponent.&lt;br /&gt;
&lt;br /&gt;
One method that seems quite suitable is dynamic scripting.  Each move in the rulebase has an associated weight which influences the probability of a given rule being used.  As a game progresses, the weights are updated automatically according to the success or failure of past moves of the current game (or campaign) according to both and individuals state (unit eval function) and the overall game state (team eval function).  This would allow the AI to adapt to a player's tactics and encourage the player to develop diverse strategies for use in campaign mode. &lt;br /&gt;
&lt;br /&gt;
==Related Papers==&lt;br /&gt;
&lt;br /&gt;
Online Adaptation of Game Opponent AI in Simulation and in Practice, Spronk et al. [http://www.fdaw.unimaas.nl/education/3.1cs/postma/GAMEON2003-Paper8-Spronck.pdf]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24260</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24260"/>
		<updated>2008-03-22T01:34:49Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added a list for keywords&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;
== Approach ==&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;
== Formula Access ==&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 type 'f'. A command textbox will appear, where you can type a formula, and the results will be printed. For instance, try pressing 'f' and then type &amp;quot;8 + 4&amp;quot; and the result, &amp;quot;12&amp;quot; will appear. You can now use Wesnoth like a calculator. :-)&lt;br /&gt;
&lt;br /&gt;
== Formula Basics ==&lt;br /&gt;
&lt;br /&gt;
The Formula language supports basic arithmetic operations, such as +, -, *, /, etc. 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 supports integers but does NOT support decimal or floating point numbers.&lt;br /&gt;
&lt;br /&gt;
It also supports common operators such as and, or, and not. These are examples of valid formulas&lt;br /&gt;
&lt;br /&gt;
4 + 8*7 (evaluates to 60)&lt;br /&gt;
(4 + 8)*7 (evaluates to 84)&lt;br /&gt;
5 and 0 (evaluates to 0)&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
Of course, 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 textbox using 'f' and then type in 'turn'. 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;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&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. A simple example of a function is the 'if' function. The 'if' function takes three parameters; if the first parameter is true, the function will evaluate to being equal to its second input, otherwise it will evaluate to being equal to its third input.&lt;br /&gt;
&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;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also define your own functions (see below).&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;
* 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 def function_name(arg1, arg2, ....) function_body.  For example,   &lt;br /&gt;
     def sum(x,y) x + y&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
The formula language has support for lists. A list is a sequence of values. For instance, 'my_units' is a list of unit objects. A list is represented as square brackets, [], surrounding a comma-seperated list. For instance, [4, 8, 7] is a list of three numbers.&lt;br /&gt;
&lt;br /&gt;
There are various functions which operate on lists:&lt;br /&gt;
&lt;br /&gt;
size(list): number of items in the list EXAMPLE: size(my_units) -- number of units the AI controls&lt;br /&gt;
&lt;br /&gt;
head(list): the first item in the list EXAMPLE: head(my_units) -- the first unit in the list of units.&lt;br /&gt;
&lt;br /&gt;
map(list, formula): will run 'formula' on each item in the list, and evaluate to a new list which contains the same number of items as in 'list', with the formulas run on each item. EXAMPLE: map(my_units, unit.hitpoints) -- 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;
filter(list, formula): will run 'formula' on each item in the list. Will evaluate to a list which only contains items the formula was true for. EXAMPLE: filter(my_units, hitpoints &amp;lt; 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.&lt;br /&gt;
&lt;br /&gt;
sum(list): evaluates to the sum of the items in the list (which all must be numbers) EXAMPLE: sum(map(my_units, max_hitpoints - hitpoints)) -- finds the total damage your units have taken.&lt;br /&gt;
&lt;br /&gt;
max(list) and min(list): evaluates to the maximum or minimum item in the list (which all must be numbers) EXAMPLE: max(my_units, level) -- finds the maximum level of the units you have.&lt;br /&gt;
&lt;br /&gt;
choose(list, formula): evaluates 'formula' for each item in the list. Will evaluate to the item which 'formula' gave the highest value. EXAMPLE: to give back the unit with the highest level, choose(my_units, level).&lt;br /&gt;
&lt;br /&gt;
sort(list, formula): evaluates to a 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 &amp;gt; b.hitpoints).&lt;br /&gt;
&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=unit&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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24258</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24258"/>
		<updated>2008-03-22T01:33:41Z</updated>

		<summary type="html">&lt;p&gt;Dhains: Added def keyword&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;
== Approach ==&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;
== Formula Access ==&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 type 'f'. A command textbox will appear, where you can type a formula, and the results will be printed. For instance, try pressing 'f' and then type &amp;quot;8 + 4&amp;quot; and the result, &amp;quot;12&amp;quot; will appear. You can now use Wesnoth like a calculator. :-)&lt;br /&gt;
&lt;br /&gt;
== Formula Basics ==&lt;br /&gt;
&lt;br /&gt;
The Formula language supports basic arithmetic operations, such as +, -, *, /, etc. 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 supports integers but does NOT support decimal or floating point numbers.&lt;br /&gt;
&lt;br /&gt;
It also supports common operators such as and, or, and not. These are examples of valid formulas&lt;br /&gt;
&lt;br /&gt;
4 + 8*7 (evaluates to 60)&lt;br /&gt;
(4 + 8)*7 (evaluates to 84)&lt;br /&gt;
5 and 0 (evaluates to 0)&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
Of course, 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 textbox using 'f' and then type in 'turn'. 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;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&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. A simple example of a function is the 'if' function. The 'if' function takes three parameters; if the first parameter is true, the function will evaluate to being equal to its second input, otherwise it will evaluate to being equal to its third input.&lt;br /&gt;
&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;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also define your own functions (see below).&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;
functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
def: This keyword creates functions using the syntax def function_name(arg1, arg2, ....) function_body.  For example,   &lt;br /&gt;
     def sum(x,y) x + y&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
The formula language has support for lists. A list is a sequence of values. For instance, 'my_units' is a list of unit objects. A list is represented as square brackets, [], surrounding a comma-seperated list. For instance, [4, 8, 7] is a list of three numbers.&lt;br /&gt;
&lt;br /&gt;
There are various functions which operate on lists:&lt;br /&gt;
&lt;br /&gt;
size(list): number of items in the list EXAMPLE: size(my_units) -- number of units the AI controls&lt;br /&gt;
&lt;br /&gt;
head(list): the first item in the list EXAMPLE: head(my_units) -- the first unit in the list of units.&lt;br /&gt;
&lt;br /&gt;
map(list, formula): will run 'formula' on each item in the list, and evaluate to a new list which contains the same number of items as in 'list', with the formulas run on each item. EXAMPLE: map(my_units, unit.hitpoints) -- 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;
filter(list, formula): will run 'formula' on each item in the list. Will evaluate to a list which only contains items the formula was true for. EXAMPLE: filter(my_units, hitpoints &amp;lt; 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.&lt;br /&gt;
&lt;br /&gt;
sum(list): evaluates to the sum of the items in the list (which all must be numbers) EXAMPLE: sum(map(my_units, max_hitpoints - hitpoints)) -- finds the total damage your units have taken.&lt;br /&gt;
&lt;br /&gt;
max(list) and min(list): evaluates to the maximum or minimum item in the list (which all must be numbers) EXAMPLE: max(my_units, level) -- finds the maximum level of the units you have.&lt;br /&gt;
&lt;br /&gt;
choose(list, formula): evaluates 'formula' for each item in the list. Will evaluate to the item which 'formula' gave the highest value. EXAMPLE: to give back the unit with the highest level, choose(my_units, level).&lt;br /&gt;
&lt;br /&gt;
sort(list, formula): evaluates to a 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 &amp;gt; b.hitpoints).&lt;br /&gt;
&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=unit&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;
== Unit Formulas ==&lt;br /&gt;
&lt;br /&gt;
You san 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;
   formula=&amp;quot;move(me.loc, loc(me.loc.x, me.loc.y - 1))&amp;quot;&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;
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;
  formula=&amp;quot;if(attack, attack, move(me.loc, choose(unit_moves(me.loc), -distance_between(self, 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), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
  [/ai_vars]&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 opponent which is 3 hexes (value specified by guard_radius variable) 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;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24038</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=24038"/>
		<updated>2008-03-20T23:37:48Z</updated>

		<summary type="html">&lt;p&gt;Dhains: added Keywords section&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;
== Approach ==&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;
== Formula Access ==&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 type 'f'. A command textbox will appear, where you can type a formula, and the results will be printed. For instance, try pressing 'f' and then type &amp;quot;8 + 4&amp;quot; and the result, &amp;quot;12&amp;quot; will appear. You can now use Wesnoth like a calculator. :-)&lt;br /&gt;
&lt;br /&gt;
== Formula Basics ==&lt;br /&gt;
&lt;br /&gt;
The Formula language supports basic arithmetic operations, such as +, -, *, /, etc. 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 supports integers but does NOT support decimal or floating point numbers.&lt;br /&gt;
&lt;br /&gt;
It also supports common operators such as and, or, and not. These are examples of valid formulas&lt;br /&gt;
&lt;br /&gt;
4 + 8*7 (evaluates to 60)&lt;br /&gt;
(4 + 8)*7 (evaluates to 84)&lt;br /&gt;
5 and 0 (evaluates to 0)&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
Of course, 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 textbox using 'f' and then type in 'turn'. 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;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&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. A simple example of a function is the 'if' function. The 'if' function takes three parameters; if the first parameter is true, the function will evaluate to being equal to its second input, otherwise it will evaluate to being equal to its third input.&lt;br /&gt;
&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;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also define your own functions (see below).&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;
functions : Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
The formula language has support for lists. A list is a sequence of values. For instance, 'my_units' is a list of unit objects. A list is represented as square brackets, [], surrounding a comma-seperated list. For instance, [4, 8, 7] is a list of three numbers.&lt;br /&gt;
&lt;br /&gt;
There are various functions which operate on lists:&lt;br /&gt;
&lt;br /&gt;
size(list): number of items in the list EXAMPLE: size(my_units) -- number of units the AI controls&lt;br /&gt;
&lt;br /&gt;
head(list): the first item in the list EXAMPLE: head(my_units) -- the first unit in the list of units.&lt;br /&gt;
&lt;br /&gt;
map(list, formula): will run 'formula' on each item in the list, and evaluate to a new list which contains the same number of items as in 'list', with the formulas run on each item. EXAMPLE: map(my_units, unit.hitpoints) -- 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;
filter(list, formula): will run 'formula' on each item in the list. Will evaluate to a list which only contains items the formula was true for. EXAMPLE: filter(my_units, hitpoints &amp;lt; 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.&lt;br /&gt;
&lt;br /&gt;
sum(list): evaluates to the sum of the items in the list (which all must be numbers) EXAMPLE: sum(map(my_units, max_hitpoints - hitpoints)) -- finds the total damage your units have taken.&lt;br /&gt;
&lt;br /&gt;
max(list) and min(list): evaluates to the maximum or minimum item in the list (which all must be numbers) EXAMPLE: max(my_units, level) -- finds the maximum level of the units you have.&lt;br /&gt;
&lt;br /&gt;
choose(list, formula): evaluates 'formula' for each item in the list. Will evaluate to the item which 'formula' gave the highest value. EXAMPLE: to give back the unit with the highest level, choose(my_units, level).&lt;br /&gt;
&lt;br /&gt;
sort(list, formula): evaluates to a 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 &amp;gt; b.hitpoints).&lt;br /&gt;
&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=unit&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;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dhains</name></author>
		
	</entry>
</feed>