← Back to team overview

widelands-dev team mailing list archive

Re: [Merge] lp:~widelands-dev/widelands/ai_dna_dump into lp:widelands

 

Code check says:

/home/travis/build/widelands/widelands/src/logic/ai_dna_handler.h:20: Use WL_LOGIC_AI_DNA_HANDLER_H as include guard.

/home/travis/build/widelands/widelands/src/logic/ai_dna_handler.cc:108: Use log() from base/log.h instead of printf.


Added some diff comments - it's all only minor issues :)

Diff comments:

> === added directory 'data/ai'
> === added file 'data/ai/ai_input_1.wai'
> --- data/ai/ai_input_1.wai	1970-01-01 00:00:00 +0000
> +++ data/ai/ai_input_1.wai	2017-07-24 20:38:49 +0000
> @@ -0,0 +1,379 @@
> +# Automatically created by Widelands bzr[] (Debug)

The revision number is missing here.

It would also be good if there was a short documentation string dumped into these files.

> +
> +[magic_numbers]
> +0="18"
> +1="-47"
> +2="21"
> +3="35"
> +4="-7"
> +5="-56"
> +6="-53"
> +7="81"
> +8="0"
> +9="0"
> +10="-55"
> +11="22"
> +12="-92"
> +13="48"
> +14="70"
> +15="-30"
> +16="26"
> +17="79"
> +18="-63"
> +19="-12"
> +20="79"
> +21="-28"
> +22="13"
> +23="39"
> +24="0"
> +25="3"
> +26="45"
> +27="-33"
> +28="53"
> +29="51"
> +30="-93"
> +31="47"
> +32="-42"
> +33="90"
> +34="-72"
> +35="52"
> +36="-68"
> +37="-47"
> +38="17"
> +39="-72"
> +40="51"
> +41="51"
> +42="-4"
> +43="-40"
> +44="47"
> +45="7"
> +46="6"
> +47="3"
> +48="-64"
> +49="-41"
> +50="-3"
> +51="-55"
> +52="62"
> +53="0"
> +54="57"
> +55="-92"
> +56="4"
> +57="-89"
> +58="66"
> +59="-44"
> +60="-87"
> +61="56"
> +62="19"
> +63="-34"
> +64="-20"
> +65="24"
> +66="-54"
> +67="84"
> +68="56"
> +69="-51"
> +70="0"
> +71="44"
> +72="0"
> +73="-2"
> +74="-11"
> +75="-4"
> +76="-96"
> +77="-34"
> +78="0"
> +79="-31"
> +80="71"
> +81="-98"
> +82="-25"
> +83="-44"
> +84="58"
> +85="68"
> +86="0"
> +87="28"
> +88="-54"
> +89="23"
> +90="21"
> +91="53"
> +92="80"
> +93="0"
> +94="-41"
> +95="58"
> +96="53"
> +97="27"
> +98="-73"
> +99="-65"
> +100="14"
> +101="-42"
> +102="31"
> +103="-92"
> +104="-62"
> +105="86"
> +106="-55"
> +107="-63"
> +108="0"
> +109="-40"
> +110="77"
> +111="0"
> +112="-65"
> +113="0"
> +114="32"
> +115="-26"
> +116="0"
> +117="0"
> +118="-70"
> +119="74"
> +120="85"
> +121="0"
> +122="52"
> +123="48"
> +124="-30"
> +125="25"
> +126="-61"
> +127="62"
> +128="60"
> +129="8"
> +130="-52"
> +131="46"
> +132="100"
> +133="-74"
> +134="19"
> +135="95"
> +136="-9"
> +137="-100"
> +138="36"
> +139="-4"
> +140="77"
> +141="15"
> +142="-57"
> +143="-82"
> +144="-22"
> +145="7"
> +146="0"
> +147="-30"
> +148="76"
> +149="-47"
> +
> +[neuron_values]
> +0="48"
> +1="-85"
> +2="-26"
> +3="47"
> +4="-93"
> +5="-9"
> +6="-91"
> +7="84"
> +8="50"
> +9="-12"
> +10="0"
> +11="-59"
> +12="-89"
> +13="98"
> +14="53"
> +15="-83"
> +16="-91"
> +17="-90"
> +18="-56"
> +19="0"
> +20="59"
> +21="-13"
> +22="52"
> +23="-70"
> +24="41"
> +25="76"
> +26="47"
> +27="-31"
> +28="79"
> +29="0"
> +30="0"
> +31="25"
> +32="-59"
> +33="0"
> +34="-38"
> +35="-85"
> +36="-60"
> +37="-42"
> +38="-55"
> +39="-70"
> +40="-27"
> +41="-95"
> +42="-87"
> +43="-55"
> +44="92"
> +45="-12"
> +46="-21"
> +47="-76"
> +48="4"
> +49="97"
> +50="58"
> +51="-79"
> +52="71"
> +53="-90"
> +54="-72"
> +55="0"
> +56="-14"
> +57="-94"
> +58="-15"
> +59="66"
> +60="-54"
> +61="9"
> +62="67"
> +63="-47"
> +64="-74"
> +65="-36"
> +66="-39"
> +67="51"
> +68="0"
> +69="-3"
> +70="48"
> +71="0"
> +72="-41"
> +73="4"
> +74="41"
> +75="-46"
> +76="18"
> +77="0"
> +78="51"
> +79="-49"
> +
> +[neuron_functions]
> +0="1"
> +1="0"
> +2="1"
> +3="2"
> +4="0"
> +5="2"
> +6="0"
> +7="0"
> +8="0"
> +9="0"
> +10="2"
> +11="1"
> +12="2"
> +13="2"
> +14="2"
> +15="1"
> +16="2"
> +17="2"
> +18="2"
> +19="2"
> +20="2"
> +21="1"
> +22="0"
> +23="2"
> +24="2"
> +25="1"
> +26="0"
> +27="1"
> +28="0"
> +29="2"
> +30="1"
> +31="2"
> +32="2"
> +33="1"
> +34="2"
> +35="1"
> +36="0"
> +37="1"
> +38="2"
> +39="1"
> +40="2"
> +41="2"
> +42="2"
> +43="1"
> +44="0"
> +45="1"
> +46="2"
> +47="2"
> +48="0"
> +49="0"
> +50="1"
> +51="0"
> +52="2"
> +53="1"
> +54="0"
> +55="1"
> +56="2"
> +57="0"
> +58="1"
> +59="1"
> +60="0"
> +61="0"
> +62="1"
> +63="0"
> +64="0"
> +65="2"
> +66="2"
> +67="2"
> +68="1"
> +69="0"
> +70="0"
> +71="1"
> +72="2"
> +73="2"
> +74="1"
> +75="0"
> +76="0"
> +77="2"
> +78="2"
> +79="1"
> +
> +[fneurons]
> +0="482938525"
> +1="1323289279"
> +2="1154975886"
> +3="3850610167"
> +4="2325197375"
> +5="72672609"
> +6="3177653318"
> +7="2470637805"
> +8="1670592797"
> +9="906269786"
> +10="1526985352"
> +11="2815572333"
> +12="1173298984"
> +13="1885154951"
> +14="1523685677"
> +15="1175155510"
> +16="2863175513"
> +17="2956009518"
> +18="2788417044"
> +19="1123523384"
> +20="131413436"
> +21="2840577824"
> +22="3271016660"
> +23="2817506633"
> +24="1066463961"
> +25="1425037041"
> +26="2550820714"
> +27="4142541183"
> +28="4078712499"
> +29="117894310"
> +30="2200895127"
> +31="3463099423"
> +32="3891648480"
> +33="2047251290"
> +34="4144223227"
> +35="1032997214"
> +36="263449493"
> +37="2279562880"
> +38="1161120916"
> +39="4153896190"
> +40="3464013214"
> +41="736468043"
> +42="2046764308"
> +43="3994786385"
> +44="3381673767"
> +45="1426202340"
> +46="1267797649"
> +47="2484017495"
> +48="2824408371"
> +49="3014148188"
> +50="2158737554"
> +51="735548966"
> +52="2400772218"
> +53="2821059969"
> +54="757174171"
> +55="867489696"
> +56="1359489203"
> +57="4020366408"
> +58="2609642563"
> +59="701416851"
> 
> === modified file 'src/ai/ai_help_structs.cc'
> --- src/ai/ai_help_structs.cc	2017-07-04 11:34:00 +0000
> +++ src/ai/ai_help_structs.cc	2017-07-24 20:38:49 +0000
> @@ -21,17 +21,19 @@
>  
>  #include "base/macros.h"
>  #include "base/time_string.h"
> +#include "logic/ai_dna_handler.h"
>  #include "logic/map.h"
>  #include "logic/player.h"
>  
> +namespace Widelands {
> +
>  // couple of constants for calculation of road interconnections
>  constexpr int kRoadNotFound = -1000;
>  constexpr int kShortcutWithinSameEconomy = 1000;
>  constexpr int kRoadToDifferentEconomy = 10000;
> -constexpr int kUpperDefaultMutationLimit = 200;
> -constexpr int kLowerDefaultMutationLimit = 150;
> -
> -namespace Widelands {
> +constexpr int kUpperDefaultMutationLimit = 150;
> +constexpr int kLowerDefaultMutationLimit = 75;
> +constexpr int16_t kPrefNumberProbability = (kAITrainingMode) ? 5 : 100;

No need for the () here

>  
>  // CheckStepRoadAI
>  CheckStepRoadAI::CheckStepRoadAI(Player* const pl, uint8_t const mc, bool const oe)
> @@ -472,7 +475,9 @@
>                              const uint16_t attackers,
>                              const int16_t trained_soldiers,
>                              const int16_t latest_attackers,
> -                            const uint16_t conq_ws) {
> +                            const uint16_t conq_ws,
> +                            const uint16_t m_strength,

is m_ = min_ or max_?

> +                            const uint32_t existing_ps) {
>  
>  	const int16_t main_bonus =
>  	   ((static_cast<int32_t>(land - old_land) > 0 && land > max_e_land * 5 / 6 && attackers > 0 &&
> @@ -482,15 +487,21 @@
>  
>  	const int16_t land_delta_bonus = static_cast<int16_t>(land - old_land) * kLandDeltaMultiplier;
>  
> +	const uint32_t ps_sites_bonus =
> +	   kPSitesRatioMultiplier * existing_ps * existing_ps * existing_ps / 1000 / 1000;

You could use std::pow here http://www.cplusplus.com/reference/cmath/pow/

> +
>  	score = land / kCurrentLandDivider + land_delta_bonus + main_bonus +
>  	        attackers * kAttackersMultiplier + ((attackers > 0) ? kAttackBonus : -kAttackBonus) +
> -	        trained_soldiers * kTrainedSoldiersScore + +kConqueredWhBonus + conq_ws;
> +	        trained_soldiers * kTrainedSoldiersScore + kConqueredWhBonus * conq_ws +
> +	        m_strength * kStrengthMultiplier + ps_sites_bonus - 500 * kPSitesRatioMultiplier;
>  
> -	log(" %2d %s: reviewing AI mngm. data, sc: %5d Pr.p: %d (l: %4d / %4d / %4d, "
> -	    "at:%4d(%3d), ts:%4d(%2d), ConqWH:%2d)\n",
> +	log(" %2d %s: reviewing AI mngm. data, sc: %5d Pr.p: %d (l:%4d/%s/%4d, "
> +	    "at:%4d(%3d),ts:%4d/%2d,cWH:%2d,str:%2d/%4d,ps:%4d/%4d)\n",

I think the output would be more readable with a blank space after each ,

>  	    pn, gamestring_with_leading_zeros(gametime), score, primary_parent,
> -	    land / kCurrentLandDivider, main_bonus, land_delta_bonus, attackers * kAttackersMultiplier,
> -	    latest_attackers, trained_soldiers * kTrainedSoldiersScore, trained_soldiers, conq_ws);
> +	    land / kCurrentLandDivider, (main_bonus) ? "*" : " ", land_delta_bonus,
> +	    attackers * kAttackersMultiplier, latest_attackers, trained_soldiers * kTrainedSoldiersScore,
> +	    trained_soldiers, conq_ws, m_strength, m_strength * kStrengthMultiplier, existing_ps,
> +	    ps_sites_bonus);
>  
>  	if (score < -10000 || score > 30000) {
>  		log("%2d %s: reviewing AI mngm. data, score too extreme: %4d\n", pn,
> @@ -507,403 +518,42 @@
>  
>  	log("%2d: DNA initialization... \n", pn);
>  
> -	// AutoSCore_AIDNA_1
> -	const std::vector<int16_t> AI_initial_military_numbers_A = {
> -	   18,  -42, 21,  59,  -7,  -78,
> -	   -22, 81,  48,  0,  //  AutoContent_01_AIDNA_1
> -	   -82, 45,  -96, 16,  70,  -30,
> -	   33,  79,  -78, -42,  //  AutoContent_02_AIDNA_1
> -	   79,  -16, 34,  46,  -22, 0,
> -	   45,  -29, 53,  51,  //  AutoContent_03_AIDNA_1
> -	   24,  47,  -27, 80,  -86, 46,
> -	   -63, -47, 20,  -63,  //  AutoContent_04_AIDNA_1
> -	   78,  51,  -11, -77, 20,  38,
> -	   6,   37,  -64, -41,  //  AutoContent_05_AIDNA_1
> -	   -3,  -55, 62,  0,   64,  -92,
> -	   4,   -89, 71,  -18,  //  AutoContent_06_AIDNA_1
> -	   -87, 56,  17,  -34, -69, 24,
> -	   -57, 84,  40,  -51,  //  AutoContent_07_AIDNA_1
> -	   0,   44,  0,   -2,  -11, -4,
> -	   -96, -35, -29, -12,  //  AutoContent_08_AIDNA_1
> -	   71,  -98, -25, 50,  97,  74,
> -	   0,   65,  -60, 23,  //  AutoContent_09_AIDNA_1
> -	   38,  53,  74,  0,   -43, 27,
> -	   32,  37,  -24, -65,  //  AutoContent_10_AIDNA_1
> -	   16,  -42, 19,  -94, -28, 83,
> -	   -55, -63, 16,  -41,  //  AutoContent_11_AIDNA_1
> -	   28,  -3,  0,   -87, 32,  5,
> -	   4,   6,   -20, 62,  //  AutoContent_12_AIDNA_1
> -	   85,  0,   58,  48,  -80, -20,
> -	   -49, 71,  60,  8,  //  AutoContent_13_AIDNA_1
> -	   -52, 59,  100, -74, 0,   -36,
> -	   -9,  80,  41,  -67,  //  AutoContent_14_AIDNA_1
> -	   0,   15,  -96, -51, -21, 11,
> -	   -27, -30, 76,  -47  //  AutoContent_15_AIDNA_1
> -	};
> -
> -	assert(kMagicNumbersSize == AI_initial_military_numbers_A.size());
> -
> -	const std::vector<int8_t> input_weights_A =
> -	   //  0     1     2     3     4     5     6     7     8     9
> -	   {
> -	      48,  -85, -26, 47,  -93, -22,
> -	      -91, 84,  24,  -12,  //  AutoContent_16_AIDNA_1
> -	      98,  -59, -89, 76,  81,  95,
> -	      -91, -90, -56, -15,  //  AutoContent_17_AIDNA_1
> -	      -65, -18, 6,   -65, 41,  38,
> -	      47,  -31, 79,  23,  //  AutoContent_18_AIDNA_1
> -	      16,  25,  -59, 0,   -38, -85,
> -	      -60, -42, 0,   -70,  //  AutoContent_19_AIDNA_1
> -	      -78, -86, -87, -55, 92,  -63,
> -	      -21, -76, 4,   87,  //  AutoContent_20_AIDNA_1
> -	      58,  -40, 71,  -90, -72, 0,
> -	      -47, -94, -15, 66,  //  AutoContent_21_AIDNA_1
> -	      -32, 9,   67,  -47, -44, -76,
> -	      -53, 57,  -31, -47,  //  AutoContent_22_AIDNA_1
> -	      0,   -28, -16, 48,  41,  -45,
> -	      36,  -8,  51,  -49  //  AutoContent_23_AIDNA_1
> -	   };
> -	const std::vector<int8_t> input_func_A = {
> -	   1, 0, 1, 2, 2, 1,
> -	   0, 0, 0, 0,  //  AutoContent_24_AIDNA_1
> -	   2, 1, 2, 2, 2, 1,
> -	   2, 2, 2, 1,  //  AutoContent_25_AIDNA_1
> -	   2, 2, 0, 2, 2, 1,
> -	   0, 1, 0, 2,  //  AutoContent_26_AIDNA_1
> -	   1, 2, 2, 1, 2, 1,
> -	   0, 1, 2, 1,  //  AutoContent_27_AIDNA_1
> -	   2, 1, 2, 0, 0, 1,
> -	   2, 0, 0, 0,  //  AutoContent_28_AIDNA_1
> -	   1, 0, 0, 1, 0, 1,
> -	   0, 0, 1, 1,  //  AutoContent_29_AIDNA_1
> -	   2, 0, 1, 2, 0, 2,
> -	   2, 2, 1, 0,  //  AutoContent_30_AIDNA_1
> -	   2, 1, 2, 2, 1, 1,
> -	   0, 2, 2, 1  //  AutoContent_31_AIDNA_1
> -	};
> -	assert(kNeuronPoolSize == input_func_A.size());
> -	assert(kNeuronPoolSize == input_weights_A.size());
> -
> -	const std::vector<uint32_t> f_neurons_A = {
> -	   471130763,  1322756799, 1148682382, 2713953719, 194460207,  18113635,
> -	   2947490886, 3275944172, 3438582086, 856208494,  //  AutoContent_32_AIDNA_1
> -	   1326156684, 986431571,  3465514749, 1962749574, 1523585333, 1376482111,
> -	   1223335901, 2962231598, 657710612,  578259960,  //  AutoContent_33_AIDNA_1
> -	   1271222963, 2915927856, 3396846486, 1743568169, 2679432920, 410834609,
> -	   134904175,  2968201710, 2132567223, 2248461478,  //  AutoContent_34_AIDNA_1
> -	   161963959,  3295327519, 670058472,  2013696856, 3608400883, 496651103,
> -	   733137541,  2952748738, 3307293853, 3886490843,  //  AutoContent_35_AIDNA_1
> -	   3233788172, 715230539,  2583635732, 4271028953, 1217674278, 4043323645,
> -	   1857109651, 2181897047, 2825979187, 3081298269,  //  AutoContent_36_AIDNA_1
> -	   1277901018, 1255642150, 2384261818, 2866704864, 755617465,  835768208,
> -	   1394358417, 4012239945, 2601238115, 3933467106  //  AutoContent_37_AIDNA_1
> -	};
> -	assert(kFNeuronPoolSize == f_neurons_A.size());
> -
> -	// AutoSCore_AIDNA_2
> -	const std::vector<int16_t> AI_initial_military_numbers_B = {
> -	   18,  -42, 21,  59,  -7,  -78,
> -	   -22, 81,  48,  0,  //  AutoContent_01_AIDNA_2
> -	   -55, 45,  -96, 16,  70,  -30,
> -	   33,  79,  -78, -42,  //  AutoContent_02_AIDNA_2
> -	   79,  -16, 34,  46,  -22, 0,
> -	   45,  -33, 53,  51,  //  AutoContent_03_AIDNA_2
> -	   49,  47,  -27, 80,  -86, 46,
> -	   -63, -47, 20,  -63,  //  AutoContent_04_AIDNA_2
> -	   78,  51,  23,  -77, 20,  38,
> -	   6,   37,  -64, -41,  //  AutoContent_05_AIDNA_2
> -	   -3,  -55, 62,  0,   64,  -92,
> -	   4,   -89, 71,  -18,  //  AutoContent_06_AIDNA_2
> -	   -87, 56,  17,  -34, -69, 24,
> -	   -57, 84,  40,  -51,  //  AutoContent_07_AIDNA_2
> -	   0,   44,  0,   -2,  -11, -4,
> -	   -96, -35, -29, -12,  //  AutoContent_08_AIDNA_2
> -	   71,  -98, -25, 50,  97,  74,
> -	   0,   65,  -60, 23,  //  AutoContent_09_AIDNA_2
> -	   38,  53,  74,  0,   -15, 27,
> -	   32,  37,  -24, -65,  //  AutoContent_10_AIDNA_2
> -	   16,  -42, 19,  -94, -28, 83,
> -	   -55, -63, 16,  -41,  //  AutoContent_11_AIDNA_2
> -	   28,  -3,  0,   -87, 32,  5,
> -	   4,   6,   -20, 62,  //  AutoContent_12_AIDNA_2
> -	   85,  0,   58,  48,  -80, -20,
> -	   -49, 71,  60,  8,  //  AutoContent_13_AIDNA_2
> -	   -52, 59,  100, -74, 0,   -36,
> -	   -9,  80,  41,  -67,  //  AutoContent_14_AIDNA_2
> -	   0,   15,  -96, -51, -21, 11,
> -	   -27, -30, 76,  -47  //  AutoContent_15_AIDNA_2
> -	};
> -	assert(kMagicNumbersSize == AI_initial_military_numbers_B.size());
> -
> -	const std::vector<int8_t> input_weights_B = {
> -	   48,  -85, -26, 47,  -93, -22,
> -	   -91, 84,  50,  -12,  //  AutoContent_16_AIDNA_2
> -	   98,  -59, -89, 76,  81,  95,
> -	   -91, -90, -56, -15,  //  AutoContent_17_AIDNA_2
> -	   -65, -18, 6,   -65, 41,  38,
> -	   47,  -31, 79,  23,  //  AutoContent_18_AIDNA_2
> -	   16,  25,  -59, 0,   -38, -85,
> -	   -60, -42, 0,   -70,  //  AutoContent_19_AIDNA_2
> -	   -78, -86, -87, -55, 92,  -63,
> -	   -21, -76, 4,   87,  //  AutoContent_20_AIDNA_2
> -	   58,  -40, 71,  -90, -72, 0,
> -	   -47, -94, -15, 66,  //  AutoContent_21_AIDNA_2
> -	   -32, 9,   67,  -47, -44, -76,
> -	   -53, 57,  -31, -47,  //  AutoContent_22_AIDNA_2
> -	   0,   -28, -16, 48,  41,  -45,
> -	   36,  -8,  51,  -49  //  AutoContent_23_AIDNA_2
> -	};
> -
> -	const std::vector<int8_t> input_func_B = {
> -	   1, 0, 1, 2, 2, 1,
> -	   0, 0, 0, 0,  //  AutoContent_24_AIDNA_2
> -	   2, 1, 2, 2, 2, 1,
> -	   2, 2, 2, 1,  //  AutoContent_25_AIDNA_2
> -	   2, 2, 0, 2, 2, 1,
> -	   0, 1, 0, 2,  //  AutoContent_26_AIDNA_2
> -	   1, 2, 2, 1, 2, 1,
> -	   0, 1, 2, 1,  //  AutoContent_27_AIDNA_2
> -	   2, 1, 2, 0, 0, 1,
> -	   2, 0, 0, 0,  //  AutoContent_28_AIDNA_2
> -	   1, 0, 0, 1, 0, 1,
> -	   0, 0, 1, 1,  //  AutoContent_29_AIDNA_2
> -	   2, 0, 1, 2, 0, 2,
> -	   2, 2, 1, 0,  //  AutoContent_30_AIDNA_2
> -	   2, 1, 2, 2, 1, 1,
> -	   0, 2, 2, 1  //  AutoContent_31_AIDNA_2
> -	};
> -	assert(kNeuronPoolSize == input_func_B.size());
> -	assert(kNeuronPoolSize == input_weights_B.size());
> -
> -	const std::vector<uint32_t> f_neurons_B = {
> -	   471130763,  1322756799, 1148682382, 2713953719, 194460207,  18113635,
> -	   2947490886, 3275944172, 3438582022, 855676014,  //  AutoContent_32_AIDNA_2
> -	   1326156684, 986431571,  3465514749, 1962749574, 1523650869, 1376482111,
> -	   2347409353, 2962227502, 657710612,  578259960,  //  AutoContent_33_AIDNA_2
> -	   1271222963, 2915927856, 3396846486, 1743568169, 2679432920, 410834609,
> -	   134904175,  2968201710, 2132567223, 2248461478,  //  AutoContent_34_AIDNA_2
> -	   161963959,  3295327519, 670058472,  2013696856, 4145271795, 496651103,
> -	   733211269,  2952748738, 1159810205, 3886490843,  //  AutoContent_35_AIDNA_2
> -	   3225153820, 732007755,  2583635732, 4271028825, 1217674278, 4043323645,
> -	   1857109651, 2249005911, 2825979187, 3081298269,  //  AutoContent_36_AIDNA_2
> -	   1277901018, 1255642150, 2384261818, 2866704864, 755617465,  835768208,
> -	   1394096273, 4012239945, 2609626723, 3932418530  //  AutoContent_37_AIDNA_2
> -	};
> -	assert(kFNeuronPoolSize == f_neurons_B.size());
> -
> -	// AutoSCore_AIDNA_3
> -	const std::vector<int16_t> AI_initial_military_numbers_C =
> -	   {
> -	      18,  -42, 63,  82,  -7,  -78,
> -	      -22, 81,  48,  0,  //  AutoContent_01_AIDNA_3
> -	      -55, 55,  -96, 16,  70,  -30,
> -	      33,  79,  -78, -42,  //  AutoContent_02_AIDNA_3
> -	      79,  -16, 34,  46,  0,   0,
> -	      0,   -29, 53,  51,  //  AutoContent_03_AIDNA_3
> -	      24,  47,  -27, 42,  -86, 46,
> -	      -63, -47, 20,  -63,  //  AutoContent_04_AIDNA_3
> -	      78,  31,  98,  -73, 20,  38,
> -	      44,  37,  -64, -41,  //  AutoContent_05_AIDNA_3
> -	      -3,  -55, 67,  0,   64,  -92,
> -	      4,   -89, 71,  -60,  //  AutoContent_06_AIDNA_3
> -	      -87, 56,  17,  -34, -69, 24,
> -	      -57, 50,  40,  -51,  //  AutoContent_07_AIDNA_3
> -	      -34, 44,  0,   -2,  -11, -4,
> -	      -96, -35, -29, -12,  //  AutoContent_08_AIDNA_3
> -	      68,  -98, -25, 50,  97,  74,
> -	      0,   65,  -60, 23,  //  AutoContent_09_AIDNA_3
> -	      38,  53,  74,  0,   -15, 27,
> -	      32,  61,  -24, -65,  //  AutoContent_10_AIDNA_3
> -	      16,  -42, 19,  -94, -65, 83,
> -	      -55, -63, 16,  -41,  //  AutoContent_11_AIDNA_3
> -	      74,  -3,  0,   -87, 32,  5,
> -	      4,   6,   -70, 62,  //  AutoContent_12_AIDNA_3
> -	      85,  0,   58,  48,  -80, -20,
> -	      -49, 71,  60,  8,  //  AutoContent_13_AIDNA_3
> -	      -52, 30,  69,  -74, 0,   -36,
> -	      -57, 80,  64,  -67,  //  AutoContent_14_AIDNA_3
> -	      0,   15,  -96, -51, -21, 0,
> -	      -33, -30, 76,  -47  //  AutoContent_15_AIDNA_3
> -	   }
> -
> -	;
> -
> -	assert(kMagicNumbersSize == AI_initial_military_numbers_C.size());
> -
> -	const std::vector<int8_t> input_weights_C = {
> -	   48,  -85, -26, 47,  -65, -19,
> -	   -91, 84,  92,  -12,  //  AutoContent_16_AIDNA_3
> -	   78,  -59, -89, 76,  81,  95,
> -	   -91, -90, -56, -15,  //  AutoContent_17_AIDNA_3
> -	   -65, -18, 6,   -65, 17,  38,
> -	   47,  -45, 79,  23,  //  AutoContent_18_AIDNA_3
> -	   16,  25,  -59, 36,  -38, -85,
> -	   -60, -42, 0,   -70,  //  AutoContent_19_AIDNA_3
> -	   -78, -86, -87, -55, 92,  -63,
> -	   -21, -76, 4,   87,  //  AutoContent_20_AIDNA_3
> -	   58,  -40, 71,  -90, -72, 0,
> -	   -47, -94, -15, 95,  //  AutoContent_21_AIDNA_3
> -	   -32, 9,   67,  -47, -44, -76,
> -	   -53, 57,  -31, -47,  //  AutoContent_22_AIDNA_3
> -	   0,   -28, -16, 48,  41,  -45,
> -	   36,  -8,  63,  -49  //  AutoContent_23_AIDNA_3
> -	};
> -	const std::vector<int8_t> input_func_C = {
> -	   1, 0, 1, 2, 2, 1,
> -	   0, 0, 0, 0,  //  AutoContent_24_AIDNA_3
> -	   2, 1, 2, 2, 1, 1,
> -	   2, 2, 2, 1,  //  AutoContent_25_AIDNA_3
> -	   2, 2, 0, 2, 2, 1,
> -	   0, 1, 0, 2,  //  AutoContent_26_AIDNA_3
> -	   1, 2, 2, 1, 2, 1,
> -	   0, 1, 2, 1,  //  AutoContent_27_AIDNA_3
> -	   2, 1, 2, 0, 0, 1,
> -	   2, 0, 0, 0,  //  AutoContent_28_AIDNA_3
> -	   1, 0, 0, 1, 0, 2,
> -	   0, 0, 1, 1,  //  AutoContent_29_AIDNA_3
> -	   2, 0, 1, 2, 0, 2,
> -	   2, 2, 1, 0,  //  AutoContent_30_AIDNA_3
> -	   2, 1, 2, 2, 1, 1,
> -	   0, 2, 2, 1  //  AutoContent_31_AIDNA_3
> -	};
> -	assert(kNeuronPoolSize == input_func_C.size());
> -	assert(kNeuronPoolSize == input_weights_C.size());
> -
> -	const std::vector<uint32_t> f_neurons_C = {
> -	   202828425,  1322625717, 1148682382, 2244191679, 194456367,  26493027,
> -	   2947491014, 3410163948, 3438582086, 856208494,  //  AutoContent_32_AIDNA_3
> -	   1259048860, 986431571,  3457662708, 1954360966, 1523650869, 1376351039,
> -	   1223335901, 2997887274, 657657361,  645368312,  //  AutoContent_33_AIDNA_3
> -	   1271218867, 2915927856, 3933717470, 2011479337, 2645864080, 408737457,
> -	   2282387823, 2968205806, 1597793527, 2248461494,  //  AutoContent_34_AIDNA_3
> -	   161963959,  1147843615, 670058474,  2013712728, 4145271795, 496651102,
> -	   724812677,  2952748738, 1629834973, 3819381979,  //  AutoContent_35_AIDNA_3
> -	   3233788172, 732007755,  2583635734, 4271028825, 1217670182, 4043323645,
> -	   1857109659, 2249005911, 2834367795, 3072909661,  //  AutoContent_36_AIDNA_3
> -	   1278949528, 1792513063, 2384261690, 2732487136, 755615385,  835767184,
> -	   1393834641, 4012239945, 2601238115, 2859725290  //  AutoContent_37_AIDNA_3
> -	};
> -	assert(kFNeuronPoolSize == f_neurons_C.size());
> -
> -	// AutoSCore_AIDNA_4
> -	const std::vector<int16_t> AI_initial_military_numbers_D = {
> -	   18,  -42, 21,  59,  -7,  -78,
> -	   -22, 81,  48,  0,  //  AutoContent_01_AIDNA_4
> -	   -55, 45,  -96, 16,  70,  -30,
> -	   33,  79,  -78, -42,  //  AutoContent_02_AIDNA_4
> -	   79,  -16, 34,  46,  -22, 0,
> -	   45,  -29, 53,  51,  //  AutoContent_03_AIDNA_4
> -	   24,  47,  -27, 80,  -86, 46,
> -	   -63, -47, 20,  -63,  //  AutoContent_04_AIDNA_4
> -	   78,  51,  -25, -77, 20,  38,
> -	   6,   37,  -64, -41,  //  AutoContent_05_AIDNA_4
> -	   -3,  -55, 62,  0,   64,  -92,
> -	   4,   -89, 71,  -18,  //  AutoContent_06_AIDNA_4
> -	   -87, 56,  17,  -34, -69, 24,
> -	   -57, 84,  40,  -51,  //  AutoContent_07_AIDNA_4
> -	   0,   44,  0,   -2,  -11, -4,
> -	   -96, -35, -29, -12,  //  AutoContent_08_AIDNA_4
> -	   71,  -98, -25, 50,  97,  74,
> -	   0,   65,  -60, 23,  //  AutoContent_09_AIDNA_4
> -	   38,  53,  74,  0,   -15, 27,
> -	   32,  37,  -24, -65,  //  AutoContent_10_AIDNA_4
> -	   16,  -61, 19,  -94, -28, 83,
> -	   -55, -63, 16,  -41,  //  AutoContent_11_AIDNA_4
> -	   28,  -3,  0,   -87, 32,  5,
> -	   4,   6,   -20, 62,  //  AutoContent_12_AIDNA_4
> -	   85,  0,   58,  48,  -80, -20,
> -	   -49, 71,  60,  8,  //  AutoContent_13_AIDNA_4
> -	   -52, 59,  100, -74, 0,   -36,
> -	   -9,  80,  41,  -67,  //  AutoContent_14_AIDNA_4
> -	   0,   15,  -96, -51, -21, 11,
> -	   -27, -30, 76,  -47  //  AutoContent_15_AIDNA_4
> -	};
> -	assert(kMagicNumbersSize == AI_initial_military_numbers_D.size());
> -
> -	const std::vector<int8_t> input_weights_D = {
> -	   48,  -85, -26, 47,  -93, -22,
> -	   -91, 84,  50,  -12,  //  AutoContent_16_AIDNA_4
> -	   98,  -59, -89, 76,  81,  95,
> -	   -91, -90, -56, -15,  //  AutoContent_17_AIDNA_4
> -	   -65, -18, 6,   -65, 41,  38,
> -	   47,  -31, 79,  23,  //  AutoContent_18_AIDNA_4
> -	   16,  25,  -59, 0,   -38, -85,
> -	   -60, -42, 0,   -70,  //  AutoContent_19_AIDNA_4
> -	   -78, -86, -87, -55, 92,  -63,
> -	   -21, -76, 4,   87,  //  AutoContent_20_AIDNA_4
> -	   58,  -40, 71,  -90, -72, 0,
> -	   -47, -94, -15, 66,  //  AutoContent_21_AIDNA_4
> -	   -32, 9,   67,  -47, -44, -76,
> -	   -53, 57,  -31, -47,  //  AutoContent_22_AIDNA_4
> -	   0,   -28, -16, 48,  41,  -45,
> -	   36,  -8,  63,  -49  //  AutoContent_23_AIDNA_4
> -	};
> -
> -	const std::vector<int8_t> input_func_D = {
> -	   1, 0, 1, 2, 2, 1,
> -	   0, 0, 0, 0,  //  AutoContent_24_AIDNA_4
> -	   2, 1, 2, 2, 2, 1,
> -	   2, 2, 2, 1,  //  AutoContent_25_AIDNA_4
> -	   2, 2, 0, 2, 2, 1,
> -	   0, 1, 0, 2,  //  AutoContent_26_AIDNA_4
> -	   1, 2, 2, 1, 2, 1,
> -	   0, 1, 2, 1,  //  AutoContent_27_AIDNA_4
> -	   2, 1, 2, 0, 0, 1,
> -	   2, 0, 0, 0,  //  AutoContent_28_AIDNA_4
> -	   1, 0, 0, 1, 0, 1,
> -	   0, 0, 1, 1,  //  AutoContent_29_AIDNA_4
> -	   2, 0, 1, 2, 0, 2,
> -	   2, 2, 1, 0,  //  AutoContent_30_AIDNA_4
> -	   2, 1, 2, 2, 1, 1,
> -	   0, 2, 2, 1  //  AutoContent_31_AIDNA_4
> -	};
> -	assert(kNeuronPoolSize == input_func_D.size());
> -	assert(kNeuronPoolSize == input_weights_D.size());
> -
> -	const std::vector<uint32_t> f_neurons_D = {
> -	   471130763,  1322756799, 1148682382, 2713953719, 194460175,  18113635,
> -	   2947490886, 3275944172, 3438582214, 856208494,  //  AutoContent_32_AIDNA_4
> -	   1326156684, 449560659,  3465512701, 1962749574, 1523650869, 1376482111,
> -	   2347409353, 2962227502, 657710614,  578259960,  //  AutoContent_33_AIDNA_4
> -	   1271222963, 2915927856, 3396846486, 1743568169, 2679432920, 410834611,
> -	   134904175,  2968201710, 2132567223, 2248461478,  //  AutoContent_34_AIDNA_4
> -	   161963959,  3295327519, 670058472,  2013696856, 3608400883, 496651103,
> -	   733137541,  2952748738, 1159810205, 3886490843,  //  AutoContent_35_AIDNA_4
> -	   3225153820, 732007755,  2583635732, 4271028825, 1217674278, 4043323645,
> -	   1857109651, 2248481623, 3899721011, 3081298269,  //  AutoContent_36_AIDNA_4
> -	   1277901016, 1255642150, 2384261818, 2866704864, 755617465,  835768208,
> -	   1394358417, 4012239945, 2601238115, 3933467106  //  AutoContent_37_AIDNA_4
> -	};
> -	assert(kFNeuronPoolSize == f_neurons_D.size());
> -
>  	primary_parent = std::rand() % 4;
>  	const uint8_t parent2 = std::rand() % 4;
>  
> +	std::vector<int16_t> AI_military_numbers_P1(kMagicNumbersSize);
> +	std::vector<int8_t> input_weights_P1(kNeuronPoolSize);
> +	std::vector<int8_t> input_func_P1(kNeuronPoolSize);
> +	std::vector<uint32_t> f_neurons_P1(kFNeuronPoolSize);
> +	ai_dna_handler.fetch_dna(
> +	   AI_military_numbers_P1, input_weights_P1, input_func_P1, f_neurons_P1, primary_parent + 1);
> +
> +	std::vector<int16_t> AI_military_numbers_P2(kMagicNumbersSize);
> +	std::vector<int8_t> input_weights_P2(kNeuronPoolSize);
> +	std::vector<int8_t> input_func_P2(kNeuronPoolSize);
> +	std::vector<uint32_t> f_neurons_P2(kFNeuronPoolSize);
> +	ai_dna_handler.fetch_dna(
> +	   AI_military_numbers_P2, input_weights_P2, input_func_P2, f_neurons_P2, parent2 + 1);
> +
>  	log("    ... Primary parent: %d, secondary parent: %d\n", primary_parent, parent2);
>  
>  	// First setting of military numbers, they go directly to persistent data
>  	for (uint16_t i = 0; i < kMagicNumbersSize; i += 1) {
> -		// Child inherits DNA with probability 5:1 from main parent
> -		uint8_t dna_donor = (std::rand() % kSecondParentProbability > 0) ? primary_parent : parent2;
> +		// Child inherits DNA with probability 1/kSecondParentProbability from main parent
> +		uint8_t dna_donor = ((std::rand() % kSecondParentProbability) > 0) ? 0 : 1;

0 and 1 are recurring values, use an enum class?

>  		if (i == kMutationRatePosition) {  // Overwriting
> -			dna_donor = primary_parent;
> +			dna_donor = 0;
>  		}
>  
>  		switch (dna_donor) {
>  		case 0:
> -			set_military_number_at(i, AI_initial_military_numbers_A[i]);
> +			set_military_number_at(i, AI_military_numbers_P1[i]);
>  			break;
>  		case 1:
> -			set_military_number_at(i, AI_initial_military_numbers_B[i]);
> -			break;
> -		case 2:
> -			set_military_number_at(i, AI_initial_military_numbers_C[i]);
> -			break;
> -		case 3:
> -			set_military_number_at(i, AI_initial_military_numbers_D[i]);
> +			set_military_number_at(i, AI_military_numbers_P2[i]);
>  			break;
>  		default:
> -			log("parent %d?\n", dna_donor);
> +			log("Invalid dna_donor for military numbers: %d?\n", dna_donor);
>  			NEVER_HERE();
>  		}
>  	}
> @@ -1000,6 +634,11 @@
>  		log("%2d: Very weak mode, increasing mutation probability to 1 / %d\n", pn, probability);
>  	}
>  
> +	// Widlcard for ai trainingmode

Widlcard -> Wildcard

> +	if (kAITrainingMode && std::rand() % 8 == 0) {
> +		probability /= 3;
> +	}
> +
>  	assert(probability > 0 && probability <= 201);
>  
>  	log("%2d: mutating DNA with probability 1 / %3d:\n", pn, probability);
> @@ -1152,59 +794,8 @@
>  	return;
>  }
>  
> -// Print DNA data to console, used for training
> -// TODO(tiborb): Once we will have AI dumped into files, this should be removed
> -// Also, used only for training
> -void ManagementData::dump_data() {
> -	// dumping new numbers
> -	log("     actual military_numbers (%lu):\n      {", pd->magic_numbers.size());
> -	uint16_t itemcounter = 1;
> -	uint16_t line_counter = 1;
> -	for (const auto& item : pd->magic_numbers) {
> -		log(" %3d%s", item, (&item != &pd->magic_numbers.back()) ? ", " : "  ");
> -		if (itemcounter % 10 == 0) {
> -			log(" //  AutoContent_%02d\n       ", line_counter);
> -			line_counter += 1;
> -		}
> -		++itemcounter;
> -	}
> -	log("}\n");
> -
> -	log("     actual neuron setup:\n      ");
> -	log("{ ");
> -	itemcounter = 1;
> -	for (auto& item : neuron_pool) {
> -		log(" %3d%s", item.get_weight(), (&item != &neuron_pool.back()) ? ", " : "  ");
> -		if (itemcounter % 10 == 0) {
> -			log(" //  AutoContent_%02d\n       ", line_counter);
> -			line_counter += 1;
> -		}
> -		++itemcounter;
> -	}
> -	log("}\n      { ");
> -	itemcounter = 1;
> -	for (auto& item : neuron_pool) {
> -		log(" %3d%s", item.get_type(), (&item != &neuron_pool.back()) ? ", " : "  ");
> -		if (itemcounter % 10 == 0) {
> -			log(" //  AutoContent_%02d\n       ", line_counter);
> -			line_counter += 1;
> -		}
> -		++itemcounter;
> -	}
> -	log("}\n");
> -
> -	log("     actual f-neuron setup:\n      ");
> -	log("{ ");
> -	itemcounter = 1;
> -	for (auto& item : f_neuron_pool) {
> -		log(" %8u%s", item.get_int(), (&item != &f_neuron_pool.back()) ? ", " : "  ");
> -		if (itemcounter % 10 == 0) {
> -			log(" //  AutoContent_%02d\n       ", line_counter);
> -			line_counter += 1;
> -		}
> -		++itemcounter;
> -	}
> -	log("}\n");
> +void ManagementData::dump_data(const PlayerNumber pn) {
> +	ai_dna_handler.dump_output(pd, pn);

Is pd a class member? Should be _pd then. It's also not clear what pd means, please use a longer name.

>  }
>  
>  // Querying military number at a possition
> 
> === modified file 'src/ai/ai_help_structs.h'
> --- src/ai/ai_help_structs.h	2017-06-28 19:31:08 +0000
> +++ src/ai/ai_help_structs.h	2017-07-24 20:38:49 +0000
> @@ -635,9 +637,18 @@
>  	void mutate(PlayerNumber = 0);
>  	void new_dna_for_persistent(uint8_t, Widelands::AiType);
>  	void copy_persistent_to_local();
> -	void review(
> -	   uint32_t, PlayerNumber, uint32_t, uint32_t, uint32_t, uint16_t, int16_t, int16_t, uint16_t);
> -	void dump_data();
> +	void review(uint32_t,

Can you give some names to the variables? It's impossible to guess what they mean.

> +	            PlayerNumber,
> +	            uint32_t,
> +	            uint32_t,
> +	            uint32_t,
> +	            uint16_t,
> +	            int16_t,
> +	            int16_t,
> +	            uint16_t,
> +	            uint16_t,
> +	            uint32_t);
> +	void dump_data(PlayerNumber);
>  	uint16_t new_neuron_id() {
>  		++next_neuron_id;
>  		return next_neuron_id - 1;
> 
> === modified file 'src/ai/defaultai.cc'
> --- src/ai/defaultai.cc	2017-06-28 08:50:42 +0000
> +++ src/ai/defaultai.cc	2017-07-24 20:38:49 +0000
> @@ -3820,6 +3833,11 @@
>  
>  	// Wells handling
>  	if (site.bo->is(BuildingAttribute::kWell)) {
> +		// Never get bellow target count of wells

bellow -> below

> +		if (site.bo->total_count() <= site.bo->cnt_target) {
> +			return false;
> +		}
> +
>  		if (site.unoccupied_till + 6 * 60 * 1000 < gametime &&
>  		    site.site->get_statistics_percent() == 0) {
>  			site.bo->last_dismantle_time = gametime;
> @@ -5230,6 +5283,31 @@
>  	return count;
>  }
>  
> +// Calculates ratio of building that the player has in comparison to all buildings that are

building that the player has -> the buildings that the player has

> +// buildable by the player
> +// In range 0 - 1000, to avoid floats
> +uint32_t DefaultAI::count_productionsites_without_buildings() {
> +	uint32_t total = 0;
> +	uint32_t existing = 0;
> +	if (tribe_ == nullptr) {
> +		late_initialization();
> +	}
> +
> +	for (BuildingObserver& bo : buildings_) {
> +		if (bo.type == BuildingObserver::Type::kProductionsite &&
> +		    bo.is(BuildingAttribute::kBuildable)) {
> +			total += 1;
> +			if (bo.cnt_built > 0) {
> +				existing += 1000;
> +			} else if (bo.cnt_under_construction > 0) {
> +				existing += 500;
> +			}
> +		}
> +	}
> +
> +	return existing / total;
> +}
> +
>  // \returns the building observer
>  BuildingObserver& DefaultAI::get_building_observer(char const* const name) {
>  	if (tribe_ == nullptr) {
> 
> === modified file 'src/helper.cc'
> --- src/helper.cc	2017-05-31 21:27:07 +0000
> +++ src/helper.cc	2017-07-24 20:38:49 +0000
> @@ -53,3 +53,6 @@
>  		return result;
>  	throw wexception("expected word");
>  }
> +

You can lose the blank lines -> smaller diff

> +
> +
> 
> === added file 'src/logic/ai_dna_handler.cc'
> --- src/logic/ai_dna_handler.cc	1970-01-01 00:00:00 +0000
> +++ src/logic/ai_dna_handler.cc	2017-07-24 20:38:49 +0000
> @@ -0,0 +1,137 @@
> +/*
> + * Copyright (C) 2002-2017 by the Widelands Development Team

2002-2017 -> 2017

> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + *
> + */
> +
> +#include "logic/ai_dna_handler.h"
> +
> +#include <cstring>
> +#include <ctime>
> +#include <memory>
> +
> +#include <boost/algorithm/string.hpp>
> +#include <boost/format.hpp>
> +
> +#include "base/macros.h"
> +#include "base/wexception.h"
> +#include "logic/constants.h"
> +#include "wui/interactive_base.h"
> +
> +#define AI_SUFFIX "wai"
> +
> +namespace Widelands {
> +
> +AiDnaHandler::AiDnaHandler() {
> +	g_fs->ensure_directory_exists(get_base_dir());
> +}
> +
> +// this reads AI file for particular slot (position) and populate numbers into passed vectors

// This reads the AI file for a particular slot (position) and populates numbers into passed vectors.
// Slots are numbers 1 - 4 as we have 4 possible input files with an AI's DNA.

> +// slots are numbers  1 - 4 as we have 4 possible input files with AI's DNA
> +void AiDnaHandler::fetch_dna(std::vector<int16_t>& military_numbers,
> +                             std::vector<int8_t>& input_weights,
> +                             std::vector<int8_t>& input_func,
> +                             std::vector<uint32_t>& f_neurons,
> +                             uint8_t slot) {
> +
> +	// AI files are in range 1-4
> +	assert(slot > 0 && slot < 5);
> +
> +	std::string full_filename = get_base_dir() + g_fs->file_separator() + "ai_input_" +
> +	                            std::to_string(static_cast<int16_t>(slot)) + "." + AI_SUFFIX;
> +
> +	Profile prof;
> +	prof.read(full_filename.c_str(), nullptr, *g_fs);
> +	Section& mn = prof.get_safe_section("magic_numbers");
> +	for (uint16_t i = 0; i < military_numbers.size(); i++) {
> +		int32_t value = mn.get_int(std::to_string(static_cast<int32_t>(i)).c_str());
> +		if (value < -100 || value > 100) {
> +			throw wexception("Out of range AI data in magic_numbers section: %d\n", i);
> +		}
> +		military_numbers[i] = static_cast<int16_t>(value);
> +	}
> +
> +	Section& nv = prof.get_safe_section("neuron_values");
> +	for (uint16_t i = 0; i < input_weights.size(); i++) {
> +		int32_t value = nv.get_int(std::to_string(static_cast<int32_t>(i)).c_str());
> +		if (value < -100 || value > 100) {
> +			throw wexception("Out of range  AI data in neuron_values section: %d\n", i);

Double blank space: range  AI -> range AI

> +		}
> +		input_weights[i] = static_cast<int8_t>(value);
> +	}
> +
> +	Section& nf = prof.get_safe_section("neuron_functions");
> +	for (uint16_t i = 0; i < input_func.size(); i++) {
> +		int32_t value = nf.get_int(std::to_string(static_cast<int32_t>(i)).c_str());
> +		if (value < 0 || value > 3) {
> +			throw wexception("Out of range  AI data in neuron_functions section: %d\n", i);

Double blank space: range  AI -> range AI

> +		}
> +		input_func[i] = static_cast<int8_t>(value);
> +	}
> +
> +	Section& fn = prof.get_safe_section("fneurons");
> +	for (uint16_t i = 0; i < f_neurons.size(); i++) {
> +		uint32_t value = fn.get_natural(std::to_string(static_cast<int32_t>(i)).c_str());
> +
> +		f_neurons[i] = value;

Assign directly to f_neurons[i], since nothing else is done with it. Unless you want to add a range check too?

> +	}
> +}
> +
> +// this generate new file with AI data in home folder - in ai folder

// This generates a new file with AI data in '.widelands/ai'

> +void AiDnaHandler::dump_output(Widelands::Player::AiPersistentState* pd, uint8_t pn) {
> +
> +	time_t t;
> +	time(&t);
> +	struct tm* currenttime = localtime(&t);
> +
> +	std::string timestamp =
> +	   str(boost::format("%d-%02d-%02dT%02d.%02d.%02d") % (1900 + currenttime->tm_year) %
> +	       (currenttime->tm_mon + 1) % currenttime->tm_mday % currenttime->tm_hour %
> +	       currenttime->tm_min % currenttime->tm_sec);

This timestamp looks familiar. Is it the same as used by game save files? In that case, we could pull out a common function and put it in base/time_string

> +
> +	std::string full_filename = get_base_dir() + g_fs->file_separator() + timestamp + "_ai_player_" +
> +	                            std::to_string(static_cast<int16_t>(pn)) + "." + AI_SUFFIX;
> +
> +	printf(" %d: AI to be dumped to %s\n", pn, full_filename.c_str());
> +
> +	Profile prof;
> +
> +	Section& mn = prof.create_section("magic_numbers");
> +	assert(pd->magic_numbers_size == pd->magic_numbers.size());
> +	for (uint16_t i = 0; i < pd->magic_numbers_size; ++i) {

If pd->magic_numbers etc. are containers (e.g. vectors), we should use size_t here instead of uint16_t (both for reading and writing all profile sections).

> +		mn.set_int(std::to_string(static_cast<int32_t>(i)).c_str(), pd->magic_numbers[i]);

Why the static_cast? to_string can handle unsigned types.

This goes for all get/set calls.

> +	}
> +
> +	Section& nv = prof.create_section("neuron_values");
> +	assert(pd->neuron_pool_size == pd->neuron_weights.size());
> +	for (uint16_t i = 0; i < pd->neuron_pool_size; ++i) {
> +		nv.set_int(std::to_string(static_cast<int32_t>(i)).c_str(), pd->neuron_weights[i]);
> +	}
> +
> +	Section& nf = prof.create_section("neuron_functions");
> +	assert(pd->neuron_pool_size == pd->neuron_functs.size());
> +	for (uint16_t i = 0; i < pd->neuron_pool_size; ++i) {
> +		nf.set_int(std::to_string(static_cast<int32_t>(i)).c_str(), pd->neuron_functs[i]);
> +	}
> +
> +	Section& fn = prof.create_section("fneurons");
> +	assert(pd->f_neuron_pool_size == pd->f_neurons.size());
> +	for (uint16_t i = 0; i < pd->f_neuron_pool_size; ++i) {
> +		fn.set_natural(std::to_string(static_cast<int64_t>(i)).c_str(), pd->f_neurons[i]);
> +	}
> +	prof.write(full_filename.c_str(), false, *g_fs);
> +}
> +}
> 
> === added file 'src/logic/ai_dna_handler.h'
> --- src/logic/ai_dna_handler.h	1970-01-01 00:00:00 +0000
> +++ src/logic/ai_dna_handler.h	2017-07-24 20:38:49 +0000
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright (C) 2007-2017 by the Widelands Development Team

2007-2017 -> 2017

> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + *
> + */
> +
> +#ifndef WL_LOGIC_AI_DUMP_H

WL_LOGIC_AI_DNA_HANDLER_H

> +#define WL_LOGIC_AI_DUMP_H
> +
> +#include <cstring>
> +#include <string>
> +
> +#include <stdint.h>
> +
> +#include "base/time_string.h"
> +#include "logic/game.h"
> +#include "logic/player.h"
> +
> +namespace Widelands {
> +
> +/**
> + * This handles reading and saving AI DNA to files
> + * - reading when initializing new AI
> + * - saving AI into files (with timestamp and player number) after mutation
> + */
> +class AiDnaHandler {
> +public:
> +	AiDnaHandler();
> +
> +	static std::string get_base_dir() {
> +		return "ai";
> +	}
> +
> +	void fetch_dna(std::vector<int16_t>&,
> +	               std::vector<int8_t>&,
> +	               std::vector<int8_t>&,
> +	               std::vector<uint32_t>&,
> +	               uint8_t);
> +	void dump_output(Widelands::Player::AiPersistentState* pd, uint8_t);
> +};
> +}
> +#endif  // end of include guard: WL_LOGIC_AI_DUMP_H

WL_LOGIC_AI_DNA_HANDLER_H

> 
> === modified file 'src/profile/profile.cc'
> --- src/profile/profile.cc	2017-07-05 00:26:07 +0000
> +++ src/profile/profile.cc	2017-07-24 20:38:49 +0000
> @@ -444,6 +444,10 @@
>  	set_string(name, std::to_string(value));
>  }
>  
> +void Section::set_natural(char const* const name, uint32_t const value) {
> +	set_string(name, std::to_string(static_cast<int64_t>(value)));

No need for the static_cast here.

> +}
> +
>  void Section::set_string(char const* const name, char const* string) {
>  	create_val(name, string).mark_used();
>  }
> 
> === modified file 'src/wlapplication.cc'
> --- src/wlapplication.cc	2017-06-20 19:55:32 +0000
> +++ src/wlapplication.cc	2017-07-24 20:38:49 +0000
> @@ -101,6 +101,8 @@
>  // The time in seconds for how long old replays/syncstreams should be kept
>  // around, in seconds. Right now this is 4 weeks.
>  constexpr double kReplayKeepAroundTime = 4 * 7 * 24 * 60 * 60;
> +// Similary we delete AI files older then one week

then -> than

> +constexpr double kAIFilesKeepAroundTime = 7 * 24 * 60 * 60;
>  
>  /**
>   * Shut the hardware down: stop graphics mode, stop sound handler
> @@ -182,11 +184,11 @@
>  
>  // Extracts a long from 'text' into 'val' returning true if all of the string
>  // was valid. If not, the content of 'val' is undefined.
> -bool to_long(const std::string& text, long* val) {
> -	const char* start = text.c_str();
> -	char* end;
> -	*val = strtol(start, &end, 10);
> -	return *end == '\0';
> + bool to_long(const std::string& text, long* val) {
> + const char* start = text.c_str();
> + char* end;
> +*val = strtol(start, &end, 10);
> + return *end == '\0';

Revert the indentation.

>  }
>  
>  // Extracts the creation date from 'path' which is expected to
> @@ -1402,6 +1406,23 @@
>  	}
>  }
>  
> +/**
> + * Delete old ai dna files generated during AI initialization
> + */
> +void WLApplication::cleanup_ai_files() {
> +	for (const std::string& filename :
> +	     filter(g_fs->list_directory("ai"),  // NOCOM repace with common defineds
> +	                                         // used by both locations (here and ai_dna_handler)

Implement the NOCOM.

> +	            [](const std::string& fn) {
> +		            return boost::ends_with(fn, "wai") || boost::contains(fn, "ai_player");
> +		         })) {
> +		if (is_autogenerated_and_expired(filename, kAIFilesKeepAroundTime)) {
> +			log("Deleting generated ai file: %s\n", filename.c_str());
> +			g_fs->fs_unlink(filename);
> +		}
> +	}
> +}
> +
>  bool WLApplication::redirect_output(std::string path) {
>  	if (path.empty()) {
>  #ifdef _WIN32


-- 
https://code.launchpad.net/~widelands-dev/widelands/ai_dna_dump/+merge/327988
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/ai_dna_dump into lp:widelands.


References