AIPriorities.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #ifndef AI_PRIORITIES
  2. #define AI_PRIORITIES
  3. #include "AIPriorities.h"
  4. #include <sstream>
  5. // TODO: No using namespace!!
  6. using namespace geniusai;
  7. Network::Network()
  8. {}
  9. Network::Network(vector<unsigned int> whichFeatures)// random network
  10. : net(whichFeatures.size(),
  11. whichFeatures.size() * 0.601 + 2,
  12. whichFeatures.size() * 0.251 + 2,
  13. 1),
  14. whichFeatures(whichFeatures)
  15. {
  16. }
  17. Network::Network(istream & input)
  18. {
  19. // vector<int> whichFeatures;
  20. int feature;
  21. string line;
  22. getline(input,line);
  23. stringstream lineIn(line);
  24. while(lineIn>>feature)
  25. whichFeatures.push_back(feature);
  26. getline(input, line);//get R
  27. net = neuralNetwork(whichFeatures.size(),
  28. whichFeatures.size() * 0.601 + 2,
  29. whichFeatures.size() * 0.251 + 2,
  30. 1);
  31. }
  32. float Network::feedForward(const vector<float> & stateFeatures)
  33. {
  34. // TODO: Should comment/rewrite it...
  35. return (rand() % 1000) / 800.0f;
  36. double * input = new double[whichFeatures.size()];
  37. for (int i = 0; i < whichFeatures.size(); i++)
  38. input[i] = stateFeatures[whichFeatures[i]];
  39. float ans = net.feedForwardPattern(input)[0];
  40. delete input;
  41. return ans;
  42. }
  43. Priorities::Priorities(const string & filename) //read brain from file
  44. :numSpecialFeatures(8)
  45. {
  46. ifstream infile(filename.c_str());
  47. // object_num [list of features]
  48. // brain data or "R" for random brain
  49. objectNetworks.resize(255);
  50. buildingNetworks.resize(9);
  51. char type;
  52. int object_num;
  53. int town_num;
  54. int building_num;
  55. while(infile>>type)
  56. {
  57. switch(type)
  58. {
  59. case 'o'://map object
  60. infile >> object_num;
  61. objectNetworks[object_num].push_back(Network(infile));
  62. break;
  63. case 't'://town building
  64. infile >> town_num >> building_num;
  65. buildingNetworks[town_num][building_num]=Network(infile);
  66. break;
  67. }
  68. }
  69. }
  70. void Priorities::fillFeatures(const CGeniusAI::HypotheticalGameState & hgs)
  71. {
  72. stateFeatures.clear();
  73. stateFeatures.resize(50);
  74. for(int i = 0; i < stateFeatures.size(); i++)
  75. stateFeatures[i]=0;
  76. for(int i = 0; i < hgs.resourceAmounts.size();i++) //features 0-7 are resources
  77. stateFeatures[i]=hgs.resourceAmounts[i];
  78. //TODO: //features 8-15 are incomes
  79. specialFeaturesStart = 16; //features 16-23 are special features (filled in by get functions before ANN)
  80. stateFeatures[24] = hgs.AI->m_cb->getDate();
  81. stateFeatures[25] = 1;
  82. }
  83. float Priorities::getCost(vector<int> &resourceCosts,const CGHeroInstance * moved,int distOutOfTheWay)
  84. {
  85. if(!resourceCosts.size())return -1;
  86. //TODO: replace with ann
  87. float cost = resourceCosts[0]/4.0+resourceCosts[1]/2.0+resourceCosts[2]/4.0+resourceCosts[3]/2.0+resourceCosts[4]/2.0+resourceCosts[5]/2.0+resourceCosts[6]/3000.0;
  88. if(moved) //TODO: multiply by importance of hero
  89. cost+=distOutOfTheWay/10000.0;
  90. return cost;
  91. }
  92. float Priorities::getValue(const CGeniusAI::AIObjective & obj)
  93. { //resource
  94. vector<int> resourceAmounts(8,0);
  95. int amount;
  96. if(obj.type==CGeniusAI::AIObjective::finishTurn) //TODO: replace with value of visiting that object divided by days till completed
  97. return .0001; //small nonzero
  98. float a;
  99. if(obj.type==CGeniusAI::AIObjective::attack)
  100. return 100;
  101. if(dynamic_cast<const CGeniusAI::HeroObjective* >(&obj))
  102. {
  103. const CGeniusAI::HeroObjective* hobj = dynamic_cast<const CGeniusAI::HeroObjective* >(&obj);
  104. stateFeatures[16] = hobj->whoCanAchieve.front()->h->getTotalStrength();
  105. if(dynamic_cast<const CArmedInstance*>(hobj->object))
  106. stateFeatures[17] = dynamic_cast<const CArmedInstance*>(hobj->object)->getArmyStrength();
  107. switch(hobj->object->ID)
  108. {
  109. case 5: //artifact //TODO: return value of each artifact
  110. return 0;
  111. case 79://resources on the ground
  112. switch(hobj->object->subID)
  113. {
  114. case 6:
  115. amount = 800;
  116. break;
  117. case 0: case 2:
  118. amount = 9.5; //will be rounded, sad
  119. break;
  120. default:
  121. amount = 4;
  122. break;
  123. }
  124. resourceAmounts[hobj->object->subID]=amount;
  125. return getCost(resourceAmounts,NULL,0);
  126. break;
  127. case 55://mystical garden
  128. resourceAmounts[6]=500;
  129. a=getCost(resourceAmounts,NULL,0);
  130. resourceAmounts[6]=0;
  131. resourceAmounts[5]=5;
  132. return (a+getCost(resourceAmounts,NULL,0))*.5;
  133. case 109:
  134. resourceAmounts[6]=1000;
  135. return getCost(resourceAmounts,NULL,0);
  136. case 12://campfire
  137. resourceAmounts[6]=500;
  138. for(int i = 0; i < 6;i++)
  139. resourceAmounts[i]=1;
  140. return getCost(resourceAmounts,NULL,0);
  141. case 112://windmill
  142. for(int i = 1; i < 6;i++)//no wood
  143. resourceAmounts[i]=1;
  144. return getCost(resourceAmounts,NULL,0);
  145. break;
  146. case 49://magic well
  147. //TODO: add features for hero's spell points
  148. break;
  149. case 34: //hero
  150. if(dynamic_cast<const CGHeroInstance*>(hobj->object)->getOwner()==obj.AI->m_cb->getMyColor())//friendly hero
  151. {
  152. stateFeatures[17] = dynamic_cast<const CGHeroInstance*>(hobj->object)->getTotalStrength();
  153. return objectNetworks[34][0].feedForward(stateFeatures);
  154. }
  155. else
  156. {
  157. stateFeatures[17] = dynamic_cast<const CGHeroInstance*>(hobj->object)->getTotalStrength();
  158. return objectNetworks[34][1].feedForward(stateFeatures);
  159. }
  160. break;
  161. case 98:
  162. if(dynamic_cast<const CGTownInstance*>(hobj->object)->getOwner()==obj.AI->m_cb->getMyColor())//friendly town
  163. {
  164. stateFeatures[17] = dynamic_cast<const CGTownInstance*>(hobj->object)->getArmyStrength();
  165. return 0; // objectNetworks[98][0].feedForward(stateFeatures);
  166. }
  167. else
  168. {
  169. stateFeatures[17] = dynamic_cast<const CGTownInstance*>(hobj->object)->getArmyStrength();
  170. return 0; //objectNetworks[98][1].feedForward(stateFeatures);
  171. }
  172. break;
  173. case 88:
  174. //TODO: average value of unknown level 1 spell, or value of known spell
  175. case 89:
  176. //TODO: average value of unknown level 2 spell, or value of known spell
  177. case 90:
  178. //TODO: average value of unknown level 3 spell, or value of known spell
  179. return 0;
  180. break;
  181. case 215://quest guard
  182. return 0;
  183. case 53: //various mines
  184. return 0; //out of range crash
  185. //objectNetworks[53][hobj->object->subID].feedForward(stateFeatures);
  186. case 113://TODO: replace with value of skill for the hero
  187. return 0;
  188. case 103: case 58://TODO: replace with value of seeing x number of new tiles
  189. return 0;
  190. default:
  191. if (objectNetworks[hobj->object->ID].size())
  192. return objectNetworks[hobj->object->ID][0].feedForward(stateFeatures);
  193. tlog6 << "don't know the value of ";
  194. switch(obj.type)
  195. {
  196. case CGeniusAI::AIObjective::visit:
  197. tlog6 << "visiting " << hobj->object->ID;
  198. break;
  199. tlog6 << "attacking " << hobj->object->ID;
  200. break;
  201. case CGeniusAI::AIObjective::finishTurn:
  202. obj.print();
  203. break;
  204. }
  205. tlog6 << endl;
  206. }
  207. }
  208. else //town objective
  209. {
  210. if(obj.type == CGeniusAI::AIObjective::buildBuilding)
  211. {
  212. const CGeniusAI::TownObjective* tnObj = dynamic_cast<const CGeniusAI::TownObjective* >(&obj);
  213. if(buildingNetworks[tnObj->whichTown->t->subID].find(tnObj->which)!=buildingNetworks[tnObj->whichTown->t->subID].end())
  214. return buildingNetworks[tnObj->whichTown->t->subID][tnObj->which].feedForward(stateFeatures);
  215. else
  216. {
  217. tlog6 << "don't know the value of ";
  218. obj.print();
  219. tlog6 << endl;
  220. }
  221. }
  222. }
  223. return 0;
  224. }
  225. #endif