AIPriorities.cpp 7.1 KB

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