AIPriorities.cpp 7.2 KB

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