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. double * input = new double[whichFeatures.size()];
  27. for(int i = 0; i < whichFeatures.size();i++)
  28. input[i]=stateFeatures[whichFeatures[i]];
  29. float ans = net.feedForwardPattern(input)[0];
  30. delete input;
  31. return ans;
  32. }
  33. Priorities::Priorities()//random brain
  34. :numSpecialFeatures(8)
  35. {
  36. /* vector<unsigned int> whichFeatures;//(512);
  37. whichFeatures.push_back(16);
  38. whichFeatures.push_back(17);
  39. networks.push_back(Network(whichFeatures)); //for a friendly hero
  40. networks.push_back(Network(whichFeatures)); //for an enemy hero
  41. whichFeatures.clear();
  42. whichFeatures.push_back(16); //hero's AI value
  43. networks.push_back(Network(whichFeatures)); //for school of magic
  44. whichFeatures.clear();
  45. for(int i = 0; i <=16;i++)
  46. whichFeatures.push_back(i); //hero's AI value is 16
  47. networks.push_back(Network(whichFeatures)); //for treasure chest
  48. whichFeatures.clear();
  49. whichFeatures.push_back(17);
  50. networks.push_back(Network(whichFeatures)); //for a friendly town
  51. networks.push_back(Network(whichFeatures)); //for an enemy town
  52. whichFeatures.clear();
  53. whichFeatures.push_back(16);
  54. networks.push_back(Network(whichFeatures)); //for learning stone
  55. */
  56. }
  57. Priorities::Priorities(const string & filename) //read brain from file
  58. :numSpecialFeatures(8)
  59. {
  60. ifstream infile(filename.c_str());
  61. // object_num [list of features]
  62. // brain data or "R" for random brain
  63. networks.resize(255);
  64. int object_num;
  65. while(infile>>object_num)
  66. {
  67. networks[object_num].push_back(Network(infile));
  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()==0)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!=NULL) //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(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:
  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 networks[34][0].feedForward(stateFeatures);
  152. }
  153. else
  154. {
  155. stateFeatures[17] = dynamic_cast<const CGHeroInstance*>(hobj->object)->getTotalStrength();
  156. return networks[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 networks[98][0].feedForward(stateFeatures);
  164. }
  165. else
  166. {
  167. stateFeatures[17] = dynamic_cast<const CGTownInstance*>(hobj->object)->getArmyStrength();
  168. return networks[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 networks[53][hobj->object->subID].feedForward(stateFeatures);
  183. case 113://TODO: replace with value of skill for the hero
  184. return 0;
  185. case 103:case 58://TODO: replace with value of seeing x number of new tiles
  186. return 0;
  187. default:
  188. if(networks[hobj->object->ID].size()!=0)
  189. return networks[hobj->object->ID][0].feedForward(stateFeatures);
  190. cout << "don't know the value of ";
  191. switch(obj.type)
  192. {
  193. case CGeniusAI::AIObjective::visit:
  194. cout << "visiting " << hobj->object->ID;
  195. break;
  196. case CGeniusAI::AIObjective::attack:
  197. cout << "attacking " << hobj->object->ID;
  198. break;
  199. case CGeniusAI::AIObjective::finishTurn:
  200. obj.print();
  201. break;
  202. }
  203. cout << endl;
  204. }
  205. }
  206. else //town objective
  207. {
  208. }
  209. return 0;
  210. }
  211. #endif