1 /** 2 * Copyright: © 2012-2014 Anton Gushcha 3 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 4 * Authors: NCrashed <ncrashed@gmail.com>, 5 * LeMarwin <lemarwin42@gmail.com>, 6 * Nazgull09 <nazgull90@gmail.com> 7 */ 8 module devol.compiler; 9 10 import std.stdio; 11 import std.array; 12 13 import devol.singleton; 14 import core.time; 15 import core.thread; 16 17 public 18 { 19 import devol.typemng; 20 import devol.operatormng; 21 import devol.population; 22 import devol.evolutor; 23 import devol.programtype; 24 } 25 26 struct SequentCompilation 27 { 28 static void initPop( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType ) 29 { 30 foreach( ind; pop ) 31 { 32 ind.invals = progType.initValues( world ); 33 ind.outvals = new Line[0]; 34 } 35 } 36 37 static void compilePop( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType, bool delegate() whenExit ) 38 { 39 writeln("Entered compile method"); 40 foreach ( ind; pop ) 41 { 42 if(whenExit()) return; 43 writeln("Taking indivi"); 44 foreach( line; ind.program ) 45 { 46 if(whenExit()) return; 47 writeln("Compiling line"); 48 line.compile(ind, world); 49 } 50 } 51 } 52 53 static void calcPopFitness( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType ) 54 { 55 uint i =0; 56 ulong summ = 0; 57 foreach( ind; pop ) 58 { 59 writeln("Individ №",i++); 60 ind.fitness = progType.getFitness(ind, world, 0); 61 summ += ind.fitness; 62 writeln("Fitness = ", ind.fitness ); 63 } 64 auto asumm = cast(double)summ/pop.length; 65 writeln("Average fitness = ", asumm); 66 } 67 } 68 69 struct GameCompilation(alias stopCond, alias drawStep, alias drawFinal, int roundsPerInd) 70 { 71 static void initPop( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType ) 72 { 73 foreach( ind; pop ) 74 { 75 ind.invals = progType.initValues( world ); 76 ind.outvals = new Line[0]; 77 } 78 } 79 80 static void compilePop( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType, bool delegate() whenExit ) 81 { 82 writeln("Entered compile method"); 83 84 foreach ( ind; pop ) 85 { 86 auto fitts = new double[roundsPerInd]; 87 foreach(j; 0..roundsPerInd) 88 { 89 if(whenExit()) return; 90 world.initialize(); 91 int step = 0; 92 ind.initialize(); 93 while( !stopCond( step, ind, world ) ) 94 { 95 96 foreach( line; ind.program ) 97 { 98 if(whenExit()) return; 99 writeln("Compiling line"); 100 line.compile(ind, world); 101 drawStep(ind, world); 102 } 103 104 step++; 105 } 106 fitts[j] = progType.getFitness(ind, world, 0); 107 } 108 double summ = 0; 109 foreach(val; fitts) 110 summ+=val; 111 ind.fitness = summ/fitts.length; 112 } 113 } 114 115 static void calcPopFitness( PopAbstract pop, WorldAbstract world, ProgTypeAbstract progType ) 116 { 117 uint i =0; 118 ulong summ = 0; 119 foreach( ind; pop ) 120 { 121 writeln("Individ №",i++); 122 //ind.fitness = progType.getFitness(ind, world, 0); 123 summ += ind.fitness; 124 writeln("Fitness = ", ind.fitness ); 125 } 126 127 drawFinal(pop, world); 128 auto asumm = cast(double)summ/pop.length; 129 writeln("Average fitness = ", asumm); 130 } 131 } 132 133 class Compiler( 134 CompStg = SequentCompilation, 135 EvolutorStg = Evolutor, 136 ProgType, 137 PopType, 138 WorldType) 139 if( __traits(compiles, "PopAbstract pop = new PopType()") ) 140 : Singleton!Compiler 141 { 142 public: 143 144 this() 145 { 146 //super(this); 147 //if ( OperatorMng.getSingleton() is null ) 148 // new OperatorMng(); 149 150 //if ( TypeMng.getSingleton() is null ) 151 // new TypeMng(); 152 153 evolutor = new EvolutorStg(); 154 pops = new PopType[0]; 155 world = new WorldType(); 156 progtype = new ProgType(); 157 } 158 159 void addPop(PopType pop) 160 { 161 if (pop is null || !checkPop(pop)) return; 162 163 pops ~= pop; 164 } 165 166 PopType getPop(uint i) 167 { 168 return pops[i]; 169 } 170 171 PopType addPop(int size, string name="") 172 { 173 auto pop = new PopType(size); 174 175 if (name.empty) 176 pop.genName(); 177 else 178 pop.name = name; 179 180 181 foreach(ref ind; pop) 182 { 183 evolutor.generateInitProgram(ind, progtype); 184 } 185 186 debug writeln("Created population ", pop.name, " size of ", size); 187 188 pops ~= pop; 189 return pop; 190 } 191 192 void envolveGeneration(bool delegate() whenExit) 193 { 194 writeln("Entering comp..."); 195 foreach( ref pop; pops ) 196 { 197 writeln("Pop init"); 198 CompStg.initPop( pop, world, progtype ); 199 if(whenExit()) return; 200 201 writeln("Pop compile"); 202 CompStg.compilePop( pop, world, progtype, whenExit); 203 if(whenExit()) return; 204 205 writeln("GENERATION №", pop.generation, " results:"); 206 CompStg.calcPopFitness( pop, world, progtype ); 207 scope(exit) 208 { 209 pop.saveBests("saves/AntsBests/"); 210 pop.saveAll("saves/AntsAll/"); 211 } 212 213 if(whenExit()) return; 214 pop = evolutor.formNextPopulation( pop, progtype ); 215 pop.generation = pop.generation + 1; 216 if(whenExit()) return; 217 } 218 } 219 220 protected: 221 222 PopType[] pops; 223 WorldAbstract world; 224 ProgTypeAbstract progtype; 225 EvolutorStg evolutor; 226 227 bool checkPop(PopAbstract pop) 228 { 229 foreach(p; pops) 230 { 231 if (p == pop) return false; 232 } 233 return true; 234 } 235 236 }