<?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=Dragonking</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=Dragonking"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/Special:Contributions/Dragonking"/>
	<updated>2026-05-21T23:11:55Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Fosdem2010&amp;diff=33269</id>
		<title>Fosdem2010</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Fosdem2010&amp;diff=33269"/>
		<updated>2009-12-05T18:37:12Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Schedule/Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General information ==&lt;br /&gt;
This page is meant to somehow coordinate the small Wesconf taking place at FOSDEM 2010. That is everyone attending should please list him/herself in the list of arrivals and stuff like this. FOSDEM 2010 will take place at the first weekend in Febuary 2010, on Saturday 6th and Sunday 7th.&lt;br /&gt;
&lt;br /&gt;
* Fosdem - http://fosdem.org/2010/&lt;br /&gt;
* [http://www.wesnoth.org/forum/viewtopic.php?p=283311#283311 List with phone numbers] (forum moderators only)&lt;br /&gt;
&lt;br /&gt;
== Schedule/Plans ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! (nick)name(s)&lt;br /&gt;
! Arrival&lt;br /&gt;
! Departure&lt;br /&gt;
! Accomodation&lt;br /&gt;
|-&lt;br /&gt;
| Ivanovic&lt;br /&gt;
| Fri, 5th&lt;br /&gt;
| Sun, 7th&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| Crab&lt;br /&gt;
| Fri, 5th&lt;br /&gt;
| 7th or 8th&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| grzywacz &amp;amp; deekay&lt;br /&gt;
| Fri, 5th (?)&lt;br /&gt;
| Mon, 8th (?)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| Boucman&lt;br /&gt;
| Fri, 5th (?)&lt;br /&gt;
| Mon, 8th (?)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| mordante&lt;br /&gt;
| Fri, 5th&lt;br /&gt;
| Sun, 7th&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| Turuk&lt;br /&gt;
| Fri, 5th&lt;br /&gt;
| Sun, 7th (?)&lt;br /&gt;
| unknown&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For accomodations please keep in mind that parking in the center of Brussels is really problematic. It might make sense to drive to the University where FOSDEM takes place, park there and take the bus into the town center (where some of the hotels/hostels are).&lt;br /&gt;
&lt;br /&gt;
Possible hostels that we at least contacted over the last years (some of them might already be booked out by now!):&lt;br /&gt;
* [http://www.chab.be/ CHAB]&lt;br /&gt;
* [http://www.2go4.be/ 2go4] Note: groups bigger 6 are not allowed, so we can (officially) not form a complete Wesnoth group at this hostel, got to meet somewhere in town/at the university...&lt;br /&gt;
* [http://www.jeugdherbergen.be/brusselE.htm Bruegel YH]&lt;br /&gt;
&lt;br /&gt;
On the official FOSDEM page [http://fosdem.org/2010/practical/accomodation some more possible hotels/hostels] are listed.&lt;br /&gt;
&lt;br /&gt;
== Maps ==&lt;br /&gt;
* [http://tinyurl.com/3a65gr Bruegel YH]&lt;br /&gt;
* [http://tinyurl.com/35br9c Brussels Central (Train Station) → Bruegel YH]&lt;br /&gt;
* [http://tinyurl.com/37d9v4 Bruegel YH → Brussels Central (Train Station) → Novotel Grand Place]&lt;br /&gt;
* [http://tinyurl.com/2mzns6 Novotel Grand Place]&lt;br /&gt;
* [http://tinyurl.com/3dggg3 CrownePlaza (Europa)]&lt;br /&gt;
* [http://tinyurl.com/36epxj FOSDEM]&lt;br /&gt;
* [http://tinyurl.com/2w4bms Novotel Grand Place -&amp;gt; FOSDEM]&lt;br /&gt;
&lt;br /&gt;
== Transportation ==&lt;br /&gt;
Information about how to reach the FOSDEM is listed at the [http://fosdem.org/2010/practical/transportation official transportation subpage].&lt;br /&gt;
&lt;br /&gt;
Short version of how to get there for those that reside in Bruegel YH and Novotel Grand Place (basically town center):&lt;br /&gt;
&lt;br /&gt;
* Enter Bus 71 (Debrouckere - Central Station (&amp;quot;Gare Centrale&amp;quot;) - Delta) somewhere at 'Central Station'&lt;br /&gt;
* Leave the bus at &amp;quot;ULB&amp;quot; (crossroads Ave. Adolphe Buyl - Sq. Deveze)&lt;br /&gt;
* Walk down Ave. Paul Heger on your right hand.&lt;br /&gt;
&lt;br /&gt;
== Wesnoth Hacking Room ==&lt;br /&gt;
&lt;br /&gt;
Wesnoth will not have a room of its own. Instead we will use one of the &amp;quot;general hacking rooms&amp;quot;. So far it is not sure which room it will be, if we do it like the last two years, it will be room number 115 in the building AW1. Last year this was the smaller of the two hacking rooms and we had no real problem with conquering (and holding) the first row in this room. There were not too many power outlets, so this year at least Ivanovic will bring one multi-outlet power strip plus some extension cable (5m or something like this). There is no wired network, everything wireless (and sometimes rather/very unstable!). Beside this you should bring laptops since there are no computers available for hacking.&lt;br /&gt;
&lt;br /&gt;
Short version:&lt;br /&gt;
 AW1 - Room 115&lt;br /&gt;
&lt;br /&gt;
== Planned discussion ==&lt;br /&gt;
We usually discuss all sorts of things at FOSDEM, this section is here to have a small bullet list of things that we actively want to discuss at FOSDEM.&lt;br /&gt;
* GSOC 2010: finding mentors, organizing the submission etc..&lt;br /&gt;
* FOSDEM 2011 : trying to get a dev room with other games ?&lt;br /&gt;
* [wanted: discussion topics!]&lt;br /&gt;
&lt;br /&gt;
== FOSDEM 2009 ==&lt;br /&gt;
We were already at FOSDEM 2009, here something as reference:&lt;br /&gt;
&lt;br /&gt;
* [http://www.wesnoth.org/wiki/Fosdem2009 FOSDEM 2009 wiki page]&lt;br /&gt;
&lt;br /&gt;
== FOSDEM 2008 ==&lt;br /&gt;
We were already at FOSDEM 2008, here something as reference:&lt;br /&gt;
&lt;br /&gt;
* [http://www.wesnoth.org/forum/viewtopic.php?p=283649#p283649 Forum topic (with group photo)]&lt;br /&gt;
* [http://www.wesnoth.org/wiki/Fosdem2008 2008 wiki page]&lt;br /&gt;
* [https://mail.gna.org/public/wesnoth-dev/2008-02/msg00078.html Summary of FOSDEM 2008 results]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Wesconf]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=30088</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=30088"/>
		<updated>2009-04-10T17:34:37Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 type=attack&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(me, target), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organize recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one wants to have AI recruit army, that consists of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Function would check for current unit ratio and try to recruit most needed units first, according to the specified map. Variations of above will be possible, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
*much more...&lt;br /&gt;
&lt;br /&gt;
all easy to achieve with some if() conditions.&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
Like last year, I'll have limited amount of free time till I finish all of my exams (around end of June). So there will be time when I will work for wesnoth for about 3-4 dais straight in a row, but there will be also some when I won't touch the code for even one week. I plan finis about 1/3 work before midterm evaluation, and focus on the rest after it, during July and August when I'll have a lot of free time just for wesnoth. Lat year it was not a problem at all.&lt;br /&gt;
&lt;br /&gt;
== Things to finish before midtime evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Redesign recruitment formula and make simple library from it&lt;br /&gt;
* Redesign how evaluation of unit effectivness works&lt;br /&gt;
* Code on fail formulas for units, side, candidate moves, design error reporting standard and document it, use it&lt;br /&gt;
* Implement one or two proposed code functionality&lt;br /&gt;
* Reorganize rercuitment= formula o work more like a move= formula&lt;br /&gt;
* Attach some simple recruitment formula to multiplayer scenario&lt;br /&gt;
* Play developer game around midterm evaluation time&lt;br /&gt;
&lt;br /&gt;
== Goals for the final evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Play more developer games to test different recruitment approaches.&lt;br /&gt;
* Make good recruitment formula for MP (comments from noy and Soliton and other people will be helpful)&lt;br /&gt;
** NOTE - this milestone is a HUGE one due to amount of things that we need to take into account:&lt;br /&gt;
*** Size and terrian on a map&lt;br /&gt;
*** number of villages&lt;br /&gt;
*** average defense/movement cost&lt;br /&gt;
*** enemy strength&lt;br /&gt;
*** AI current strength&lt;br /&gt;
*** abilities/weapon special bonuses&lt;br /&gt;
*** and more... &lt;br /&gt;
* Finish documentation of recruitment library&lt;br /&gt;
* Implement all of proposed code functionality&lt;br /&gt;
&lt;br /&gt;
== Above expectations ==&lt;br /&gt;
&lt;br /&gt;
* Design &amp;quot;Leader formula&amp;quot; to control leader&lt;br /&gt;
* Make recruit formula smartly position recruted units&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=29979</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=29979"/>
		<updated>2009-04-07T22:36:52Z</updated>

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

		<summary type="html">&lt;p&gt;Dragonking: /* Goals for the final evaluation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organize recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one wants to have AI recruit army, that consists of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Function would check for current unit ratio and try to recruit most needed units first, according to the specified map. Variations of above will be possible, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
*much more...&lt;br /&gt;
&lt;br /&gt;
all easy to achieve with some if() conditions.&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
Like last year, I'll have limited amount of free time till I finish all of my exams (around end of June). So there will be time when I will work for wesnoth for about 3-4 dais straight in a row, but there will be also some when I won't touch the code for even one week. I plan finis about 1/3 work before midterm evaluation, and focus on the rest after it, during July and August when I'll have a lot of free time just for wesnoth. Lat year it was not a problem at all.&lt;br /&gt;
&lt;br /&gt;
== Things to finish before midtime evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Redesign recruitment formula and make simple library from it&lt;br /&gt;
* Redesign how evaluation of unit effectivness works&lt;br /&gt;
* Code on fail formulas for units, side, candidate moves, design error reporting standard and document it, use it&lt;br /&gt;
* Implement one or two proposed code functionality&lt;br /&gt;
* Reorganize rercuitment= formula o work more like a move= formula&lt;br /&gt;
* Attach some simple recruitment formula to multiplayer scenario&lt;br /&gt;
* Play developer game around midterm evaluation time&lt;br /&gt;
&lt;br /&gt;
== Goals for the final evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Play more developer games to test different recruitment approaches.&lt;br /&gt;
* Make good recruitment formula for MP (comments from noy and Soliton and other people will be helpful)&lt;br /&gt;
** NOTE - this milestone is a HUGE one due to amount of things that we need to take into account:&lt;br /&gt;
*** Size and terrian on a map&lt;br /&gt;
*** number of villages&lt;br /&gt;
*** average defense/movement cost&lt;br /&gt;
*** enemy strength&lt;br /&gt;
*** AI current strength&lt;br /&gt;
*** abilities/weapon special bonuses&lt;br /&gt;
*** and more... &lt;br /&gt;
* Finish documentation of recruitment library&lt;br /&gt;
* Implement all of proposed code functionality&lt;br /&gt;
&lt;br /&gt;
== Above expectations ==&lt;br /&gt;
&lt;br /&gt;
* Design &amp;quot;Leader formula&amp;quot; to control leader&lt;br /&gt;
* Make recruit formula smartly position recruted units&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29785</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29785"/>
		<updated>2009-04-03T16:53:27Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Things to finish before midtime evaluation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organize recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one wants to have AI recruit army, that consists of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Function would check for current unit ratio and try to recruit most needed units first, according to the specified map. Variations of above will be possible, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
*much more...&lt;br /&gt;
&lt;br /&gt;
all easy to achieve with some if() conditions.&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
Like last year, I'll have limited amount of free time till I finish all of my exams (around end of June). So there will be time when I will work for wesnoth for about 3-4 dais straight in a row, but there will be also some when I won't touch the code for even one week. I plan finis about 1/3 work before midterm evaluation, and focus on the rest after it, during July and August when I'll have a lot of free time just for wesnoth. Lat year it was not a problem at all.&lt;br /&gt;
&lt;br /&gt;
== Things to finish before midtime evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Redesign recruitment formula and make simple library from it&lt;br /&gt;
* Redesign how evaluation of unit effectivness works&lt;br /&gt;
* Code on fail formulas for units, side, candidate moves, design error reporting standard and document it, use it&lt;br /&gt;
* Implement one or two proposed code functionality&lt;br /&gt;
* Reorganize rercuitment= formula o work more like a move= formula&lt;br /&gt;
* Attach some simple recruitment formula to multiplayer scenario&lt;br /&gt;
* Play developer game around midterm evaluation time&lt;br /&gt;
&lt;br /&gt;
== Goals for the final evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Play more developer games to test different recruitment approaches.&lt;br /&gt;
* Make good recruitment formula for MP (comments from noy and Soliton and other people will be helpful)&lt;br /&gt;
** NOTE - this milestone is a HUGE one due to amount of things that we need to take into account:&lt;br /&gt;
*** Size of a map&lt;br /&gt;
*** number of villages&lt;br /&gt;
*** average defense/movement cost&lt;br /&gt;
*** enemy strength&lt;br /&gt;
*** AI current strength&lt;br /&gt;
*** abilities/weapon special bonuses&lt;br /&gt;
*** many more... &lt;br /&gt;
* Finish documentation of recruitment library&lt;br /&gt;
* Implement all of proposed code functionality&lt;br /&gt;
&lt;br /&gt;
== Above expectations ==&lt;br /&gt;
&lt;br /&gt;
* Design &amp;quot;Leader formula&amp;quot; to control leader&lt;br /&gt;
* Make recruit formula smartly position recruted units&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29770</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29770"/>
		<updated>2009-04-03T11:34:08Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Milestones/Timeline */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organize recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one wants to have AI recruit army, that consists of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Function would check for current unit ratio and try to recruit most needed units first, according to the specified map. Variations of above will be possible, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
*much more...&lt;br /&gt;
&lt;br /&gt;
all easy to achieve with some if() conditions.&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
Like last year, I'll have limited amount of free time till I finish all of my exams (around end of June). So there will be time when I will work for wesnoth for about 3-4 dais straight in a row, but there will be also some when I won't touch the code for even one week. I plan finis about 1/3 work before midterm evaluation, and focus on the rest after it, during July and August when I'll have a lot of free time just for wesnoth. Lat year it was not a problem at all.&lt;br /&gt;
&lt;br /&gt;
== Things to finish before midtime evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Redesign recruitment formula and make simple library from it&lt;br /&gt;
* Redesign how evaluation of unit effectivness works&lt;br /&gt;
* Code on fail formulas for units, side, candidate moves, design error reporting standard and document it, use it&lt;br /&gt;
* Implement one or two proposed code functionality&lt;br /&gt;
* Reorganize rercuitment= formula o work more like a move= formula&lt;br /&gt;
* Attach some simple recruitment formula to multiplayer scenario&lt;br /&gt;
* Play developer game around  &lt;br /&gt;
&lt;br /&gt;
== Goals for the final evaluation ==&lt;br /&gt;
&lt;br /&gt;
* Play more developer games to test different recruitment approaches.&lt;br /&gt;
* Make good recruitment formula for MP (comments from noy and Soliton and other people will be helpful)&lt;br /&gt;
** NOTE - this milestone is a HUGE one due to amount of things that we need to take into account:&lt;br /&gt;
*** Size of a map&lt;br /&gt;
*** number of villages&lt;br /&gt;
*** average defense/movement cost&lt;br /&gt;
*** enemy strength&lt;br /&gt;
*** AI current strength&lt;br /&gt;
*** abilities/weapon special bonuses&lt;br /&gt;
*** many more... &lt;br /&gt;
* Finish documentation of recruitment library&lt;br /&gt;
* Implement all of proposed code functionality&lt;br /&gt;
&lt;br /&gt;
== Above expectations ==&lt;br /&gt;
&lt;br /&gt;
* Design &amp;quot;Leader formula&amp;quot; to control leader&lt;br /&gt;
* Make recruit formula smartly position recruted units&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29768</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29768"/>
		<updated>2009-04-03T10:41:12Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruting in SP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organize recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one wants to have AI recruit army, that consists of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Function would check for current unit ratio and try to recruit most needed units first, according to the specified map. Variations of above will be possible, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
*much more...&lt;br /&gt;
&lt;br /&gt;
all easy to achieve with some if() conditions.&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29767</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29767"/>
		<updated>2009-04-03T10:39:08Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruting in SP */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organice recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one want to have AI recruit army, that consist of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Funcion would check for current unit ratio and try to recruit most needed units first according to the specified map. Variations of above, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to recruit only units good agaisnt side 3, and side 1 recruit agaisnt side 4&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribute:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready to use. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example usage where we get units good against side 3 and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*) # custom function that returns map of unit -&amp;gt; score #&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples. Some additional function to &amp;quot;normalize&amp;quot; score values could be use as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29766</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29766"/>
		<updated>2009-04-03T10:36:18Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruitment formula */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in SP ====&lt;br /&gt;
&lt;br /&gt;
One of the problems is how to make recruting customizable for scenario designers and campaigns developers. In that matter, cooperation with campaign developers is needed, since there are people who are supposed to use it. I already did some talking about this idea and scenario developers needs with zookeeper.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organice recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one want to have AI recruit army, that consist of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Funcion would check for current unit ratio and try to recruit most needed units first according to the specified map. Variations of above, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to fight only agaisnt side 3, and side 1 agaisnt side 4&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribure:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example of function that gets units good against side 3, and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*)&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
Of course custom function must meet some conditions, but these would be specified in the &amp;quot;recruitment wiki&amp;quot; with some examples.&lt;br /&gt;
&lt;br /&gt;
==== Recruting in MP ====&lt;br /&gt;
&lt;br /&gt;
Recruting in multiplayer would be based on this library as well. To get desired set of functions and good set of recruting options, testing is needed. I would like to create table of units &amp;quot;ratings&amp;quot; against different factions, and of course play some games to test how recruiting works in certain situations.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29765</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29765"/>
		<updated>2009-04-03T10:20:36Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruitment formula */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
Other problem is how to make recruting customizable for scenario designers and campaigns developers.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organice recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one want to have AI recruit army, that consist of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Funcion would check for current unit ratio and try to recruit most needed units first according to the specified map. Variations of above, for example:&lt;br /&gt;
*recruiting one set of units between turns 1 and 10 and different one later&lt;br /&gt;
*making side 2 seem to fight only agaisnt side 3, and side 1 agaisnt side 4&lt;br /&gt;
&lt;br /&gt;
Also it would be good idea to take into account units &amp;quot;usage&amp;quot; attribure:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army_by_usage( [ 'fighter' -&amp;gt; 60, 'archer' -&amp;gt; 30, 'scout' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, documented in the wiki and ready. Of course for some specific purposes someone may need combining some custom rate_effectivness function with these provided by us. Example of function that gets units good against side 3, and good in forest:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 &lt;br /&gt;
 def rate_units_in_forest(ai*)&lt;br /&gt;
  ...;&lt;br /&gt;
 &lt;br /&gt;
 recruit_army( combine_ratings( calculate_defenders(self),rate_units_in_forest(self) ), self )&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, for example to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29757</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29757"/>
		<updated>2009-04-03T09:36:15Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruitment formula */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. That's why I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
First questions that may come to your mind are probably &amp;quot;Is this formula really needed?&amp;quot;, &amp;quot;Will it really bring some improvement?&amp;quot; or &amp;quot;Will it be really useful after re-designing of the whole AI?&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula showed that it is quite useful and generally recruits better than default AI. It does not exactly mean that '''default AI''' that uses this formula is always doing better - no, because even if we provide current AI with most useful set of units, it may still suicide some of them with stupid moves. But it brings at least some improvement. And what's most important - since in both Dave's and DartFool's proposal they mentioned possibility of using formula AI, then this recruitment formula '''will work with &amp;quot;new&amp;quot; AIs''' as well.&lt;br /&gt;
&lt;br /&gt;
Other problem is how to make recruting customizable for scenario designers and campaigns developers.&lt;br /&gt;
&lt;br /&gt;
My idea is to re-organice recruitment code, categorize functions and put these into fai file that one could include to their scenarios and make use of some default functions. For example if one want to have AI recruit army, that consist of 60% elvish fighters, 30% elvish archers and 10% mages, he would just write:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( [ 'Elvish Fighter' -&amp;gt; 60, 'Elvish archer' -&amp;gt; 30, 'Mage' -&amp;gt; 10 ], self )&lt;br /&gt;
&lt;br /&gt;
Funcion would check for current unit ratio and try to recruit most needed units first according to the specified map.&lt;br /&gt;
&lt;br /&gt;
Other example is trying to get good defensive set of units:&lt;br /&gt;
&lt;br /&gt;
 {data/AI/formula/lib/recruitment.fai}&lt;br /&gt;
 recruit_army( calculate_defenders(self), self )&lt;br /&gt;
&lt;br /&gt;
There would be set of functions, all documented in the wiki...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TO DO&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, for example to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29653</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29653"/>
		<updated>2009-04-02T16:26:12Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Things to write with FormulaAI language */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
I believe that to spot bugs and think about good new features and functions that should be added, usage of the formula AI is needed. As I wrote before, I don't think that writing whole AI in formula AI makes much sense, and that it is hard to create good '''general''' function library. I would like to continue work on the recruitment formula, based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]] but modified and improved.&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than default AI. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;TO DO&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
=== Developer games ===&lt;br /&gt;
&lt;br /&gt;
We need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test the formula AI, exchange ideas and of course have some fun. Games would be simmilar to these we used to play some time ago: developers against AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29651</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29651"/>
		<updated>2009-04-02T16:13:57Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Recruitment formula and leader move */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula  ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than default AI. Generally, this time I'd like to extend this formula to make it more like a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruiting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Leader candidate move ===&lt;br /&gt;
&lt;br /&gt;
Recruiting is connected with leader control, because we can recruit only if leader is in the keep. I'd like to introduce leader control candidate move, that could control the leader and take use for example of multiple available keeps, make use of it's abilities, etc. For example leader control itself could return set of orders to execute to make use of leadership ability.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29645</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29645"/>
		<updated>2009-04-02T16:03:32Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Candidate moves formulas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
***Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
***Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
***Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
***Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29644</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29644"/>
		<updated>2009-04-02T16:02:31Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Candidate moves formulas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
Besides recruitment formula I'd like to add some candidate moves to improve AI with some candidate moves:&lt;br /&gt;
&lt;br /&gt;
*Candidate moves that I would like to have:&lt;br /&gt;
**Scouting candidate move&lt;br /&gt;
Such candidate move exists already, just in not to well tested and remains unmaintained. I believe it is good idea to try to add it to the AI.&lt;br /&gt;
**Poisoners candidate move&lt;br /&gt;
Velory already wrote this candidate move. This also could be added to support default AI and when tested, maybe tweaked a bit (eval formula probably has the biggest impact on how effective this function is).&lt;br /&gt;
*Candidate moves that I would like to test:&lt;br /&gt;
**Berserker candidate move&lt;br /&gt;
Candidate move for this unit could probably improve how AI now uses these units. I believe that candidate move would be just temporary solution, because such special units should be treated by the AI in completely different way and be considered as really precious ones that AI should try to screen well.&lt;br /&gt;
**Levelup candidate move&lt;br /&gt;
Also one of candidate moves that we already have in our repository - also one that is not maintained anymore. I'd like to check whether it works properly and maybe tweak it. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So far I can think only about adding above candidate moves to support the AI, I somehow doubt that altering what healers and units with low hp do will have good influence on the AI.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29640</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29640"/>
		<updated>2009-04-02T15:43:45Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Then, why not AI ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29639</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29639"/>
		<updated>2009-04-02T15:32:05Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Then, why not AI ? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is similar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you need a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29638</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29638"/>
		<updated>2009-04-02T15:31:32Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Let's start from what is proposed... */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talks on the IRC, I can see 2 proposed ideas: first is Formula AI library, with functions that user could include and use. Second one is AI written in FormulaAI language that improves current C++ and can beat it. I consider first idea to be too general one. I find it hard to define milestones and find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29637</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29637"/>
		<updated>2009-04-02T15:21:04Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Why FormulaAI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. I'm also experienced wesnoth player and I know many various strategies/tactics. I have really strong understanding of different aspects of the game, what is definitely a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29606</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29606"/>
		<updated>2009-04-01T22:38:30Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29605</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29605"/>
		<updated>2009-04-01T22:38:13Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Things to implement to formula engine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
&lt;br /&gt;
=== New operators for list/map operations ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
We lack good way of simply doing some math operations on values inside lists and maps.&lt;br /&gt;
==== Background ====&lt;br /&gt;
I propose something like that:&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ] .+ [ 7, 6, 5 ]&lt;br /&gt;
&lt;br /&gt;
Operator .+ would just sum up values of above lists, and return new one of the same size:&lt;br /&gt;
&lt;br /&gt;
 [ 8, 8, 8 ]&lt;br /&gt;
&lt;br /&gt;
Simmilar operators would be .- .* and ./&lt;br /&gt;
&lt;br /&gt;
In case of map, operator .+ would work in simmilar way, just for values:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ] .+ [ 'elf' -&amp;gt; 30, 'dwarf'-&amp;gt; 40, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
would return&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 40, 'dwarf'-&amp;gt; 60, 'skeleton' -&amp;gt; 5 ]&lt;br /&gt;
&lt;br /&gt;
So values of the same keys are added, if key is non-existent in one of the maps, it is treated like it has value of 0 in this map.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SummerOfCodeIdeas&amp;diff=29428</id>
		<title>SummerOfCodeIdeas</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SummerOfCodeIdeas&amp;diff=29428"/>
		<updated>2009-03-30T18:03:17Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* AI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a compilation of ideas from ML. Needs to be refined (more detailed description, deliverables, workload estimation?):&lt;br /&gt;
&lt;br /&gt;
== I want to be one of your Google Summer of Code students, what should I do... ==&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of things to do to get you started&lt;br /&gt;
* Create an account on gna.org&lt;br /&gt;
* Create an account on the wesnoth forum, and tell an admin on the IRC channel to mark is as a GSoC Student account (Admins are boucman, Ivanovic, mordante, Shadow_Master, Sirp and Turuk)&lt;br /&gt;
* Join the irc channel (#wesnoth-dev on irc.freenode.net) and introduce yourself. We will not give formal interviews, but we will clearly favor people we have learned to know during the selection process (basically communication via IRC is mandatory for our project! it is the main way of &amp;quot;every day communication&amp;quot; for Wesnoth. For the same reason, it's also a good idea to regularly read the [http://wesnoth.debian.net/?C=M;O=A IRC logs].).&lt;br /&gt;
&lt;br /&gt;
* Start a wiki page about your idea, add a link on the bottom of this page and add this information on it:&lt;br /&gt;
** List your account names (gna, forum, irc nick) so that we can recognize you&lt;br /&gt;
** Fill the questionnaire on this page: [[SoC_Information_for_Google#Does_your_organization_have_an_application_template_you_would_like_to_see_students_use.3F_If_so.2C_please_provide_it_now.| List of questions to answer]]&lt;br /&gt;
** Detail your idea as much as possible, look at other students pages, and please give milestones and studies you've done&lt;br /&gt;
** Add a link to the page at the bottom of this page&lt;br /&gt;
&lt;br /&gt;
* Though not mandatory, it is highly advisable to go to the [[EasyCoding]] and [[NotSoEasyCoding]] pages and implement one of these ideas (or any idea of similar scope) so we have an idea how you work. Be sure to use your gna account when submitting these patches so we know who it is coming from. You can also implement some features from our feature request database at gna. When you implement something, also list it on your own page with a reference to the patch.&lt;br /&gt;
&lt;br /&gt;
* For working on Wesnoth you have to be able to compile trunk. To do so you should have a look at the [[WesnothSVN|page about svn]] and afterwards [[CompilingWesnoth|compile Wesnoth svn]].&lt;br /&gt;
&lt;br /&gt;
* Once you have everything done here and think your idea is okay, go to [http://groups.google.com/group/google-summer-of-code-announce/web/guide-to-the-gsoc-web-app-for-student-applicants page at google] to submit your application. You have to submit it before '''Date to be supplied later''' or you have no chance to get in!&lt;br /&gt;
&lt;br /&gt;
== List of Ideas for the Project (Suggestions from the wesnoth developers) ==&lt;br /&gt;
&lt;br /&gt;
Here is only a short description of possible Ideas we have, each has a page of its own with a more detailed version on it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize implementation of WML for memory usage ===&lt;br /&gt;
&lt;br /&gt;
Based on this idea: [http://dave.wesnoth.org/?p=9] optimize WML to minimize its memory usage. High memory usage has been a problem for Wesnoth, and this project will aim to reduce it.&lt;br /&gt;
&lt;br /&gt;
=== Implement campaign statistics reports on stats.wesnoth.org ===&lt;br /&gt;
&lt;br /&gt;
Wesnoth has an infrastructure which records details of campaigns that players play into a centralized MySQL database. However, we only have rudimentary reports based on this MySQL database available at this time, at [http://stats.wesnoth.org].&lt;br /&gt;
&lt;br /&gt;
This project would involve writing a stats reporting web site which would take the data from the MySQL database and produce reports in chart and table form. Campaign designers would be able to use these reports to gather feedback on their campaigns and get ideas for improvements.&lt;br /&gt;
&lt;br /&gt;
A student could largely make their choice of infrastructure for creating the Website -- whether they prefer Python, Perl, Ruby, PHP, etc. This is a great opportunity for someone who doesn't want to dive into hardcore C++ to make a valuable contribution to Wesnoth.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Stats Server]] - Full Version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Extending the Multiplayer server ===&lt;br /&gt;
&lt;br /&gt;
Our multiplayer community is generally strong and healthy, but we believe its growth is limited by some problems in the interface of the multiplayer lobby.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Multiplayer server]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Addon server ===&lt;br /&gt;
Wesnoth has an addon server which offers users to upload user &lt;br /&gt;
made content (UMC). This allows all other users of Wesnoth&lt;br /&gt;
to easily download and install this content. The server was &lt;br /&gt;
originally written for user-made campaigns but contains a lot&lt;br /&gt;
more types of addons nowadays. Both the server side and the &lt;br /&gt;
client side need to be improved.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Addon Server]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== WML validation schemes ===&lt;br /&gt;
Wesnoth uses WML as basic data structure. Over the years&lt;br /&gt;
this language has evolved and got more complex. At the&lt;br /&gt;
moment the WML is validated at runtime and in case of a&lt;br /&gt;
problem the engine stops. With schemes these problems can&lt;br /&gt;
be validated when loading the WML, making it easier to find&lt;br /&gt;
problems before running into them.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Schemes]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Write a primitive library for Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Wesnoth has always had a simple C++ based AI. David (our lead developer) has been working on a simple language to write AI in Wesnoth: [[FormulaAI]]&lt;br /&gt;
&lt;br /&gt;
The Wesnoth AI is used as an opponent in most campaigns, and as such is an important piece of code for the Wesnoth project. Unfortunately, because the skills required to understand and modify it are rather arcane, it is also one of the most neglected parts of the Wesnoth code. This is a place where a lot of research and useful work could be done. But keep in mind that [[WhyWritingAWesnothAIIsHard|writing an AI for Wesnoth is difficult]].&lt;br /&gt;
&lt;br /&gt;
Writing a whole AI is so complicated that we believe it can't be done in a single Summer of code. All proposals should keep that in mind and try to identify an interesting subset that would be workable in the limited time of a summer of code&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas FormulaAI]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Savegame reorganization ===&lt;br /&gt;
The savegame formats of Wesnoth for single player campaigns&lt;br /&gt;
and multiplayer differ from each other. And they are processed&lt;br /&gt;
differently as well. Now there is an additional request coming&lt;br /&gt;
up: Multiplayer campaigns. The task will be to unify the savegames&lt;br /&gt;
for all types of scenarios in order to provide a maintainable code&lt;br /&gt;
again.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Savegame]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other possible ideas to be fleshed out ===&lt;br /&gt;
A MapGenerator rewrite - better scalable for outdoor maps, plus the possibility to define areas (similar to the caverns in the cave generator) etc.&lt;br /&gt;
&lt;br /&gt;
=== Make your own ideas ===&lt;br /&gt;
If you have your own idea the best thing is to join IRC wesnoth-dev at irc.freenode.net and discuss the idea with the developers there. If the developers think your idea is interesting and like the feature you can start to turn it into a full proposal. Once done discuss it again on IRC so the developers can accept your idea.&lt;br /&gt;
&lt;br /&gt;
== Information about our Project ==&lt;br /&gt;
The information we provided google with about our project can be looked up at the site [[SoC Information for Google]].&lt;br /&gt;
&lt;br /&gt;
Also see the [[DeveloperResources]] link (from the [[Project]] page).&lt;br /&gt;
&lt;br /&gt;
== People to bug on IRC ==&lt;br /&gt;
We have prepared a list of people with their &amp;quot;area of competence&amp;quot;. This is to give you an idea on which areas those people can be of help for you. Of course you should always just ask in the IRC chan, but those are the most likely ones to answer questions in the respective area. And here is the list:&lt;br /&gt;
&lt;br /&gt;
[[SoC People to bug on IRC]]&lt;br /&gt;
&lt;br /&gt;
== GSoC Student pages ==&lt;br /&gt;
&lt;br /&gt;
Please add a link to your wiki page below&lt;br /&gt;
&lt;br /&gt;
==== AI ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Velory| Velory - SoC Proposal]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_AI_Improvement_Crab| Crab - SoC Proposal - AI Improvement]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Sparksteel | Sparksteel - Improving the AI engine design]]&lt;br /&gt;
&lt;br /&gt;
[[FormulaAISoC2009Dragonking | Dragonking - Improving the formula AI ]]&lt;br /&gt;
&lt;br /&gt;
==== Savegame reorganization ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Euschn | Euschn - Savegame reorganization]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_lmg| lmg - Savegame reorganization]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_grantwu| grantwu - Savegame reorganization]]&lt;br /&gt;
&lt;br /&gt;
==== Extending the Multiplayer server ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_rubend | rubend - Extending the Multiplayer server]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_IneQuation | IneQuation - Extending the Multiplayer server]]&lt;br /&gt;
&lt;br /&gt;
[[MP Server Ilor | Ilor - Extending the Multiplayer server]]&lt;br /&gt;
&lt;br /&gt;
==== Addon server ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Ryochan7| Ryochan7 - Addon server]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_iyonius| iyonius - Addon server]]&lt;br /&gt;
&lt;br /&gt;
==== Optimize implementation of WML for memory usage ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_res| res -  Optimize implementation of WML for memory usage ]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_jdmunro| jdmunro -  Optimize implementation of WML for memory usage ]]&lt;br /&gt;
&lt;br /&gt;
==== WML validation schemes ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_orian| orian - WML validation schemes ]]&lt;br /&gt;
&lt;br /&gt;
==== Implement campaign statistics reports on stats.wesnoth.org ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Elbin| Elbin - New campaign statistics page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Munk| Munk - New campaign stats page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_carlestyle| carlestyle - New campaign stats page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_nerwa| NeRwa - New campaign stats page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_mrfinch| mrfinch - New Campaign Statistics Page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_corn| corn - New Campaign Statistics Page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_csaunders | csaunders - SoC Proposal - Stats Server]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code|*]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29413</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29413"/>
		<updated>2009-03-30T00:17:19Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Milestones/Timeline =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29412</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29412"/>
		<updated>2009-03-30T00:16:29Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Things to write with FormulaAI language */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) '''regular developer games''' to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29411</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29411"/>
		<updated>2009-03-30T00:13:46Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Up to one month before releasing 1.6 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Other contributions ===&lt;br /&gt;
&lt;br /&gt;
* Wrote partol formula for 16th scenario of 'Legend of Wesmere' [http://svn.gna.org/viewcvs/wesnoth?rev=33683&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33796&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29410</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29410"/>
		<updated>2009-03-29T23:57:10Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#My contributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29409</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29409"/>
		<updated>2009-03-29T23:56:43Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
***My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
*** Either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
***Dragonking&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
***By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
***I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
***I have access to SVN. My recent contributions to Wesnoth:[[#MyContributions | my contributions]]&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29408</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29408"/>
		<updated>2009-03-29T23:51:29Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Candidate moves formulas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
= My contributions =&lt;br /&gt;
&lt;br /&gt;
== Up to one month before releasing 1.6 ==&lt;br /&gt;
&lt;br /&gt;
=== More important and significant changes ===&lt;br /&gt;
* Implemented pathfinding especially for formula AI to make functions move and move_partial work properly and be intuitive [http://svn.gna.org/viewcvs/wesnoth?rev=33009&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33223&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33361&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33362&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves crash wesnoth every time there was an error in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=32804&amp;amp;view=rev]&lt;br /&gt;
* Made unit loop formulas work even when no unit formula is specified [http://svn.gna.org/viewcvs/wesnoth?rev=33370&amp;amp;view=rev]&lt;br /&gt;
* Candidate moves and general side formula now work besides each other, not instead [http://svn.gna.org/viewcvs/wesnoth?rev=33618&amp;amp;view=rev]&lt;br /&gt;
* Added support for prorities for unit formulas, fixed candidate moves bug that made it execute first moves with *lowest* score, initial unit modification to prepare it for on_fail formula support.[http://svn.gna.org/viewcvs/wesnoth?rev=33636&amp;amp;view=rev]&lt;br /&gt;
* Added [ai] tag to single unit WML, renamed [ai_vars] to [vars], renamed 'faifile' keyword to 'fai', added new keyword: end. Fixed  bug that caused some unit variables be saved to file incorrectly. Removed obsolete formula test case. [http://svn.gna.org/viewcvs/wesnoth?rev=33677&amp;amp;view=rev]&lt;br /&gt;
* Added new formula function castle_locs [http://svn.gna.org/viewcvs/wesnoth?rev=33712&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
=== Various fixes and improvements ===&lt;br /&gt;
&lt;br /&gt;
* Disable formula AI in multiplayer [http://svn.gna.org/viewcvs/wesnoth?rev=33169&amp;amp;view=rev]&lt;br /&gt;
* Fixed candidate moves into infinite loop bug [http://svn.gna.org/viewcvs/wesnoth?rev=33192&amp;amp;view=rev]&lt;br /&gt;
* Fix for attack function and some overall improvements [http://svn.gna.org/viewcvs/wesnoth?rev=33190&amp;amp;view=rev][http://svn.gna.org/viewcvs/wesnoth?rev=33346&amp;amp;view=rev]&lt;br /&gt;
* Made formula AI unit members correspond to these in SingleUnitWML [http://svn.gna.org/viewcvs/wesnoth?rev=33368&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula parser bug [http://svn.gna.org/viewcvs/wesnoth?rev=33373&amp;amp;view=rev]&lt;br /&gt;
* Fixed formula operator '.' bug [http://svn.gna.org/viewcvs/wesnoth?rev=33566&amp;amp;view=rev]&lt;br /&gt;
* Made [function] WML tag for formula work [http://svn.gna.org/viewcvs/wesnoth?rev=33612&amp;amp;view=rev]&lt;br /&gt;
* Improved formula test scenario [http://svn.gna.org/viewcvs/wesnoth?rev=33648&amp;amp;view=rev]&lt;br /&gt;
* Moved adjacent_locs form location object to separate function and fixed it. Fixed attack() function. [http://svn.gna.org/viewcvs/wesnoth?rev=33639&amp;amp;view=rev]&lt;br /&gt;
* Fixed buggy 'special' attack object member [http://svn.gna.org/viewcvs/wesnoth?rev=33653&amp;amp;view=rev]&lt;br /&gt;
* Formula AI parser bug causing where keyword crash wesnoth when 'self' was used in the formula [http://svn.gna.org/viewcvs/wesnoth?rev=33793&amp;amp;view=rev]&lt;br /&gt;
* Fixed defense_on function [http://svn.gna.org/viewcvs/wesnoth?rev=33860&amp;amp;view=rev]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== During Summer of Code application period ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29407</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29407"/>
		<updated>2009-03-29T23:06:21Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
= Idea Description =&lt;br /&gt;
== Why FormulaAI? ==&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
== Let's start from what is proposed... ==&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
== Then, why not AI ? ==&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
== Straight to the point ==&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
== Things to implement to formula engine ==&lt;br /&gt;
&lt;br /&gt;
=== 'on_fail' formulas ===&lt;br /&gt;
==== Background ==== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
=== Fractions ===&lt;br /&gt;
==== Background ====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
=== Candidate moves ideas === &lt;br /&gt;
==== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
==== 'support' type candidate move ====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
==== Precondition formula ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
=== FormulaAI improved logs ===&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
=== More info for FormulaAI ===&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
=== Add option to choose FormulaAI as alternative AI ===&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other ideas ===&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
== Things to write with FormulaAI language ==&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
=== Recruitment formula and leader move ===&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
=== Candidate moves formulas ===&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29405</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29405"/>
		<updated>2009-03-29T21:39:19Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Let's start from what is proposed... */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
In the wiki, and after some talking on the IRC I can see 2 proposed ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other ideas ====&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
==== Recruitment formula and leader move ====&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves formulas ====&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29404</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29404"/>
		<updated>2009-03-29T21:38:44Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Why FormulaAI? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new functions, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many various strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, formula AI language can be used by other people to write their own simple AI - and I do enjoy helping others who want learn this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
On the wiki, and after some talking on the IRC I can see 2 ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other ideas ====&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
==== Recruitment formula and leader move ====&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves formulas ====&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29403</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29403"/>
		<updated>2009-03-29T21:17:20Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new function, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many verious strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, forula AI language can be used by other people to write their own simple AI - and I do enjoy helping others gain knowledge about how to use this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
On the wiki, and after some talking on the IRC I can see 2 ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 name=my_candidate_move&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which different evals returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other ideas ====&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
==== Recruitment formula and leader move ====&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves formulas ====&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29402</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29402"/>
		<updated>2009-03-29T21:15:11Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Things to write with FormulaAI language */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new function, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many verious strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, forula AI language can be used by other people to write their own simple AI - and I do enjoy helping others gain knowledge about how to use this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
On the wiki, and after some talking on the IRC I can see 2 ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which this eval returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other ideas ====&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
&lt;br /&gt;
I believe, that to spot bugs and be able to think about new features and functions, usage of formula AI is needed. Besides that ,we need testing, that's why I would like to organize from time to time (starting from around midterm evaluation) regular developer games to test formula AI.&lt;br /&gt;
&lt;br /&gt;
==== Recruitment formula and leader move ====&lt;br /&gt;
&lt;br /&gt;
Based on my last year proposal: [[FormulaAIBaseAI#AI_recruitment]]&lt;br /&gt;
&lt;br /&gt;
Recent testing of this formula, showed that it is quite useful and generally recruits better than defaul AI. Generally, this time I'd like to extend this formula to make it more loke a &amp;quot;leader control formula&amp;quot;. There is still number of things to take into account while recruting for example:&lt;br /&gt;
&lt;br /&gt;
'''size of the map''', units '''max movement'''&lt;br /&gt;
To calculate how many scouts we need, we have to remember that on small maps often we don't need any scouts.&lt;br /&gt;
&lt;br /&gt;
And besides that, some more testing is needed, to tweak bonuses that units get for weapon specials and abilities.&lt;br /&gt;
&lt;br /&gt;
A leader part would be responsible for keeping leader in keep/getting some nearby villages at the beggining. Further improvements may include using some special abilities like healing/poison/leadership - and these need to have higher priority than any used candidate moves.&lt;br /&gt;
&lt;br /&gt;
==== Candidate moves formulas ====&lt;br /&gt;
&lt;br /&gt;
I'd like to add some candidate moves for poisoners (I know velory wrote one already, but I have my own idea for that) and scouting evaluation (we already have one now, but also I'd do it a bit in a different way). But this task can wait for now.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29398</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29398"/>
		<updated>2009-03-29T20:29:14Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Add option to choose FormulaAI as alternative AI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new function, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many verious strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, forula AI language can be used by other people to write their own simple AI - and I do enjoy helping others gain knowledge about how to use this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
On the wiki, and after some talking on the IRC I can see 2 ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which this eval returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Other ideas ====&lt;br /&gt;
&lt;br /&gt;
I had few different ideas, regarding writing formulas and making that and testing easier, but currently other students (well, mainly Crab :) ) are working on some patches to do exactly that, so I'll focus on what I've written above, to not duplicate their work.&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
WIP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29397</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29397"/>
		<updated>2009-03-29T20:21:20Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Idea Description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
=== Why FormulaAI? ===&lt;br /&gt;
&lt;br /&gt;
I have been working on FormulaAI for a while now - bugfixing, new function, new features, testing, etc. I know the existing code well. Besides that, I'm experienced wesnoth player, and I know many verious strategies/tactics, so I have really strong understanding of different aspects of the game, what is definiately a desired thing if one wants to work on improving the AI. Besides that, forula AI language can be used by other people to write their own simple AI - and I do enjoy helping others gain knowledge about how to use this language.&lt;br /&gt;
&lt;br /&gt;
=== Let's start from what is proposed... ===&lt;br /&gt;
&lt;br /&gt;
On the wiki, and after some talking on the IRC I can see 2 ideas: first is Formula AI library, with functions that user could inclue and use. Second, is AI written in FormulaAI language, that improves current C++ and can beat it. After some thinking, I consider first idea to be too general one. I find it hard to define milestones, find reasonable ideas for functions. In my opinion, such thing is not good to choose for SoC, when you have to write something useful in limited amount of time, but should grow slowly, based on what people who actually use formula AI need.&lt;br /&gt;
&lt;br /&gt;
=== Then, why not AI ? ===&lt;br /&gt;
&lt;br /&gt;
Second proposal is simmilar to the one form year ago. Because I was one of the people working on this during SoC 2008, I can see some problems with this idea. First problem I encountered year ago, was FormulaAI language itself - it was not developed enough for such a big task at that time, and because of that I was forced to focus on improving language itself rather than working on the AI. I believe that in current state of FormulaAI language, designing AI could be easier, but still would be disturbed by bugfixing. Second problem I can see, is that I don't believe that general wesnoth AI can be written in FormulaAI language alone. It can work perfectly for some scenario  where you nee a specific-purpose AI, but not for general case, even with current approach of candidate moves/side formulas because of how complicated AI in wesnoth must be. And third thing: recently DarthFool and Sirp presented some interesting ideas of re-developing AI for wesnoth. Both of them mentioned, that formulas written in formula AI language could be used as plugins to the AI - difference between current implementation and their ideas would be that we could better design the relation between C++ AI and formulas - not make formula AI and then fallback to default &amp;quot;stupid&amp;quot; one like it is only possible now. And this leads to what I would like to do during Summer of Code:&lt;br /&gt;
&lt;br /&gt;
=== Straight to the point ===&lt;br /&gt;
&lt;br /&gt;
I would like to focus on improving and extending the formulaAI language during Google Summer of Code 2009. First, because it could be later used to &amp;quot;support&amp;quot; creating better default AI, second, because 1.6 is first stable release in which formula AI is available for campaign designers. I know that it may sound a bit &amp;quot;general&amp;quot; and it may be hard to consider good tasks and milestones, but I believe that with my experience from previous GSoC I can propose reasonable approach. Generally, I would work on my ideas for formula AI language, and in between, I would fix some bugs and help people around using formula AI. It is hard to define now how much time fixing bugs/helping others will take, so I don't want to base my evaluation on that. I just want to note that there may be a need to alter my milestones/timeline (like last year's SoC showed us). But to give you some detail that I do know what I want to do...&lt;br /&gt;
&lt;br /&gt;
=== Things to implement to formula engine ===&lt;br /&gt;
&lt;br /&gt;
==== 'on_fail' formulas ====&lt;br /&gt;
===== Background ===== &lt;br /&gt;
Current problem with formula language is: what if there no no room for recruitment but we still send order to recruit? Or we send recruit order, but with unknown/incorrect unit name? ATM, formula treats it as an invalid move, so all loop-type formulas are cancelled. This is not a good approach, because order itself is valid, just it contains incorrect data.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I propose &amp;quot;on_fail&amp;quot; formula, available both for side and for unit formulas. Basic example is:&lt;br /&gt;
&lt;br /&gt;
 move=&amp;quot;recruit('Skeleton Archer')&amp;quot;&lt;br /&gt;
 on_fail=&amp;quot;fallback()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we cannot recruit Skeleton Archer, then we just fallaback to default AI. But there's more - to give proper info about what happened, the &amp;quot;error&amp;quot; and &amp;quot;errdsc&amp;quot; side variables would be set to allow trace the problem, thus we could use on_fail formulas like that:&lt;br /&gt;
&lt;br /&gt;
 on_fail=&amp;quot;if(vars.error = 'recruitment', &lt;br /&gt;
            if( vars.errdsc = 'no_space', find_nearest_free_keep(), var.errdsc = 'unknown_unit', something_else() ), fallback() )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
There would be different types of errors and errdscs - depending on what caused the problem. on_fail formulas would support recruit, move, move_partial and attack formula orders.&lt;br /&gt;
&lt;br /&gt;
==== Fractions ====&lt;br /&gt;
===== Background =====&lt;br /&gt;
Currently formula language does not support fractions like 0.25, so formula like &amp;quot;1/2&amp;quot; is evaluated to 0.&lt;br /&gt;
===== Solution =====&lt;br /&gt;
I would implement simple fractions - by simple I mean that these fraction would have only 2 decimal places. So &amp;quot;1/3&amp;quot; would result in 0.33. Such simplified solution should be enough for formula AI, and still will make writing formulas more intuitive. This change would lead to implementing new variant TYPE_FRACTION and of course various rounding functions like round(), floor(), ceil().&lt;br /&gt;
 &lt;br /&gt;
==== Candidate moves ideas ==== &lt;br /&gt;
===== Generic &amp;quot;three part&amp;quot; formula ( based on what boucman proposed )=====&lt;br /&gt;
This kind of candidate move would look like that:&lt;br /&gt;
&lt;br /&gt;
 name=something&lt;br /&gt;
 type=three_part&lt;br /&gt;
 precondition=&amp;quot;calculate_units()&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;eval()&amp;quot;&lt;br /&gt;
 actions=&amp;quot;action()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
precondition would be used to create vector or map with units. Then based on outcome, evaluation would be run, and finally, action. Thanks ot that, we could add some flexibility to candidate moves system. I already can see that probably some new functions that operate on a map will be needed. Example usage:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;[ tomap( my_leader, enemy_units ) ]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Assuming we extend &amp;quot;tomap&amp;quot; functionality it could return map like&lt;br /&gt;
&lt;br /&gt;
 [ my_leader -&amp;gt; unit1, my_leader -&amp;gt; unit2, ... ]&lt;br /&gt;
&lt;br /&gt;
Then we would take keys and values and do pair evaluation:&lt;br /&gt;
&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit1&lt;br /&gt;
 my_leader &amp;lt;-&amp;gt; unit2&lt;br /&gt;
 ....&lt;br /&gt;
&lt;br /&gt;
===== 'support' type candidate move =====&lt;br /&gt;
Simple idea, simmilar to &amp;quot;attack&amp;quot; candidate move, just working for 2 units of the same side.&lt;br /&gt;
&lt;br /&gt;
===== Precondition formula =====&lt;br /&gt;
====== Background ======&lt;br /&gt;
Currently, when we have attack candidate move with eval like:&lt;br /&gt;
&lt;br /&gt;
 evaluation=&amp;quot;if( me.hitpoints &amp;gt; 30, evaluate_me_and_target(), -1 )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
It is evaluated for each friendly unit m times - where m is number of enemies. And after one valuation, it can be evaluated again - and that happens j+1 times, where j is number of units for which this eval returned score &amp;gt; 0. This is quite not optimal solution.&lt;br /&gt;
&lt;br /&gt;
====== Solution ======&lt;br /&gt;
I want to add precondition formula, which would be evaluated once for every unit, so above example coulbe be replaced with:&lt;br /&gt;
&lt;br /&gt;
 precondition=&amp;quot;if(me.hitpoints &amp;gt; 30, 1, -1)&amp;quot;&lt;br /&gt;
 evaluation=&amp;quot;evaluate_me_and_target()&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For each my unit precondition will be run once, and only if it returns score &amp;gt; 0, evaluation will be executed m times (for every enemy unit). I think that assuming we can have 10+ candidate moves, and more than 50 units on a map, we should consider implementing it.&lt;br /&gt;
&lt;br /&gt;
==== FormulaAI improved logs ====&lt;br /&gt;
This idea is about making formula AI more verbose, and allow it to take advantage of different log levels:&lt;br /&gt;
&lt;br /&gt;
info level would provide information about executed orders&lt;br /&gt;
&lt;br /&gt;
warning level would provide info about possible type errors&lt;br /&gt;
&lt;br /&gt;
error level would provide info about moves that caused formula to run on_fail formula&lt;br /&gt;
&lt;br /&gt;
==== More info for FormulaAI ====&lt;br /&gt;
To know where we or anamy can move, we can use now my_moves and enemy_moves. But we lack info about how far we can move if we for example kill one unit. For that I would like to add functions that return info about individual unit range, and AI members that could inform about the same, just for all units - my_range, enemy_range.&lt;br /&gt;
&lt;br /&gt;
==== Add option to choose FormulaAI as alternative AI ====&lt;br /&gt;
That idea requires taking care of two things:&lt;br /&gt;
&lt;br /&gt;
First, add option to choose formula AI, which would be at the beggining defaul AI with my recruting algorithm. Second - allow user data to overwrite default ai settings while creating multiplayer scenarios with custom formula - that is not yet possible.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Things to write with FormulaAI language ===&lt;br /&gt;
WIP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29390</id>
		<title>FormulaAISoC2009Dragonking</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAISoC2009Dragonking&amp;diff=29390"/>
		<updated>2009-03-29T11:51:06Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: New page: == Introduction ==  *Basics   **Write a small introduction to yourself. My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science an...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
*Basics &lt;br /&gt;
&lt;br /&gt;
**Write a small introduction to yourself.&lt;br /&gt;
My name is Bartek Waresiak and I'm from Poland. I'm 22 years old male interested in programming, computer science and gaming. I have been Battle for Wesnoth player for more than 5 years, and developer for about 4 years (coder since Summer of Code 2008).&lt;br /&gt;
&lt;br /&gt;
**State your preferred email address.&lt;br /&gt;
either dragonking_ATTT_o2_D0T_pl or b.waresiak_ATTT_gmail_D0T_com&lt;br /&gt;
&lt;br /&gt;
**If you have chosen a nick for IRC and Wesnoth forums, what is it?&lt;br /&gt;
Dragonking&lt;br /&gt;
&lt;br /&gt;
**Why do you want to participate in summer of code?&lt;br /&gt;
By participating in Google Summer of Code I want to significantly increase amount of time that I spend working for Battle for Wesnoth, have some fun and earn some money.&lt;br /&gt;
&lt;br /&gt;
**What are you studying, subject, level and school?&lt;br /&gt;
I'm studying Information Technology, 3nd year at AGH University of Science and Technology in Cracow, Poland.&lt;br /&gt;
&lt;br /&gt;
**If you have contributed any patches to Wesnoth, please list them below. You can also list patches that have been submitted but not committed yet and patches that have not been specifically written for Wesnoth. If you have gained commit access to our SVN (during the evaluation period or earlier) please state so.&lt;br /&gt;
I have access to SVN. My recent contributions to Wesnoth:&lt;br /&gt;
*** Before 1.6 release 'bugfixing-time':&lt;br /&gt;
&lt;br /&gt;
*** Directly before Summer of Code application period:&lt;br /&gt;
&lt;br /&gt;
*Experience &lt;br /&gt;
**What programs/software have you worked on before? &lt;br /&gt;
***I've been one of Battle for Wesnoth developers since September 2005 and I have been working on FormulaAI language since Summer of Code 2008. Besides that, I wrote various projects for my university (algorithm-testing, training projects, optimalization tasks, etc...).&lt;br /&gt;
**Have you developed software in a team environment before? (As opposed to hacking on something on your own)&lt;br /&gt;
***I'm one of Developers in 'Battle for Wesnoth' project and I have experience in group decision making.&lt;br /&gt;
**Have you participated to the Google Summer of Code before? As a mentor or a student? In what project? Were you successful? If not, why? &lt;br /&gt;
***I had been participatin in Google Summer of Code 2008, workin on Formula AI for Battle for Wesnoth project. My project was successful.&lt;br /&gt;
&lt;br /&gt;
*Open Source &lt;br /&gt;
**Are you already involved with any open source development projects? If yes, please describe the project and the scope of your involvement. &lt;br /&gt;
***As Developer for Battle for Wesnoth project I've been responsible for developing, improving, testing and documentation of the FormulaAI language. Besides that, I've been supporting people trying to use this language in their scenarios/campaigns. Previously, as a Multiplayer Developer I've been one of people responsible for unit balancing (unit statistics tweaking), multiplayer server moderation and basic administration.&lt;br /&gt;
&lt;br /&gt;
*Gaming experience &lt;br /&gt;
**Are you a gamer? &lt;br /&gt;
***Yes, I like to play various types of games: strategy games - both real time and turn-based, role-playing games and some of the first person shooters. I'm rather patient and calm player and I enjoy difficult games which require some amount of 'hard thinking'. &lt;br /&gt;
**What type of opponents do you prefer? &lt;br /&gt;
***I prefer human opponents much more than AI, but they have to be polite, civil and mature. I really enjoy  games against experienced player, though I don't mind also tutoring new ones.&lt;br /&gt;
**Are you more interested in story or gameplay? &lt;br /&gt;
***I value both - IMHO to bring a game to someone's attention, it must have a decent gameplay. If it has a nice storyline as well, then chances that players will keep playing and won't leave increase.&lt;br /&gt;
**Have you played Wesnoth? If so, tell us roughly for how long and whether you lean towards single player or multiplayer. &lt;br /&gt;
***I have been playing Wesnoth since about 0.7 version, mainly multiplayer because I enjoy Wesnoth players community and recognize it as polite and mature one. Also, like I mentioned, multiplayer games against human opponents are for me much more enjoyable than single-player campaigns.&lt;br /&gt;
&lt;br /&gt;
*Communication skills &lt;br /&gt;
**Though most of our developers are not native English speakers, English is the project's working language. Describe your fluency level in written English. &lt;br /&gt;
***I have no problem with understanding written English, and describing my thoughts to the others in this language.&lt;br /&gt;
**Are you good at interacting with other players? Our developer community is friendly, but the player community can be a bit rough. &lt;br /&gt;
***I think I know Wesnoth developers and players community well, and I've always been trying to always be on good terms with everyone. I know whom to talk to about different issues and who can give me needed advice or support. I also have quite a lot experience with interacting with multiplayer community.&lt;br /&gt;
**Do you give constructive advice? &lt;br /&gt;
***When giving advice, I try to be as detailed as possible, and make sure that people who I direct advice to understand me well. I am aware that during the internet chat you can be misinterpreted and your advice may instead be received as a negative criticism, I'm trying to avoid it by being friendly towards others.&lt;br /&gt;
**Do you receive advice well? &lt;br /&gt;
***I know that I can be wrong and that around me many people are far more experienced than me, I consider advices from others as a good thing which helps me improve and develop my skills.&lt;br /&gt;
**Are you good at sorting useful criticisms from useless ones? &lt;br /&gt;
***I have to admit it is hard to receive bad criticism - if someone is telling you that you are plain wrong, but is not providing any arguments to back up his opinion, then usually this kind of criticism is a useless one. If someone can criticize what I am doing providing examples what is wrong and how it can be improved - it is definitely an example of useful and desired criticism.&lt;br /&gt;
&lt;br /&gt;
*Project &lt;br /&gt;
Described below.&lt;br /&gt;
&lt;br /&gt;
*Practical considerations &lt;br /&gt;
**AAre you familiar with any of the following tools or languages?&lt;br /&gt;
***Subversion &lt;br /&gt;
****Yes, about 3-year experience.&lt;br /&gt;
***C++ &lt;br /&gt;
****I have more than 2 years of C/C++ experience.&lt;br /&gt;
***Python &lt;br /&gt;
****No.&lt;br /&gt;
**Which tools do you normally use for development? Why do you use them? &lt;br /&gt;
***I'm working on Debian Linux.&lt;br /&gt;
**What programming languages are you fluent in? &lt;br /&gt;
***C/C++ and Java.&lt;br /&gt;
**What spoken languages are you fluent in? &lt;br /&gt;
***Polish - which is my mother tongue, and English.&lt;br /&gt;
**At what hours are you awake (please specify in UTC) &lt;br /&gt;
***Usually I'm awake between 8 and 23 UTC, and available on IRC betweeen 17 and 23 UTC.&lt;br /&gt;
**Would you mind talking with your mentor on telephone / internet phone? We would like to have a backup way for communications for the case that somehow emails and IRC do fail.&lt;br /&gt;
***I wouldn't mind.&lt;br /&gt;
&lt;br /&gt;
== Idea Description ==&lt;br /&gt;
WIP&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SummerOfCodeIdeas&amp;diff=29134</id>
		<title>SummerOfCodeIdeas</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SummerOfCodeIdeas&amp;diff=29134"/>
		<updated>2009-03-23T12:05:15Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: Split into categories&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a compilation of ideas from ML. Needs to be refined (more detailed description, deliverables, workload estimation?):&lt;br /&gt;
&lt;br /&gt;
== I want to be one of your Google Summer of Code students, what should I do... ==&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of things to do to get you started&lt;br /&gt;
* Create an account on gna.org&lt;br /&gt;
* Create an account on the wesnoth forum, and tell an admin on the IRC channel to mark is as a GSoC Student account (Admins are boucman, Ivanovic, mordante, Shadow_Master, Sirp and Turuk)&lt;br /&gt;
* Join the irc channel (#wesnoth-dev on irc.freenode.net) and introduce yourself. We will not give formal interviews, but we will clearly favor people we have learned to know during the selection process (basically communication via IRC is mandatory for our project! it is the main way of &amp;quot;every day communication&amp;quot; for Wesnoth. For the same reason, it's also a good idea to regularly read the [http://wesnoth.debian.net/?C=M;O=A IRC logs].).&lt;br /&gt;
&lt;br /&gt;
* Start a wiki page about your idea, add a link on the bottom of this page and add this information on it:&lt;br /&gt;
** List your account names (gna, forum, irc nick) so that we can recognize you&lt;br /&gt;
** Fill the questionnaire on this page: [[SoC_Information_for_Google#Does_your_organization_have_an_application_template_you_would_like_to_see_students_use.3F_If_so.2C_please_provide_it_now.| List of questions to answer]]&lt;br /&gt;
** Detail your idea as much as possible, look at other students pages, and please give milestones and studies you've done&lt;br /&gt;
** Add a link to the page at the bottom of this page&lt;br /&gt;
&lt;br /&gt;
* Though not mandatory, it is highly advisable to go to the [[EasyCoding]] and [[NotSoEasyCoding]] pages and implement one of these ideas (or any idea of similar scope) so we have an idea how you work. Be sure to use your gna account when submitting these patches so we know who it is coming from. You can also implement some features from our feature request database at gna. When you implement something, also list it on your own page with a reference to the patch.&lt;br /&gt;
&lt;br /&gt;
* For working on Wesnoth you have to be able to compile trunk. To do so you should have a look at the [[WesnothSVN|page about svn]] and afterwards [[CompilingWesnoth|compile Wesnoth svn]].&lt;br /&gt;
&lt;br /&gt;
* Once you have everything done here and think your idea is okay, go to [http://groups.google.com/group/google-summer-of-code-announce/web/guide-to-the-gsoc-web-app-for-student-applicants page at google] to submit your application. You have to submit it before '''Date to be supplied later''' or you have no chance to get in!&lt;br /&gt;
&lt;br /&gt;
== List of Ideas for the Project (Suggestions from the wesnoth developers) ==&lt;br /&gt;
&lt;br /&gt;
Here is only a short description of possible Ideas we have, each has a page of its own with a more detailed version on it.&lt;br /&gt;
&lt;br /&gt;
=== Optimize implementation of WML for memory usage ===&lt;br /&gt;
&lt;br /&gt;
Based on this idea: [http://dave.wesnoth.org/?p=9] optimize WML to minimize its memory usage. High memory usage has been a problem for Wesnoth, and this project will aim to reduce it.&lt;br /&gt;
&lt;br /&gt;
=== Implement campaign statistics reports on stats.wesnoth.org ===&lt;br /&gt;
&lt;br /&gt;
Wesnoth has an infrastructure which records details of campaigns that players play into a centralized MySQL database. However, we only have rudimentary reports based on this MySQL database available at this time, at [http://stats.wesnoth.org].&lt;br /&gt;
&lt;br /&gt;
This project would involve writing a stats reporting web site which would take the data from the MySQL database and produce reports in chart and table form. Campaign designers would be able to use these reports to gather feedback on their campaigns and get ideas for improvements.&lt;br /&gt;
&lt;br /&gt;
A student could largely make their choice of infrastructure for creating the Website -- whether they prefer Python, Perl, Ruby, PHP, etc. This is a great opportunity for someone who doesn't want to dive into hardcore C++ to make a valuable contribution to Wesnoth.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Stats Server]] - Full Version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Extending the Multiplayer server ===&lt;br /&gt;
&lt;br /&gt;
Our multiplayer community is generally strong and healthy, but we believe its growth is limited by some problems in the interface of the multiplayer lobby.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Multiplayer server]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Addon server ===&lt;br /&gt;
Wesnoth has an addon server which offers users to upload user &lt;br /&gt;
made content (UMC). This allows all other users of Wesnoth&lt;br /&gt;
to easily download and install this content. The server was &lt;br /&gt;
originally written for user-made campaigns but contains a lot&lt;br /&gt;
more types of addons nowadays. Both the server side and the &lt;br /&gt;
client side need to be improved.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Addon Server]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== WML validation schemes ===&lt;br /&gt;
Wesnoth uses WML as basic data structure. Over the years&lt;br /&gt;
this language has evolved and got more complex. At the&lt;br /&gt;
moment the WML is validated at runtime and in case of a&lt;br /&gt;
problem the engine stops. With schemes these problems can&lt;br /&gt;
be validated when loading the WML, making it easier to find&lt;br /&gt;
problems before running into them.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Schemes]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Write a primitive library for Formula AI ===&lt;br /&gt;
&lt;br /&gt;
Wesnoth has always had a simple C++ based AI. David (our lead developer) has been working on a simple language to write AI in Wesnoth: [[FormulaAI]]&lt;br /&gt;
&lt;br /&gt;
The Wesnoth AI is used as an opponent in most campaigns, and as such is an important piece of code for the Wesnoth project. Unfortunately, because the skills required to understand and modify it are rather arcane, it is also one of the most neglected parts of the Wesnoth code. This is a place where a lot of research and useful work could be done. But keep in mind that [[WhyWritingAWesnothAIIsHard|writing an AI for Wesnoth is difficult]].&lt;br /&gt;
&lt;br /&gt;
Writing a whole AI is so complicated that we believe it can't be done in a single Summer of code. All proposals should keep that in mind and try to identify an interesting subset that would be workable in the limited time of a summer of code&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas FormulaAI]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
=== Savegame reorganization ===&lt;br /&gt;
The savegame formats of Wesnoth for single player campaigns&lt;br /&gt;
and multiplayer differ from each other. And they are processed&lt;br /&gt;
differently as well. Now there is an additional request coming&lt;br /&gt;
up: Multiplayer campaigns. The task will be to unify the savegames&lt;br /&gt;
for all types of scenarios in order to provide a maintainable code&lt;br /&gt;
again.&lt;br /&gt;
&lt;br /&gt;
[[SoC Ideas Savegame]] - Full version of the idea, with detailed information&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other possible ideas to be fleshed out ===&lt;br /&gt;
A MapGenerator rewrite - better scalable for outdoor maps, plus the possibility to define areas (similar to the caverns in the cave generator) etc.&lt;br /&gt;
&lt;br /&gt;
=== Make your own ideas ===&lt;br /&gt;
If you have your own idea the best thing is to join IRC wesnoth-dev at irc.freenode.net and discuss the idea with the developers there. If the developers think your idea is interesting and like the feature you can start to turn it into a full proposal. Once done discuss it again on IRC so the developers can accept your idea.&lt;br /&gt;
&lt;br /&gt;
== Information about our Project ==&lt;br /&gt;
The information we provided google with about our project can be looked up at the site [[SoC Information for Google]].&lt;br /&gt;
&lt;br /&gt;
Also see the [[DeveloperResources]] link (from the [[Project]] page).&lt;br /&gt;
&lt;br /&gt;
== People to bug on IRC ==&lt;br /&gt;
We have prepared a list of people with their &amp;quot;area of competence&amp;quot;. This is to give you an idea on which areas those people can be of help for you. Of course you should always just ask in the IRC chan, but those are the most likely ones to answer questions in the respective area. And here is the list:&lt;br /&gt;
&lt;br /&gt;
[[SoC People to bug on IRC]]&lt;br /&gt;
&lt;br /&gt;
== GSoC Student pages ==&lt;br /&gt;
&lt;br /&gt;
Please add a link to your wiki page below&lt;br /&gt;
&lt;br /&gt;
==== AI ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Velory| Velory - SoC Proposal]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_AI_Improvement_Crab| Crab - SoC Proposal - AI Improvement]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Sparksteel | Sparksteel - Improving the AI engine design]]&lt;br /&gt;
&lt;br /&gt;
==== Savegame reorganization ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Euschn | Euschn - Savegame reorganization]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_lmg| lmg - Savegame reorganization]]&lt;br /&gt;
&lt;br /&gt;
==== Extending the Multiplayer server ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_rubend | rubend - Extending the Multiplayer server]]&lt;br /&gt;
&lt;br /&gt;
==== Addon server ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Ryochan7| Ryochan7 - Addon server]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_iyonius| iyonius - Addon server]]&lt;br /&gt;
&lt;br /&gt;
==== Optimize implementation of WML for memory usage ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_res| res -  Optimize implementation of WML for memory usage ]]&lt;br /&gt;
&lt;br /&gt;
==== Implement campaign statistics reports on stats.wesnoth.org ====&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Elbin| Elbin - New campaign statistics page]]&lt;br /&gt;
&lt;br /&gt;
[[SummerOfCodeProposal_Munk| Munk - New campaign stats page]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code|*]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SoC_People_to_bug_on_IRC&amp;diff=28859</id>
		<title>SoC People to bug on IRC</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SoC_People_to_bug_on_IRC&amp;diff=28859"/>
		<updated>2009-03-19T21:15:14Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: reordering&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== People to bug on IRC ==&lt;br /&gt;
We have prepared a list of people with their &amp;quot;area of competence&amp;quot;. This is to give you an idea on which areas those people can be of help for you. Of course you should always just ask in the IRC chan, but those are the most likely ones to answer questions in the respective area. And here is the list:&lt;br /&gt;
&lt;br /&gt;
=== boucman ===&lt;br /&gt;
As our &amp;quot;patch monkey&amp;quot; he accustomed to critiquing patches of every kind. Beside this, he knows many areas of the game due to working on applying patches. He is particularly used to answering question from new coders, and doesn't mind explaining trivial stuff. He was the one who started the &amp;quot;two patches, you're in&amp;quot; policy and the ReferenceWML part of the project.&lt;br /&gt;
&lt;br /&gt;
=== Daniel Franke (dfranke) ===&lt;br /&gt;
Daniel is the devteam's most recent addition, and has been primarily concerned with security auditing.  Bug him &amp;lt;i&amp;gt;privately&amp;lt;/i&amp;gt; if you think you've found a security issue.&lt;br /&gt;
&lt;br /&gt;
=== Dave alias Sirp ===&lt;br /&gt;
Sirp started Wesnoth and is our lead developer. He is currently our C++ expert and is also the one that is working on the new Formula AI. Any questions regarding the formula AI should be directed to him.&lt;br /&gt;
&lt;br /&gt;
=== Dragonking ===&lt;br /&gt;
&lt;br /&gt;
He is one of our best Wesnoth players, and understands the various strategies well. He has also programmed much of the Wesnoth Formula AI system and understands it well.&lt;br /&gt;
&lt;br /&gt;
=== Elias Pscherning (elias) ===&lt;br /&gt;
He wrote the original version of campgen and as such will know a lot about what is needed to to make such an editor work correctly. The work on a scenario editor might be based upon campgen and as such his knowledge will be really helpful.&lt;br /&gt;
&lt;br /&gt;
=== Eric S. Raymond (ESR) ===&lt;br /&gt;
ESR is our project toolsmith; he has written several tools that semi-automate various aspects of WML maintenance.  While most of our developers/designers concentrate on either the C++ core or WML but not both, he has a balanced understanding of both levels and may be helpful in helping students develop a grasp of the overall architecture.  Finally, he did the last overhaul of the Wesnoth UI and understands UI design principles; he is well-equipped to guide students working in that area.&lt;br /&gt;
&lt;br /&gt;
=== ilor ===&lt;br /&gt;
2008 GSoC student, worked on and maintains the new map editor in Wesnoth 1.5/1.6. Has some fairly recent experience with getting &amp;quot;in&amp;quot; the Wesnoth codebase.&lt;br /&gt;
&lt;br /&gt;
=== Karol Nowak (grzywacz) ===&lt;br /&gt;
Two years he participated at GSoC as a student, so he will understand the situation of GSoC students. Beside this he is our top expert on Wesnoth for embedded devices as he worked on the gp2x support.&lt;br /&gt;
&lt;br /&gt;
=== loonycyborg ===&lt;br /&gt;
Maintainer of Wesnoth's SCons build system and windows packager. Might also help out with other buildsystems.&lt;br /&gt;
&lt;br /&gt;
=== Mordante ===&lt;br /&gt;
Many of the possible projects involve the code for which he is an area expert. Also, many of the possible projects currently listed on the ideas page require GUI parts to work. Mordante is currently busy rewriting the old gui engine, he will be our expert there as well as already being our area expert for the terrain engine.&lt;br /&gt;
&lt;br /&gt;
=== Nils Kneuper (Ivanovic) ===&lt;br /&gt;
He is doing nothing special, he just does some &amp;quot;administrative work&amp;quot; like packaging fresh tarballs when it is time for them and works on setting up any kind of deadlines and timetables related to releasing. He has administrative powers in most areas, no matter if website, forum or IRC. Beside this he uploads translation updates, tries to communicate with the translation teams when it is required and translates a little bit himself every now and then. But in general he is not a real expert in anything, just has a look at things that come up and redirects people to the correct contacts.&lt;br /&gt;
&lt;br /&gt;
=== Noy ===&lt;br /&gt;
Noy is an oddity among developers; he's got no coding skills whatsoever and possesses a limited understanding of computers, which is illustrated by his difficulty operating a Mac. Instead, Noy makes his contribution in gameplay and multiplayer design, drawing upon his background in social sciences research, military strategy and playing games online, to understand the effects of development on the playing community behavior. Along with Soliton, Noy is a useful conduit to discuss any issues in this area; just don't ask him about revising the level of randomness in the game.&lt;br /&gt;
&lt;br /&gt;
=== Noyga ===&lt;br /&gt;
Another versatile developer, on the C++ side he doesn't concentrate on a particular area, did some tweaks to improve translations in some languages (like enabling the female forms for names in various place) but know quite well the C++ side of units, abilities and WML. On the WML side he's an expert.&lt;br /&gt;
&lt;br /&gt;
=== Sapient ===&lt;br /&gt;
This developer started working on the GUI and widgets, but recently he focused more on improving the internal mechanics of the WML engine such as variable look-ups and filtering. Sapient is not very active anymore but he does come one IRC in the evenings (U.S.A.). He has touched-up many areas of the code in small ways over time, thus he has a good general knowledge of the C++ code and also has worked a little on some python maintenance scripts. He keeps an eye on the quality of incoming C++... especially if you plan on making any changes to GUI or WML, Sapient will be reviewing it closely and with a critical eye.&lt;br /&gt;
&lt;br /&gt;
=== Shadow Master/ShikadiLord ===&lt;br /&gt;
He joined the development team very recently, but has enough knowledge to help newcomers with trivial questions about the code and/or the C++ language. His primary focuses are the various WML handlers, such as game events code. His knowledge of the WML language itself is also enough to answer most questions and solve most problems, but only if they are not related to multiplayer games. He also has some basic knowledge of the autotools machinery we use to configure Wesnoth for foreign computers.&lt;br /&gt;
&lt;br /&gt;
=== Soliton ===&lt;br /&gt;
He knows our MP server setup best. Beside this he has already done a lot of work on the MP server himself. So he probably has most knowledge about it and, being one of our MP-developers, might provide important help from the perspective of the MP player community and what is needed there.&lt;br /&gt;
&lt;br /&gt;
=== YogiHH or Piotr Cychowski (cycholka) ===&lt;br /&gt;
Since they are the two developers who know most about building under Windows, they will probably be really helpful. Either if the student comes from the Windows side, or to help test resulting work to make sure that it does work on Windows and, for the case that it does not, to show them where problems are.&lt;br /&gt;
&lt;br /&gt;
=== zookeeper or Mythological or Rhuvaen ===&lt;br /&gt;
As our leading WML experts those are to be contacted when it comes to anything related WML problems since they know this stuff best. They do maintain most of the campaigns and improve them whenever they have a good idea for changes.&lt;br /&gt;
&lt;br /&gt;
=== See also ===&lt;br /&gt;
[[SummerOfCodeIdeas|Summer of Code Ideas]] - The root where all information regarding SoC is (or better should be) linked from.&lt;br /&gt;
&lt;br /&gt;
[[Category:Summer of Code]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=28803</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=28803"/>
		<updated>2009-03-19T00:31:35Z</updated>

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

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

		<summary type="html">&lt;p&gt;Dragonking: /* 'shortest_path' function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Syntax used to explain functions usage in this document is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = &amp;lt;function name&amp;gt;( &amp;lt;comma-separated list of parameters&amp;gt; [, &amp;lt;comma-separated list of optional parameters] )&lt;br /&gt;
&lt;br /&gt;
Function may return &amp;lt;result&amp;gt; as:&lt;br /&gt;
* &amp;lt;variable&amp;gt; - any of the supported variable types&lt;br /&gt;
* &amp;lt;boolean&amp;gt; - false ( 0 or null ) or true ( 1 )&lt;br /&gt;
* &amp;lt;unit&amp;gt; - unit&lt;br /&gt;
* &amp;lt;location&amp;gt; - place on a gamemap&lt;br /&gt;
* &amp;lt;action&amp;gt; - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.&lt;br /&gt;
* &amp;lt;result&amp;gt; - any of the above&lt;br /&gt;
&lt;br /&gt;
Also function may return only single argument, or be able to return a whole list or a map.&lt;br /&gt;
&lt;br /&gt;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also [http://www.wesnoth.org/wiki/FormulaAI#Custom_Functions define your own functions].&lt;br /&gt;
&lt;br /&gt;
=core functions=&lt;br /&gt;
&lt;br /&gt;
=== 'abs' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = abs( &amp;lt;input number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns absolute value of an &amp;lt;input number&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 abs( -5 )&lt;br /&gt;
&lt;br /&gt;
will return 5.&lt;br /&gt;
&lt;br /&gt;
=== 'choose' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates &amp;lt;formula&amp;gt; for each item in the &amp;lt;input&amp;gt; (which can be a list ro a map). Will evaluate to the one item which &amp;lt;formula&amp;gt; gave the highest value.  For example:&lt;br /&gt;
&lt;br /&gt;
 choose(my_units, level)&lt;br /&gt;
&lt;br /&gt;
gives back the unit with the highest level.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The implicit input when evaluating a mapping/filtering function's &amp;lt;formula&amp;gt; component will be that specific item under evaluation (in this example one of &amp;quot;my_units&amp;quot;), and it can be explicitly referenced as 'self' when necessary. Optional &amp;lt;string&amp;gt; paremater indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'.&lt;br /&gt;
&lt;br /&gt;
When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:&lt;br /&gt;
&lt;br /&gt;
 choose( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value )&lt;br /&gt;
&lt;br /&gt;
Will return a key-value pair &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== 'dir' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of names&amp;gt; = dir ( &amp;lt;input object&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function return list with all names of &amp;lt;input object's&amp;gt; members. For example:&lt;br /&gt;
&lt;br /&gt;
 dir( my_leader )&lt;br /&gt;
&lt;br /&gt;
will result in output:&lt;br /&gt;
&lt;br /&gt;
 [ 'x', 'y', 'loc', 'id', 'leader', 'hitpoints', 'max_hitpoints', 'experience', 'max_experience', 'level',&lt;br /&gt;
 'total_movement', 'movement_left', 'side', 'is_enemy', 'is_mine']&lt;br /&gt;
&lt;br /&gt;
This command is useful in formula command line, to get information about members of different type of data. To get list of members of the ai, type:&lt;br /&gt;
&lt;br /&gt;
 dir( self )&lt;br /&gt;
&lt;br /&gt;
=== 'filter' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = filter( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map). Will evaluate to a &amp;lt;result&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(my_units, hitpoints &amp;lt; max_hitpoints)&lt;br /&gt;
&lt;br /&gt;
will return all of your units which have less than maximum hitpoints. For instance this could be used if looking for candidates for healing.&lt;br /&gt;
&lt;br /&gt;
=== 'find' function ===&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;result&amp;gt; = find( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt;,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map) and will return a first item for which &amp;lt;formula&amp;gt; was true. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(units, id = 'Elvish Archer' )&lt;br /&gt;
&lt;br /&gt;
will return first unit with id equal to 'Elvish Archer'.&lt;br /&gt;
&lt;br /&gt;
=== 'head' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;variable&amp;gt; = head( &amp;lt;list of variables&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Head returns first item from the &amp;lt;list of variables&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 head( [ 5, 7, 9] )            #returns 5&lt;br /&gt;
 head( [ 'Orc', 'Human' ] )    #returns 'Orc'&lt;br /&gt;
&lt;br /&gt;
=== 'if' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = if( &amp;lt;condition&amp;gt; , &amp;lt;if true&amp;gt; , &amp;lt;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;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
=== '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;
&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
== 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;
=== 'shortest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = shortest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; [, &amp;lt;unit location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
When only 2 parameters are specified, function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;. If optional 3rd parameter is specified, it returns list with all locations that unit standing on &amp;lt;unit location&amp;gt; would need to move through to get from &amp;lt;location A&amp;gt; to &amp;lt;location B&amp;gt;. This function takes into account zone of control of enemy units.&lt;br /&gt;
&lt;br /&gt;
=== 'simplest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = simplest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; [, &amp;lt;unit location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
When only 2 parameters are specified, function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;. If optional 3rd parameter is specified, it returns list with all locations that unit standing on &amp;lt;unit location&amp;gt; would need to move through to get from &amp;lt;location A&amp;gt; to &amp;lt;location B&amp;gt;. This function does not take into account zone of control or enemy units.&lt;br /&gt;
&lt;br /&gt;
=== 'unit_at' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = unit_at( &amp;lt;location&amp;gt; ) &lt;br /&gt;
&lt;br /&gt;
This function takes only one argument - location, and returns unit if there is one standing in that location, or null otherwise. Example of usage:&lt;br /&gt;
&lt;br /&gt;
 unit_at( loc( 4, 4) )&lt;br /&gt;
&lt;br /&gt;
=== 'nearest_keep' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;keep location&amp;gt; = nearest_keep( &amp;lt;input location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns location of nearest keep to the specified &amp;lt;input location&amp;gt;, or null if there is no keep on the map.&lt;br /&gt;
&lt;br /&gt;
=== 'unit_moves' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;locations list&amp;gt; = unit_moves( &amp;lt;unit location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns list of all possible locations which unit standing at &amp;lt;unit location&amp;gt; can reach. If unit can't move, or there is no unit standing at given location, empty list is returned.&lt;br /&gt;
&lt;br /&gt;
=== 'units_can_reach' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;units list&amp;gt; = units_can_reach( &amp;lt;possible moves list&amp;gt;, &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function takes as an input list of possible moves ( ai.my_moves for units that belong to AI, or ai.enemy_moves for units that belong to the opponent ) and checks which units from that list can reach &amp;lt;location&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Recruitment ==&lt;br /&gt;
&lt;br /&gt;
=== 'recruit' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = recruit( &amp;lt;unit name&amp;gt; [, &amp;lt;location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function results in recruting a unit specifed by &amp;lt;unit name&amp;gt; at first free castle hex, or at given &amp;lt;location&amp;gt;. Function:&lt;br /&gt;
&lt;br /&gt;
 recruit('Footpad', loc(3,3) ) &lt;br /&gt;
&lt;br /&gt;
will result in recruting Footpad at castle hex with coordinates 3,3.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=28466</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=28466"/>
		<updated>2009-03-05T23:23:19Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* 'shortest_path' function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Syntax used to explain functions usage in this document is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = &amp;lt;function name&amp;gt;( &amp;lt;comma-separated list of parameters&amp;gt; [, &amp;lt;comma-separated list of optional parameters] )&lt;br /&gt;
&lt;br /&gt;
Function may return &amp;lt;result&amp;gt; as:&lt;br /&gt;
* &amp;lt;variable&amp;gt; - any of the supported variable types&lt;br /&gt;
* &amp;lt;boolean&amp;gt; - false ( 0 or null ) or true ( 1 )&lt;br /&gt;
* &amp;lt;unit&amp;gt; - unit&lt;br /&gt;
* &amp;lt;location&amp;gt; - place on a gamemap&lt;br /&gt;
* &amp;lt;action&amp;gt; - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.&lt;br /&gt;
* &amp;lt;result&amp;gt; - any of the above&lt;br /&gt;
&lt;br /&gt;
Also function may return only single argument, or be able to return a whole list or a map.&lt;br /&gt;
&lt;br /&gt;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also [http://www.wesnoth.org/wiki/FormulaAI#Custom_Functions define your own functions].&lt;br /&gt;
&lt;br /&gt;
=core functions=&lt;br /&gt;
&lt;br /&gt;
=== 'abs' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = abs( &amp;lt;input number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns absolute value of an &amp;lt;input number&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 abs( -5 )&lt;br /&gt;
&lt;br /&gt;
will return 5.&lt;br /&gt;
&lt;br /&gt;
=== 'choose' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates &amp;lt;formula&amp;gt; for each item in the &amp;lt;input&amp;gt; (which can be a list ro a map). Will evaluate to the one item which &amp;lt;formula&amp;gt; gave the highest value.  For example:&lt;br /&gt;
&lt;br /&gt;
 choose(my_units, level)&lt;br /&gt;
&lt;br /&gt;
gives back the unit with the highest level.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The implicit input when evaluating a mapping/filtering function's &amp;lt;formula&amp;gt; component will be that specific item under evaluation (in this example one of &amp;quot;my_units&amp;quot;), and it can be explicitly referenced as 'self' when necessary. Optional &amp;lt;string&amp;gt; paremater indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'.&lt;br /&gt;
&lt;br /&gt;
When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:&lt;br /&gt;
&lt;br /&gt;
 choose( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value )&lt;br /&gt;
&lt;br /&gt;
Will return a key-value pair &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== 'dir' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of names&amp;gt; = dir ( &amp;lt;input object&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function return list with all names of &amp;lt;input object's&amp;gt; members. For example:&lt;br /&gt;
&lt;br /&gt;
 dir( my_leader )&lt;br /&gt;
&lt;br /&gt;
will result in output:&lt;br /&gt;
&lt;br /&gt;
 [ 'x', 'y', 'loc', 'id', 'leader', 'hitpoints', 'max_hitpoints', 'experience', 'max_experience', 'level',&lt;br /&gt;
 'total_movement', 'movement_left', 'side', 'is_enemy', 'is_mine']&lt;br /&gt;
&lt;br /&gt;
This command is useful in formula command line, to get information about members of different type of data. To get list of members of the ai, type:&lt;br /&gt;
&lt;br /&gt;
 dir( self )&lt;br /&gt;
&lt;br /&gt;
=== 'filter' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = filter( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map). Will evaluate to a &amp;lt;result&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(my_units, hitpoints &amp;lt; max_hitpoints)&lt;br /&gt;
&lt;br /&gt;
will return all of your units which have less than maximum hitpoints. For instance this could be used if looking for candidates for healing.&lt;br /&gt;
&lt;br /&gt;
=== 'find' function ===&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;result&amp;gt; = find( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt;,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map) and will return a first item for which &amp;lt;formula&amp;gt; was true. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(units, id = 'Elvish Archer' )&lt;br /&gt;
&lt;br /&gt;
will return first unit with id equal to 'Elvish Archer'.&lt;br /&gt;
&lt;br /&gt;
=== 'head' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;variable&amp;gt; = head( &amp;lt;list of variables&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Head returns first item from the &amp;lt;list of variables&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 head( [ 5, 7, 9] )            #returns 5&lt;br /&gt;
 head( [ 'Orc', 'Human' ] )    #returns 'Orc'&lt;br /&gt;
&lt;br /&gt;
=== 'if' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = if( &amp;lt;condition&amp;gt; , &amp;lt;if true&amp;gt; , &amp;lt;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;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
=== '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;
&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
== 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;
=== 'shortest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = shortest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; [, &amp;lt;unit location&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
When only 2 parameters are specified, function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;. If optional 3rd paremeter is specified, it returns list with all locations that unit standing on &amp;lt;unit location&amp;gt; would need to move through to get from &amp;lt;location A&amp;gt; to &amp;lt;location B&amp;gt;. This function takes into account zone of control.&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;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=28432</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=28432"/>
		<updated>2009-03-01T22:48:16Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Unit Formulas */&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;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''enemy_units'' all units that are enemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''enemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(*ai)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 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, me.vars.guard_loc) )&lt;br /&gt;
  where attack = choose(filter(attacks, units = [me.loc] and distance_between(me.vars.guard_loc, target) &amp;lt;= me.vars.guard_radius and unit_at(target).side=me.vars.hostile_side-1 ), avg_damage_inflicted)&amp;quot;&lt;br /&gt;
  [ai_vars]&lt;br /&gt;
    guard_radius=3&lt;br /&gt;
    guard_loc=&amp;quot;loc(8,5)&amp;quot;&lt;br /&gt;
    hostile_side=1&lt;br /&gt;
  [/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 only opponent from side 1 (value specified by hostile_side variable) which is 3 hexes (guard_radius) or less from guard_loc.&lt;br /&gt;
&lt;br /&gt;
Types of variables that are supported:&lt;br /&gt;
*number:&lt;br /&gt;
 variable=3&lt;br /&gt;
*text (important: note the ' ' within &amp;quot; &amp;quot;):&lt;br /&gt;
 name=&amp;quot;'I am variable'&amp;quot;&lt;br /&gt;
*list:&lt;br /&gt;
 number_list=[ 1, 2, 3]&lt;br /&gt;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&lt;br /&gt;
&lt;br /&gt;
You can easily split your formulas between different files and include them when necessary. For example:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
  formula={my_unit_formula.fai}&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Will look for unit formula in the my_unit_formula.fai file.&lt;br /&gt;
&lt;br /&gt;
Although it is not mandatory, we advocate to use following syntax in your fai files:&lt;br /&gt;
&lt;br /&gt;
 faifile '&amp;lt;filename&amp;gt;'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
This makes formula system know which file it is working with now, and gives you improved error reporting, which is often really helpful. Valid syntax for my_unit_formula.fai would be:&lt;br /&gt;
&lt;br /&gt;
 faifile 'my_unit_formula.fai'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
== Tool Support ==&lt;br /&gt;
&lt;br /&gt;
=== ctags ===&lt;br /&gt;
&lt;br /&gt;
For some rudimentary support for exuberant ctags, add the following to .ctags (or create the file if it doesn't exist):&lt;br /&gt;
&lt;br /&gt;
 --langdef=formulaai&lt;br /&gt;
 --langmap=formulaai:.fai&lt;br /&gt;
 --regex-formulaai=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/&lt;br /&gt;
&lt;br /&gt;
This is especially nice when used with an editor or plugin with ctags support, such as Taglist for Vim.&lt;br /&gt;
&lt;br /&gt;
=== Vim ===&lt;br /&gt;
&lt;br /&gt;
====Syntax Highlighting====&lt;br /&gt;
&lt;br /&gt;
Follow these steps to enjoy vim syntax highlighting support for Formula AI.&lt;br /&gt;
&lt;br /&gt;
# Grab the Formula AI vim syntax file, [http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/tools/vim/formulaai.vim formulaai.vim].&lt;br /&gt;
# Copy formulaai.vim to .vim/syntax &lt;br /&gt;
# Add the following to .vimrc :&lt;br /&gt;
 autocmd! BufRead,BufNewFile *.fai setfiletype formulaai&lt;br /&gt;
&lt;br /&gt;
====Taglist Support====&lt;br /&gt;
&lt;br /&gt;
First you will need the very nice [http://www.vim.org/scripts/script.php?script_id=273 taglist plugin].  Follow the link for downloads and install directions if you don't already have it installed.&lt;br /&gt;
&lt;br /&gt;
Next, you'll need Formula AI support for exuberant ctags, follow the instructions in the [[#ctags|ctags]] section.  &lt;br /&gt;
&lt;br /&gt;
Once you have all that, simply add the following line to your .vimrc:&lt;br /&gt;
 &lt;br /&gt;
 let tlist_formulaai_settings = 'formulaai;d:definition'&lt;br /&gt;
&lt;br /&gt;
To test it all out, open a Formula AI script file and enter the command &lt;br /&gt;
 :Tlist&lt;br /&gt;
&lt;br /&gt;
You should now have some nice highlighting and be able to easily navigate through formula, enjoy!&lt;br /&gt;
  &lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=28415</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=28415"/>
		<updated>2009-03-01T12:35:30Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* 'filter' function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Syntax used to explain functions usage in this document is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = &amp;lt;function name&amp;gt;( &amp;lt;comma-separated list of parameters&amp;gt; [, &amp;lt;comma-separated list of optional parameters] )&lt;br /&gt;
&lt;br /&gt;
Function may return &amp;lt;result&amp;gt; as:&lt;br /&gt;
* &amp;lt;variable&amp;gt; - any of the supported variable types&lt;br /&gt;
* &amp;lt;boolean&amp;gt; - false ( 0 or null ) or true ( 1 )&lt;br /&gt;
* &amp;lt;unit&amp;gt; - unit&lt;br /&gt;
* &amp;lt;location&amp;gt; - place on a gamemap&lt;br /&gt;
* &amp;lt;action&amp;gt; - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.&lt;br /&gt;
* &amp;lt;result&amp;gt; - any of the above&lt;br /&gt;
&lt;br /&gt;
Also function may return only single argument, or be able to return a whole list or a map.&lt;br /&gt;
&lt;br /&gt;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also [http://www.wesnoth.org/wiki/FormulaAI#Custom_Functions define your own functions].&lt;br /&gt;
&lt;br /&gt;
=core functions=&lt;br /&gt;
&lt;br /&gt;
=== 'abs' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = abs( &amp;lt;input number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns absolute value of an &amp;lt;input number&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 abs( -5 )&lt;br /&gt;
&lt;br /&gt;
will return 5.&lt;br /&gt;
&lt;br /&gt;
=== 'choose' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates &amp;lt;formula&amp;gt; for each item in the &amp;lt;input&amp;gt; (which can be a list ro a map). Will evaluate to the one item which &amp;lt;formula&amp;gt; gave the highest value.  For example:&lt;br /&gt;
&lt;br /&gt;
 choose(my_units, level)&lt;br /&gt;
&lt;br /&gt;
gives back the unit with the highest level.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The implicit input when evaluating a mapping/filtering function's &amp;lt;formula&amp;gt; component will be that specific item under evaluation (in this example one of &amp;quot;my_units&amp;quot;), and it can be explicitly referenced as 'self' when necessary. Optional &amp;lt;string&amp;gt; paremater indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'.&lt;br /&gt;
&lt;br /&gt;
When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:&lt;br /&gt;
&lt;br /&gt;
 choose( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value )&lt;br /&gt;
&lt;br /&gt;
Will return a key-value pair &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== 'dir' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of names&amp;gt; = dir ( &amp;lt;input object&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function return list with all names of &amp;lt;input object's&amp;gt; members. For example:&lt;br /&gt;
&lt;br /&gt;
 dir( my_leader )&lt;br /&gt;
&lt;br /&gt;
will result in output:&lt;br /&gt;
&lt;br /&gt;
 [ 'x', 'y', 'loc', 'id', 'leader', 'hitpoints', 'max_hitpoints', 'experience', 'max_experience', 'level',&lt;br /&gt;
 'total_movement', 'movement_left', 'side', 'is_enemy', 'is_mine']&lt;br /&gt;
&lt;br /&gt;
This command is useful in formula command line, to get information about members of different type of data. To get list of members of the ai, type:&lt;br /&gt;
&lt;br /&gt;
 dir( self )&lt;br /&gt;
&lt;br /&gt;
=== 'filter' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = filter( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map). Will evaluate to a &amp;lt;result&amp;gt; which only contains items the &amp;lt;formula&amp;gt; was true for. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(my_units, hitpoints &amp;lt; max_hitpoints)&lt;br /&gt;
&lt;br /&gt;
will return all of your units which have less than maximum hitpoints. For instance this could be used if looking for candidates for healing.&lt;br /&gt;
&lt;br /&gt;
=== 'find' function ===&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;result&amp;gt; = find( &amp;lt;input&amp;gt;, [ &amp;lt;string&amp;gt;,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function will run &amp;lt;formula&amp;gt; on each item in the &amp;lt;input&amp;gt; (which can be a list or a map) and will return a first item for which &amp;lt;formula&amp;gt; was true. Optional &amp;lt;string&amp;gt; indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'. For example:&lt;br /&gt;
&lt;br /&gt;
 filter(units, id = 'Elvish Archer' )&lt;br /&gt;
&lt;br /&gt;
will return first unit with id equal to 'Elvish Archer'.&lt;br /&gt;
&lt;br /&gt;
=== 'head' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;variable&amp;gt; = head( &amp;lt;list of variables&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Head returns first item from the &amp;lt;list of variables&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 head( [ 5, 7, 9] )            #returns 5&lt;br /&gt;
 head( [ 'Orc', 'Human' ] )    #returns 'Orc'&lt;br /&gt;
&lt;br /&gt;
=== 'if' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = if( &amp;lt;condition&amp;gt; , &amp;lt;if true&amp;gt; , &amp;lt;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;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
=== '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;
&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
== 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;
=== 'shortest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = shortest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;.&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;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=27077</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=27077"/>
		<updated>2008-10-12T20:49:09Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* 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 &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== '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;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
=== '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;
&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
== 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;
=== 'shortest_path' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list of locations&amp;gt; = shortest_path( &amp;lt;location A&amp;gt; , &amp;lt;location B&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns list with all locations that unit standing on &amp;lt;location A&amp;gt; has to move through to get to &amp;lt;location B&amp;gt;.&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;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=27075</id>
		<title>FormulaAI Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI_Functions&amp;diff=27075"/>
		<updated>2008-10-12T13:12:05Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* 'move' function */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Overview =&lt;br /&gt;
&lt;br /&gt;
Syntax used to explain functions usage in this document is:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = &amp;lt;function name&amp;gt;( &amp;lt;comma-separated list of parameters&amp;gt; [, &amp;lt;comma-separated list of optional parameters] )&lt;br /&gt;
&lt;br /&gt;
Function may return &amp;lt;result&amp;gt; as:&lt;br /&gt;
* &amp;lt;variable&amp;gt; - any of the supported variable types&lt;br /&gt;
* &amp;lt;boolean&amp;gt; - false ( 0 or null ) or true ( 1 )&lt;br /&gt;
* &amp;lt;unit&amp;gt; - unit&lt;br /&gt;
* &amp;lt;location&amp;gt; - place on a gamemap&lt;br /&gt;
* &amp;lt;action&amp;gt; - object, which, if later passed to 'move= ' as the result of formula evaluation, make the AI perform a desired action.&lt;br /&gt;
* &amp;lt;result&amp;gt; - any of the above&lt;br /&gt;
&lt;br /&gt;
Also function may return only single argument, or be able to return a whole list or a map.&lt;br /&gt;
&lt;br /&gt;
There are a wide variety of functions which can be used to accomplish many different tasks. You can also [http://www.wesnoth.org/wiki/FormulaAI#Custom_Functions define your own functions].&lt;br /&gt;
&lt;br /&gt;
=core functions=&lt;br /&gt;
&lt;br /&gt;
=== 'abs' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = abs( &amp;lt;input number&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns absolute value of an &amp;lt;input number&amp;gt;, for example&lt;br /&gt;
&lt;br /&gt;
 abs( -5 )&lt;br /&gt;
&lt;br /&gt;
will return 5.&lt;br /&gt;
&lt;br /&gt;
=== 'choose' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result&amp;gt; = choose( &amp;lt;input list&amp;gt; , [ &amp;lt;string&amp;gt; ,] &amp;lt;formula&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function evaluates &amp;lt;formula&amp;gt; for each item in the &amp;lt;input&amp;gt; (which can be a list ro a map). Will evaluate to the one item which &amp;lt;formula&amp;gt; gave the highest value.  For example:&lt;br /&gt;
&lt;br /&gt;
 choose(my_units, level)&lt;br /&gt;
&lt;br /&gt;
gives back the unit with the highest level.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The implicit input when evaluating a mapping/filtering function's &amp;lt;formula&amp;gt; component will be that specific item under evaluation (in this example one of &amp;quot;my_units&amp;quot;), and it can be explicitly referenced as 'self' when necessary. Optional &amp;lt;string&amp;gt; paremater indicates what word used in &amp;lt;formula&amp;gt; is equivalent to 'self'.&lt;br /&gt;
&lt;br /&gt;
When evaluating the map data type, we can reference to each key by 'key' and each value by 'value'. For example:&lt;br /&gt;
&lt;br /&gt;
 choose( [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ], value )&lt;br /&gt;
&lt;br /&gt;
Will return a key-value pair &lt;br /&gt;
&lt;br /&gt;
 { key-&amp;gt;'dwarf', value-&amp;gt;20 }&lt;br /&gt;
&lt;br /&gt;
=== 'contains_string' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;boolean&amp;gt; = contains_string( &amp;lt;string&amp;gt;, &amp;lt;key&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Returns 1 if &amp;lt;key&amp;gt; can be found withing &amp;lt;string&amp;gt;, 0 otherwise&lt;br /&gt;
&lt;br /&gt;
 contains_string( 'Testing', 'ing' )&lt;br /&gt;
&lt;br /&gt;
returns&lt;br /&gt;
&lt;br /&gt;
 1&lt;br /&gt;
&lt;br /&gt;
=== 'debug_print' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;formula&amp;gt; = debug_print( [ &amp;lt;optional string&amp;gt; ,] &amp;lt;formula&amp;gt;  )&lt;br /&gt;
&lt;br /&gt;
This function can be used for debging the formulas. It takes formula, writes output to the console and return it unchanged. For example:&lt;br /&gt;
&lt;br /&gt;
 debug_print( [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will result in printing to the console&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
Return value is the same.&lt;br /&gt;
&lt;br /&gt;
We can specify optional parameter that helps to distinguish what each of debug_print outputs is (useful if we have multiple debug_print functions):&lt;br /&gt;
&lt;br /&gt;
 debug_print( 'My array: ', [ 1, 2, 3 ] )&lt;br /&gt;
&lt;br /&gt;
will write in the console:&lt;br /&gt;
&lt;br /&gt;
 My array: [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
And return&lt;br /&gt;
&lt;br /&gt;
 [ 1, 2, 3 ]&lt;br /&gt;
&lt;br /&gt;
=== '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;
=== 'tolist' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;list&amp;gt; = tolist( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function takes map and return a list of key-value pairs objects. For example:&lt;br /&gt;
&lt;br /&gt;
 tolist( [ 'Elf' -&amp;gt; 10, 'Dwarf' -&amp;gt; 20] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [{key-&amp;gt;'Elf',value-&amp;gt;10}, {key-&amp;gt;'Dwarf',value-&amp;gt;20}]&lt;br /&gt;
&lt;br /&gt;
=== 'tomap' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;map&amp;gt; = tomap( &amp;lt;input list A&amp;gt; [, &amp;lt;input list B&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
This function takes one or two lists as input and returns a map. If only one list is specified, then function will evaluate this list, count how many simmilar elements are withing this list, and return a map with keys being these elements, and values being a number representing of them list contains, For example:&lt;br /&gt;
&lt;br /&gt;
 tomap( ['elf', 'dwarf', 'elf', 'elf', 'human', 'human' ] )&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 3, 'dwarf' -&amp;gt; 1, 'human' -&amp;gt; 2 ]&lt;br /&gt;
&lt;br /&gt;
If two lists are specified, then elements of the first one will be used as a keys, and elements of second one as a values, when creating a output map. Note that these input lists must be of the same length.&lt;br /&gt;
&lt;br /&gt;
 tomap( [ 'elf', 'dwarf' ], [10, 20] )&lt;br /&gt;
&lt;br /&gt;
will result in:&lt;br /&gt;
&lt;br /&gt;
 [ 'elf' -&amp;gt; 10, 'dwarf' -&amp;gt; 20 ]&lt;br /&gt;
&lt;br /&gt;
=== 'values' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;result list&amp;gt; = values( &amp;lt;input map&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Extract values assigned to keys from a &amp;lt;input map&amp;gt; and return them as a &amp;lt;result list&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 values( [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ] )&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 [ 50, 60 ]&lt;br /&gt;
&lt;br /&gt;
= AI specific functions =&lt;br /&gt;
&lt;br /&gt;
== Base functions ==&lt;br /&gt;
&lt;br /&gt;
=== 'attack' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = attack( &amp;lt;attacker's position&amp;gt;, &amp;lt;destination&amp;gt;, &amp;lt;attack location&amp;gt; [,  &amp;lt;weapon&amp;gt; ] )&lt;br /&gt;
&lt;br /&gt;
The first three parameters are locations. At the begining, unit which is standing at &amp;lt;attacker's position&amp;gt; is moved to &amp;lt;destination&amp;gt; place. Then, from that place unit is attacking unit which stands in place marked by &amp;lt;attack location&amp;gt;. Fourth optional parameter is number, and indicates which weapon attacker should use - if not specified, best possible weapon is chosed automatically.&lt;br /&gt;
&lt;br /&gt;
=== 'fallback' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = fallback( [&amp;lt;name&amp;gt;] )&lt;br /&gt;
&lt;br /&gt;
This function allows to chose different AI or to human player, who will take control over side untill the end of current turn. For example:&lt;br /&gt;
&lt;br /&gt;
 fallback()&lt;br /&gt;
&lt;br /&gt;
will transfer control to the default C++ AI. You can specify a name of different AI (for example python_ai) to transfer control to it. If you want to give control to the player, use:&lt;br /&gt;
&lt;br /&gt;
 fallback( 'human' )&lt;br /&gt;
&lt;br /&gt;
=== 'get_unit_type' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;unit&amp;gt; = get_unit_type( &amp;lt;unit name&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns unit_type object of desired type, for example:&lt;br /&gt;
&lt;br /&gt;
 get_unit_type( 'Mage' )&lt;br /&gt;
&lt;br /&gt;
will result in returning unit_type of a Mage.&lt;br /&gt;
&lt;br /&gt;
=== 'move' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt; and sets unit movement to 0. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north. Leader's movement points will be reset to 0.&lt;br /&gt;
&lt;br /&gt;
=== 'move_partial' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;action&amp;gt; = move_partial( &amp;lt;source&amp;gt; , &amp;lt;destination&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Moves unit from &amp;lt;source&amp;gt; to &amp;lt;destination&amp;gt;. For example unit formula like:&lt;br /&gt;
&lt;br /&gt;
 move(my_leader.loc, loc(my_leader.loc.x, my_leader.loc.y - 1) )&lt;br /&gt;
&lt;br /&gt;
will make leader move one hex north.&lt;br /&gt;
&lt;br /&gt;
=== '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;
&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 'max_possible_damage_with_retaliation' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = max_possible_damage_with_retaliation( &amp;lt;attacking unit&amp;gt; , &amp;lt;defending unit&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
Function returns an array:&lt;br /&gt;
&lt;br /&gt;
 [ &amp;lt;attacker_melee&amp;gt;, &amp;lt;attacker_ranged&amp;gt;, &amp;lt;defender_melee&amp;gt;, &amp;lt;defender_ranged&amp;gt; ] &lt;br /&gt;
&lt;br /&gt;
in which first two elements are highest possible damage that &amp;lt;attacking unit&amp;gt; can inflict to &amp;lt;defending unit&amp;gt; with melee and ranged attacks, and latter two elements are highest possible damage that &amp;lt;defending unit&amp;gt; can inflict to &amp;lt;attacking unit&amp;gt; also with melee and ranged attacks.&lt;br /&gt;
&lt;br /&gt;
=== 'movement_cost' function ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;number&amp;gt; = movement_cost( &amp;lt;unit&amp;gt; , &amp;lt;location&amp;gt; )&lt;br /&gt;
&lt;br /&gt;
This function returns movememtn cost of given &amp;lt;unit&amp;gt; in a specific &amp;lt;location&amp;gt;. For example:&lt;br /&gt;
&lt;br /&gt;
 movement_cost( my_leader , my_leader.loc )&lt;br /&gt;
&lt;br /&gt;
shows what movement cost your leader has in a place he is currently standing on.&lt;br /&gt;
&lt;br /&gt;
== 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;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Create]]&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26967</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26967"/>
		<updated>2008-10-05T22:52:14Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Unit Formulas */&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;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''enemy_units'' all units that are enemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''enemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(*ai)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 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 and unit_at(target).side=me.vars.hostile_side-1 ), 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;
    hostile_side=1&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 only opponent from side 1 (value specified by hostile_side variable) which is 3 hexes (guard_radius) or less from guard_loc.&lt;br /&gt;
&lt;br /&gt;
Types of variables that are supported:&lt;br /&gt;
*number:&lt;br /&gt;
 variable=3&lt;br /&gt;
*text (important: note the ' ' within &amp;quot; &amp;quot;):&lt;br /&gt;
 name=&amp;quot;'I am variable'&amp;quot;&lt;br /&gt;
*list:&lt;br /&gt;
 number_list=[ 1, 2, 3]&lt;br /&gt;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&lt;br /&gt;
&lt;br /&gt;
You can easily split your formulas between different files and include them when necessary. For example:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
  formula={my_unit_formula.fai}&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Will look for unit formula in the my_unit_formula.fai file.&lt;br /&gt;
&lt;br /&gt;
Although it is not mandatory, we advocate to use following syntax in your fai files:&lt;br /&gt;
&lt;br /&gt;
 faifile '&amp;lt;filename&amp;gt;'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
This makes formula system know which file it is working with now, and gives you improved error reporting, which is often really helpful. Valid syntax for my_unit_formula.fai would be:&lt;br /&gt;
&lt;br /&gt;
 faifile 'my_unit_formula.fai'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
== Tool Support ==&lt;br /&gt;
&lt;br /&gt;
=== ctags ===&lt;br /&gt;
&lt;br /&gt;
For some rudimentary support for exuberant ctags, add the following to .ctags (or create the file if it doesn't exist):&lt;br /&gt;
&lt;br /&gt;
 --langdef=formulaai&lt;br /&gt;
 --langmap=formulaai:.fai&lt;br /&gt;
 --regex-formulaai=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/&lt;br /&gt;
&lt;br /&gt;
This is especially nice when used with an editor or plugin with ctags support, such as Taglist for Vim.&lt;br /&gt;
&lt;br /&gt;
=== Vim ===&lt;br /&gt;
&lt;br /&gt;
====Syntax Highlighting====&lt;br /&gt;
&lt;br /&gt;
Follow these steps to enjoy vim syntax highlighting support for Formula AI.&lt;br /&gt;
&lt;br /&gt;
# Grab the Formula AI vim syntax file, [http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/tools/vim/formulaai.vim formulaai.vim].&lt;br /&gt;
# Copy formulaai.vim to .vim/syntax &lt;br /&gt;
# Add the following to .vimrc :&lt;br /&gt;
 autocmd! BufRead,BufNewFile *.fai setfiletype formulaai&lt;br /&gt;
&lt;br /&gt;
====Taglist Support====&lt;br /&gt;
&lt;br /&gt;
First you will need the very nice [http://www.vim.org/scripts/script.php?script_id=273 taglist plugin].  Follow the link for downloads and install directions if you don't already have it installed.&lt;br /&gt;
&lt;br /&gt;
Next, you'll need Formula AI support for exuberant ctags, follow the instructions in the [[#ctags|ctags]] section.  &lt;br /&gt;
&lt;br /&gt;
Once you have all that, simply add the following line to your .vimrc:&lt;br /&gt;
 &lt;br /&gt;
 let tlist_formulaai_settings = 'formulaai;d:definition'&lt;br /&gt;
&lt;br /&gt;
To test it all out, open a Formula AI script file and enter the command &lt;br /&gt;
 :Tlist&lt;br /&gt;
&lt;br /&gt;
You should now have some nice highlighting and be able to easily navigate through formula, enjoy!&lt;br /&gt;
  &lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26556</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26556"/>
		<updated>2008-08-30T10:25:26Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Files and formulas */&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;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''ennemy_units'' all units that are ennemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''ennemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(*ai)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 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;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&lt;br /&gt;
&lt;br /&gt;
You can easily split your formulas between different files and include them when necessary. For example:&lt;br /&gt;
&lt;br /&gt;
 [unit]&lt;br /&gt;
  ...&lt;br /&gt;
  formula={my_unit_formula.fai}&lt;br /&gt;
 [/unit]&lt;br /&gt;
&lt;br /&gt;
Will look for unit formula in the my_unit_formula.fai file.&lt;br /&gt;
&lt;br /&gt;
Although it is not mandatory, we advocate to use following syntax in your fai files:&lt;br /&gt;
&lt;br /&gt;
 faifile '&amp;lt;filename&amp;gt;'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
This makes formula system know which file it is working with now, and gives you improved error reporting, which is often really helpful. Valid syntax for my_unit_formula.fai would be:&lt;br /&gt;
&lt;br /&gt;
 faifile 'my_unit_formula.fai'&lt;br /&gt;
 ...&lt;br /&gt;
 faiend&lt;br /&gt;
&lt;br /&gt;
== Tool Support ==&lt;br /&gt;
&lt;br /&gt;
=== ctags ===&lt;br /&gt;
&lt;br /&gt;
For some rudimentary support for exuberant ctags, add the following to .ctags (or create the file if it doesn't exist):&lt;br /&gt;
&lt;br /&gt;
 --langdef=formulaai&lt;br /&gt;
 --langmap=formulaai:.fai&lt;br /&gt;
 --regex-formulaai=/^def[ \t]*([a-zA-Z0-9_]+)/\1/d,definition/&lt;br /&gt;
&lt;br /&gt;
This is especially nice when used with an editor or plugin with ctags support, such as Taglist for Vim.&lt;br /&gt;
&lt;br /&gt;
=== Vim ===&lt;br /&gt;
&lt;br /&gt;
====Syntax Highlighting====&lt;br /&gt;
&lt;br /&gt;
Follow these steps to enjoy vim syntax highlighting support for Formula AI.&lt;br /&gt;
&lt;br /&gt;
# Grab the Formula AI vim syntax file, [http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/tools/vim/formulaai.vim formulaai.vim].&lt;br /&gt;
# Copy formulaai.vim to .vim/syntax &lt;br /&gt;
# Add the following to .vimrc :&lt;br /&gt;
 autocmd! BufRead,BufNewFile *.fai setfiletype formulaai&lt;br /&gt;
&lt;br /&gt;
====Taglist Support====&lt;br /&gt;
&lt;br /&gt;
First you will need the very nice [http://www.vim.org/scripts/script.php?script_id=273 taglist plugin].  Follow the link for downloads and install directions if you don't already have it installed.&lt;br /&gt;
&lt;br /&gt;
Next, you'll need Formula AI support for exuberant ctags, follow the instructions in the [[#ctags|ctags]] section.  &lt;br /&gt;
&lt;br /&gt;
Once you have all that, simply add the following line to your .vimrc:&lt;br /&gt;
 &lt;br /&gt;
 let tlist_formulaai_settings = 'formulaai;d:definition'&lt;br /&gt;
&lt;br /&gt;
To test it all out, open a Formula AI script file and enter the command &lt;br /&gt;
 :Tlist&lt;br /&gt;
&lt;br /&gt;
You should now have some nice highlighting and be able to easily navigate through formula, enjoy!&lt;br /&gt;
  &lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26555</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26555"/>
		<updated>2008-08-30T10:18:11Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: &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;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''ennemy_units'' all units that are ennemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''ennemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(*ai)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 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;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Files and formulas ==&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>Dragonking</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26554</id>
		<title>FormulaAI</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FormulaAI&amp;diff=26554"/>
		<updated>2008-08-30T10:13:19Z</updated>

		<summary type="html">&lt;p&gt;Dragonking: /* Unit Formulas */&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;
To acces one particular element of a list we can use operator [], for example:&lt;br /&gt;
&lt;br /&gt;
 my_list[0]&lt;br /&gt;
&lt;br /&gt;
Returns first element from the my_list, so:&lt;br /&gt;
&lt;br /&gt;
 [ 10, 20, 30, 40][2]&lt;br /&gt;
&lt;br /&gt;
Returns&lt;br /&gt;
&lt;br /&gt;
 30&lt;br /&gt;
&lt;br /&gt;
* Maps: A map is a sequence of pairs, each pair is a key and assigned to it value. For example:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ]&lt;br /&gt;
&lt;br /&gt;
Is a map which consist of two pairs, first one assigns to the text string 'Elvish Fighter' the value 50, second one assigns 60 to the 'Elvish Archer' string.&lt;br /&gt;
&lt;br /&gt;
To access value assigned to the key, we can use operator []:&lt;br /&gt;
&lt;br /&gt;
 [ 'Elvish Fighter' -&amp;gt; 50, 'Elvish Archer' -&amp;gt; 60 ][ 'Elvish Fighter' ]&lt;br /&gt;
&lt;br /&gt;
Above example returns &lt;br /&gt;
&lt;br /&gt;
 50&lt;br /&gt;
&lt;br /&gt;
== AI Formula Language ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
&lt;br /&gt;
The formula language must be able to access information about the scenario being played to make intelligent decisions. Thus there are various 'inputs' that one may access. A simple example of an input is the turn number one is on, given by the input, 'turn'. Try bringing up the formula command line using 'f' and then type in&lt;br /&gt;
&lt;br /&gt;
 turn&lt;br /&gt;
&lt;br /&gt;
The AI will print out the current turn number the game is on.&lt;br /&gt;
&lt;br /&gt;
The 'turn' input is a simple integer. However, some inputs are complex types which contain other inputs, or which may be lists of inputs. For instance, the input 'my_units' contains a list of all the AI's units.&lt;br /&gt;
&lt;br /&gt;
A complex input such as a unit will contain a variety of inputs inside it. If one has a unit input, called 'u' for instance, one can access the 'x' co-ordinate of that unit by using u.loc.x -- u.loc accesses the 'location' object inside the 'unit' object, and the 'location' object contains 'x' and 'y' inputs inside it, which are the x and y co-ordinate of the unit.&lt;br /&gt;
=== Available variables ===&lt;br /&gt;
these are variables that you can call in an AI formula or from the command line.&lt;br /&gt;
&lt;br /&gt;
* ''turn'' the current turn number&lt;br /&gt;
* ''units'' the complete list of all units&lt;br /&gt;
* ''my_units'' the complete list of all units owned by the current player&lt;br /&gt;
* ''ennemy_units'' all units that are ennemy to the current player&lt;br /&gt;
* ''villages'' all the villages on the map&lt;br /&gt;
* ''my_villages'' all the villages owned by the current player&lt;br /&gt;
* ''ennemy_and_unowned_villages'' all villages that you don't own&lt;br /&gt;
* ''map'' all the data about the map&lt;br /&gt;
* ''teams'' all the data about all the teams&lt;br /&gt;
&lt;br /&gt;
=== Built-in functions ===&lt;br /&gt;
The formula language contains a large number of built-in functions which allow you to carry out all kinds of complex tasks. List of these functions, usage and simple examples can be found [http://www.wesnoth.org/wiki/FormulaAI_Functions here].&lt;br /&gt;
&lt;br /&gt;
=== Custom Functions ===&lt;br /&gt;
&lt;br /&gt;
* You can define your own functions. A function is a formula which takes some inputs as parameters. Suppose we wanted to define a function that puts some value on a unit, we might add the following to the [ai] tag:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit&amp;quot;&lt;br /&gt;
 formula=&amp;quot;unit.hitpoints + unit.level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes a 'unit' as an input, and runs the given calculation over it.&lt;br /&gt;
&lt;br /&gt;
* We can have multiple inputs in our functions, to define them, just create comma-separated inputs list:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;attacker,defender&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This has defined a new function which takes both 'attacker' and 'defender' as an inputs.&lt;br /&gt;
&lt;br /&gt;
* Sometimes, we use one of our inputs really often in our function - to make our life easier we can make its members (inputs) directly accessible from within the formula. This is improved version of function from above:&lt;br /&gt;
&lt;br /&gt;
 [function]&lt;br /&gt;
 name=value_unit&lt;br /&gt;
 inputs=&amp;quot;unit*&amp;quot;&lt;br /&gt;
 formula=&amp;quot;hitpoints + level*4&amp;quot;&lt;br /&gt;
 [/function]&lt;br /&gt;
&lt;br /&gt;
As you can see, if we define input with a * char at the end, we make it a 'default input' for a formula. Note, that you can define only one default input per function.&lt;br /&gt;
&lt;br /&gt;
* It is important to know difference between formulas defined in custom functions, and formula defined by a 'move=' in a [ai] tag. For example, if we want to get info about leader, we write in formula 'my_leader' - which acces member of the AI. To be able to use 'my_leader' in custom functions we have to add 'ai' as an input for our function:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by writing 'ai.my_leader', or:&lt;br /&gt;
&lt;br /&gt;
 inputs=&amp;quot;ai*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
allows us to access leader info by simply writing 'my_leader'&lt;br /&gt;
&lt;br /&gt;
* You can also use 'def' [[#Keywords|keyword]] to define custom functions&lt;br /&gt;
&lt;br /&gt;
=== Comments ===&lt;br /&gt;
&lt;br /&gt;
Comments in Formula AI scripts are enclosed by # #:&lt;br /&gt;
&lt;br /&gt;
 #Define opening move#&lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)),&lt;br /&gt;
  [])&lt;br /&gt;
&lt;br /&gt;
Comments may also be included at the end of a line:&lt;br /&gt;
 &lt;br /&gt;
 def opening(*ai) &lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23), loc(14,22)), #capture village#&lt;br /&gt;
  []) #do nothing#&lt;br /&gt;
&lt;br /&gt;
and they may also be used inline:&lt;br /&gt;
&lt;br /&gt;
 def opening(*ai)&lt;br /&gt;
  if(turn = 1,&lt;br /&gt;
   move(loc(11,23) #my_leader#, loc(14,24) #closest village#),&lt;br /&gt;
  [] #do nothing# )&lt;br /&gt;
&lt;br /&gt;
== Keywords == &lt;br /&gt;
&lt;br /&gt;
The formula language has some reserved keywords to provide primitive functionality.  Currently the following keywords are defined:&lt;br /&gt;
&lt;br /&gt;
* where: This keyword is used to defining statements in formulas. You can define multiple comma-separated statements. Syntax:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;formula&amp;gt; where &amp;lt;comma-separated list of statements&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example formula:&lt;br /&gt;
&lt;br /&gt;
  a + b where a = 2, b = 4&lt;br /&gt;
&lt;br /&gt;
will give as result 6.&lt;br /&gt;
&lt;br /&gt;
* functions: Returns a list of all built-in and custom functions available to the AI&lt;br /&gt;
&lt;br /&gt;
* def: This keyword creates functions using the syntax:&lt;br /&gt;
&lt;br /&gt;
  def function_name(arg1, arg2, ....) function_body&lt;br /&gt;
&lt;br /&gt;
For example,   &lt;br /&gt;
&lt;br /&gt;
  def sum(x,y) x + y&lt;br /&gt;
&lt;br /&gt;
creates a function sum taking two arguments and returns their sum.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 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;
* map:&lt;br /&gt;
 map=[ 'Elvish Archer' -&amp;gt; 70, 'Elvish Shaman' -&amp;gt; 60 ]&lt;br /&gt;
*location:&lt;br /&gt;
 place=&amp;quot;loc(X,Y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= 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>Dragonking</name></author>
		
	</entry>
</feed>