1 // Copyright (C) 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
2 // Copyright (C) 2003 Michael Bartl
3 // Copyright (C) 2004, 2006 Andrea Paternesi
4 // Copyright (C) 2004 John Farrell
5 // Copyright (C) 2006, 2007, 2008, 2009, 2014, 2015, 2017 Ben Asselstine
6 // Copyright (C) 2007, 2008 Ole Laursen
7 //
8 //  This program is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License as published by
10 //  the Free Software Foundation; either version 3 of the License, or
11 //  (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU Library General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 //  02110-1301, USA.
22 
23 #include <fstream>
24 #include <vector>
25 
26 #include "AI_Diplomacy.h"
27 #include "AI_Analysis.h"
28 #include "ai_fast.h"
29 
30 #include "playerlist.h"
31 #include "armysetlist.h"
32 #include "stacklist.h"
33 #include "citylist.h"
34 #include "city.h"
35 #include "templelist.h"
36 #include "ruinlist.h"
37 #include "path.h"
38 #include "GameMap.h"
39 #include "Threatlist.h"
40 #include "action.h"
41 #include "xmlhelper.h"
42 #include "stack.h"
43 #include "GameScenarioOptions.h"
44 #include "hero.h"
45 #include "vectoredunitlist.h"
46 #include "PathCalculator.h"
47 #include "stacktile.h"
48 #include "armyprodbase.h"
49 #include "QuestsManager.h"
50 #include "Quest.h"
51 #include "SightMap.h"
52 #include "Sage.h"
53 #include "rnd.h"
54 #include "GameScenarioOptions.h"
55 
56 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::flush<<std::endl;}
57 #define debug(x)
58 
AI_Fast(Glib::ustring name,guint32 armyset,Gdk::RGBA color,int width,int height,int player_no)59 AI_Fast::AI_Fast(Glib::ustring name, guint32 armyset, Gdk::RGBA color, int width, int height, int player_no)
60     :RealPlayer(name, armyset, color, width, height, Player::AI_FAST, player_no), d_join(true),
61     d_maniac(false), d_analysis(0), d_diplomacy(0)
62 {
63 }
64 
AI_Fast(const Player & player)65 AI_Fast::AI_Fast(const Player& player)
66     :RealPlayer(player), d_join(true), d_maniac(false), d_analysis(0),
67     d_diplomacy(0)
68 {
69     d_type = AI_FAST;
70 }
71 
AI_Fast(XML_Helper * helper)72 AI_Fast::AI_Fast(XML_Helper* helper)
73     :RealPlayer(helper), d_analysis(0), d_diplomacy(0)
74 {
75     helper->getData(d_join, "join");
76     helper->getData(d_maniac, "maniac");
77 }
78 
~AI_Fast()79 AI_Fast::~AI_Fast()
80 {
81     if (d_analysis)
82         delete d_analysis;
83     if (d_diplomacy)
84         delete d_diplomacy;
85 }
86 
save(XML_Helper * helper) const87 bool AI_Fast::save(XML_Helper* helper) const
88 {
89     bool retval = true;
90 
91     retval &= helper->openTag(Player::d_tag);
92     retval &= helper->saveData("join", d_join);
93     retval &= helper->saveData("maniac", d_maniac);
94     retval &= Player::save(helper);
95     retval &= helper->closeTag();
96 
97     return retval;
98 }
99 
abortTurn()100 void AI_Fast::abortTurn()
101 {
102   abort_requested = true;
103   if (surrendered)
104     aborted_turn.emit();
105   else if (Playerlist::getInstance()->countPlayersAlive() == 1)
106     aborted_turn.emit();
107 }
108 
startTurn()109 bool AI_Fast::startTurn()
110 {
111     sbusy.emit();
112     if (getStacklist()->getHeroes().size() == 0 &&
113         Citylist::getInstance()->countCities(this) == 1)
114       {
115         City *first = getFirstCity();
116         if (first)
117           AI_maybeBuyScout(first);
118         else
119           {
120             fprintf(stderr,"%s : we have 1 city but no first city?  impossible\n", getName().c_str());
121             for (auto c: *Citylist::getInstance())
122               {
123                 if (c->getOwner() == this)
124                   {
125                     fprintf(stderr, "Our city is %d\n", c->getId());
126                   }
127               }
128             exit (0);
129           }
130       }
131 
132     debug(getName() << ": AI_Fast::start_turn")
133     debug("being in " <<(d_maniac?"maniac":"normal") <<" mode")
134     debug((d_join?"":"not ") <<"joining armies")
135 
136     d_analysis = new AI_Analysis(this);
137     d_diplomacy = new AI_Diplomacy(this);
138 
139     d_diplomacy->considerCuspOfWar();
140 
141     d_maniac = false;
142     float ratio = 2.0;
143     if (getUpkeep() > getIncome() * ratio)
144       d_maniac = true;
145 
146     //setup production
147     debug("examining cities");
148     for (auto c: *Citylist::getInstance())
149       {
150         if (c->getOwner() != this || c->isBurnt())
151           continue;
152         if (c->getActiveProductionSlot() == -1)
153           setBestProduction(c);
154       }
155 
156     //setup vectoring
157     debug("setting up vectoring");
158     if (!d_maniac)
159 	AI_setupVectoring(18, 3, 30);
160 
161     debug("trying to complete quests");
162     //try to complete our quests
163     std::vector<Quest*> q = QuestsManager::getInstance()->getPlayerQuests(this);
164     for (std::vector<Quest*>::iterator it = q.begin(); it != q.end(); it++)
165       {
166         Quest *quest = *it;
167         if (quest->isPendingDeletion())
168           continue;
169         Stack *s = getStacklist()->getArmyStackById(quest->getHeroId());
170         if (!s)
171           continue;
172         bool stack_died = false;
173         bool quest_completed = false;
174         bool stack_moved = AI_maybeContinueQuest(s, quest, quest_completed,
175                                                  stack_died);
176 
177         if (stack_moved == true && stack_died == false)
178           GameMap::groupStacks(s);
179       }
180 
181     while (computerTurn() == true)
182       {
183 	bool found = false;
184 
185 	//are there any stacks with paths that can move?
186 	for (Stacklist::reverse_iterator it = d_stacklist->rbegin(); it != d_stacklist->rend(); it++)
187 	  {
188 	    Stack *s = (*it);
189 	    if (s->getPath()->size() > 0 && s->enoughMoves())
190 	      {
191 		int mp = s->getPath()->calculate(s, s->getLastPointInPath());
192 		if (mp <= 0)
193 		  continue;
194 		debug ("AI_FAST stack " << s->getId() << " can still potentially move");
195 		debug ("moving from (" << s->getPos().x << "," << s->getPos().y
196 		       << ") to (" <<s->getFirstPointInPath().x << "," <<
197 		       s->getFirstPointInPath().y << ") with " << s->getMoves() <<" left");
198 
199 
200 		found = true;
201 	      }
202 	    //are there any stacks without paths that still have some moves?
203 	    else if (s->getPath()->size() == 0 && s->getMoves() > 1)
204 	      found = true;
205 	  }
206 	sbusy.emit();
207 	if (!found)
208 	  break;
209 	if (found)
210 	  found = false;
211 	if (abort_requested)
212 	  break;
213       }
214     parkAllStacks();
215     sbusy.emit();
216     Glib::usleep (50000);
217     while (g_main_context_iteration(NULL, FALSE)); //doEvents
218     Glib::usleep (50000);
219 
220     delete d_analysis;
221     d_analysis = 0;
222 
223     d_stacklist->setActivestack(0);
224 
225     // Declare war with enemies, make peace with friends
226     if (GameScenarioOptions::s_diplomacy)
227       d_diplomacy->makeProposals();
228 
229     if (abort_requested)
230       aborted_turn.emit();
231     return !(Playerlist::getInstance()->getNoOfPlayers() <= 1);
232 }
233 
scoreArmyType(const ArmyProdBase * a)234 int AI_Fast::scoreArmyType(const ArmyProdBase *a)
235 {
236   int max_strength = a->getStrength();
237 
238   int production;
239   if (a->getProduction() == 1)
240     production = 6;
241   else if (a->getProduction() == 2)
242     production = 2;
243   else
244     production = 1;
245 
246   int upkeep = 0;
247   if (a->getUpkeep() < 5)
248     upkeep = 6;
249   else if (a->getUpkeep() < 10)
250     upkeep = 2;
251   else
252     upkeep = 1;
253 
254   int newcost = 0;
255   if (a->getProductionCost() < 5)
256     newcost = 6;
257   else if (a->getProductionCost() < 10)
258     newcost = 2;
259   else
260     newcost = 1;
261 
262   //we prefer armies that move farther
263   int move_bonus = 0;
264   if (a->getMaxMoves() >  10)
265     move_bonus += 2;
266   if (a->getMaxMoves() >=  20)
267     move_bonus += 4;
268 
269   return max_strength + move_bonus + production + upkeep + newcost;
270 }
271 
setBestProduction(City * c)272 int AI_Fast::setBestProduction(City *c)
273 {
274   int select = -1;
275   int score = -1;
276 
277   // we try to determine the most attractive basic production
278   for (guint32 i = 0; i < c->getMaxNoOfProductionBases(); i++)
279     {
280       if (c->getArmytype(i) == -1)    // no production in this slot
281         continue;
282 
283       const ArmyProdBase *proto = c->getProductionBase(i);
284       if (scoreArmyType(proto) > score)
285         {
286           select = i;
287           score = scoreArmyType(proto);
288         }
289     }
290 
291 
292   if (select != c->getActiveProductionSlot())
293     {
294       cityChangeProduction(c, select);
295       debug(getName() << " Set production to slot " << select << " in " << c->getName())
296     }
297 
298   return c->getActiveProductionSlot();
299 }
300 
invadeCity(City * c)301 void AI_Fast::invadeCity(City* c)
302 {
303   CityDefeatedAction action = CITY_DEFEATED_OCCUPY;
304   bool quest_preference = AI_invadeCityQuestPreference(c, action);
305   debug("Invaded city " <<c->getName());
306 
307   if (quest_preference == false)
308     {
309       if (getIncome() < getUpkeep())
310         action = CITY_DEFEATED_OCCUPY;
311       else if (d_maniac &&
312                GameScenarioOptions::s_razing_cities != GameParameters::NEVER)
313         action = CITY_DEFEATED_RAZE;
314       else
315         action = CITY_DEFEATED_OCCUPY;
316     }
317   int gold = 0;
318   int pillaged_army_type = -1;
319   std::list<guint32> sacked_army_types;
320   switch (action)
321     {
322     case CITY_DEFEATED_OCCUPY:
323       cityOccupy(c);
324       setBestProduction(c);
325       break;
326     case CITY_DEFEATED_PILLAGE:
327       cityPillage(c, gold, &pillaged_army_type);
328       AI_maybeBuyScout(c);
329       setBestProduction(c);
330       break;
331     case CITY_DEFEATED_RAZE:
332       cityRaze(c);
333       break;
334     case CITY_DEFEATED_SACK:
335       citySack(c, gold, &sacked_army_types);
336       AI_maybeBuyScout(c);
337       setBestProduction(c);
338       break;
339     }
340 }
341 
heroGainsLevel(Hero * a)342 void AI_Fast::heroGainsLevel(Hero * a)
343 {
344     debug("Army raised a level, id = " <<a->getId())
345 
346     //advancing a level
347     // increase the strength attack (uninnovative, but enough here)
348     Army::Stat stat = Army::STRENGTH;
349     doHeroGainsLevel(a, stat);
350     addAction(new Action_Level(a, stat));
351 }
352 
findNearOwnStackToJoin(Stack * src,int max_distance)353 Stack *AI_Fast::findNearOwnStackToJoin(Stack *src, int max_distance)
354 {
355   int min_mp = -1;
356   std::vector<Stack*> stks =
357     GameMap::getNearbyFriendlyStacks(src->getPos(), max_distance);
358   if (stks.size() <= 1)
359     return NULL;
360   PathCalculator pc(src);
361   Stack* target = NULL;
362   for (auto dest : stks)
363     {
364       //is this us?
365       if (src == dest)
366         continue;
367 
368       //does the destination have few enough army units to join?
369       if (GameMap::canJoin(src, dest) == false)
370         continue;
371 
372       //is this a stack that is co-located?
373       if (src->getPos() == dest->getPos())
374         return dest;
375 
376       //can we actually get there?
377       int mp = pc.calculate(dest->getPos());
378       if (mp <= 0)
379         continue;
380 
381       if (mp < min_mp || min_mp == -1)
382         {
383           target = dest;
384           min_mp = mp;
385         }
386     }
387   return target;
388 }
389 
computerTurn()390 bool AI_Fast::computerTurn()
391 {
392   bool stack_moved = false;
393     // we have configurable behaviour in two ways:
394     // 1. join => merges close stacks
395     // 2. maniac => attack at any costs, raze everything in the path
396     //
397     // So the basic algorithm is like
398     // for all armies
399     //      if !maniac, and close to a temple, visit it
400     //      if (army_to_join close && d_join)
401     //          join armies
402     //      if (!maniac && army_damaged)
403     //          resupply
404     //      if (!maniac)
405     //          find next enemy city
406     //      else
407     //          find next enemy unit with preference to cities
408     //      attack
409     //
410     // return true if any stack moved
411 
412     // we are using reversed order because new stacks come behind old stacks
413     // and we want the freshly created stacks join the veterans and not the other
414     // way round.
415 
416   std::list<Vector<int> > points = d_stacklist->getPositions();
417   for (auto it: points)
418     {
419       Stack *s = GameMap::getFriendlyStack(it);
420       if (!s)
421         continue;
422 
423       d_stacklist->setActivestack(s);
424 
425       //move stacks to enemy cities.
426       if (s->hasPath() == true && s->getParked() == false)
427         {
428           Vector<int> pos = s->getLastPointInPath();
429           City *enemy = GameMap::getEnemyCity(pos);
430           if (enemy)
431             {
432               if (enemy->isBurnt() == false)
433                 {
434                   stack_moved |= stackMove(s);
435                   if (d_stacklist->getActivestack() == NULL)
436                     return true;
437                   if (stack_moved)
438                     continue;
439                 }
440             }
441         }
442 
443       //go to a temple or ruin
444       if (!d_maniac)
445         {
446           bool stack_died = false;
447           bool blessed = false;
448           if (s->hasHero() == false)
449             {
450               stack_moved = AI_maybeVisitTempleForBlessing
451                 (s, s->getMoves(), 50.0, blessed, stack_died);
452               if (stack_died)
453                 return true;
454               s = d_stacklist->getActivestack();
455               if (stack_moved)
456                 {
457                   GameMap::groupStacks(s);
458                   s->clearPath();
459                   continue;
460                 }
461             }
462           else if (s->hasHero() == true)
463             {
464               bool got_quest = false;
465               stack_moved = AI_maybeVisitTempleForQuest(s, s->getMoves(),
466                                                         got_quest,
467                                                         stack_died);
468               if (stack_died)
469                 return true;
470               if (!stack_moved)
471                 {
472                   bool ruin_visited = false;
473                   stack_moved = AI_maybeVisitRuin (s, s->getMoves(),
474                                                    ruin_visited, stack_died);
475                   if (stack_died)
476                     return true;
477                 }
478               s = d_stacklist->getActivestack();
479               if (stack_moved)
480                 {
481                   GameMap::groupStacks(s);
482                   s->clearPath();
483                   continue;
484                 }
485             }
486         }
487 
488       //pick up items
489       if (!d_maniac)
490         {
491           bool stack_died = false;
492           bool picked_up = false;
493 
494           stack_moved = AI_maybePickUpItems(s, s->getMoves(), picked_up,
495                                             stack_died);
496           if (stack_died)
497             return true;
498           s = d_stacklist->getActivestack();
499           if (picked_up && stack_moved)
500             stack_moved = false; //do this so we move it later on
501           else if (stack_moved)
502             continue;
503         }
504 
505       debug(">>>> What to do with stack " <<s->getId() <<" at (" <<s->getPos().x
506             <<"," <<s->getPos().y <<") containing " <<s->size() << " armies ?")
507 
508         // join armies if close
509         if (d_join && s->isFull() == false)
510           {
511             Stack* target = NULL;
512             target = findNearOwnStackToJoin(s, 5);
513 
514             if (target)
515               {
516                 debug("Joining with stack " <<target->getId() <<" at (" <<target->getPos().x <<"," <<target->getPos().y <<")")
517                   s->getPath()->calculate(s, target->getPos());
518                 stack_moved |= stackMove(s);
519                 //in case we lost our stack
520                 if (!d_stacklist->getActivestack())
521                   return true;
522                 if (s->getPos() == target->getPos())
523                   {
524                     GameMap::groupStacks(s);
525                     continue;
526                   }
527                 continue;
528               }
529           }
530 
531       // second step: try to resupply
532       if (!d_maniac)
533         {
534           City *target = Citylist::getInstance()->getNearestFriendlyCity(s->getPos());
535           if (s->isFull() == false && target)
536             {
537               debug("Restocking in " <<target->getName())
538                 // try to move to the north west part of the city (where the units
539                 // move after production), otherwise just wait and stand around
540 
541                 if (target->contains(s->getPos()) == false)
542                   {
543                     debug("Stack is not in " << target->getName() << " yet" <<std::endl);
544                     int mp = s->getPath()->calculateToCity(s, target);
545                     if (mp > 0)
546                       {
547                         stack_moved |= stackMove(s);
548 
549                         // the stack could have joined another stack waiting there
550                         if (!d_stacklist->getActivestack())
551                           return true;
552                         if (stack_moved)
553                           {
554                             GameMap::groupStacks(s);
555                             s->clearPath();
556                             continue;
557                           }
558                       }
559                   }
560                 else if (s->getPos() != target->getPos())
561                   {
562                     debug("Stack is inside " << target->getName() << std::endl);
563                     //if we're not in the upper right corner
564                     s->getPath()->calculate(s, target->getPos());
565                     //go there, and take as many as we can
566                     Stack *new_stack = NULL;
567                     stack_moved |= stackSplitAndMove(s, new_stack);
568                     //in case we lost our stack
569                     if (!d_stacklist->getActivestack())
570                       return true;
571                     if (stack_moved)
572                       {
573                         GameMap::groupStacks(s);
574                         s->clearPath();
575                         GameMap::groupStacks(target->getPos());
576                         return true;
577                       }
578                   }
579                 else
580                   {
581                     //otherwise just stay put in the city
582                     GameMap::groupStacks(s);
583                     continue;
584                   }
585             }
586 
587           // third step: non-maniac players attack only enemy cities
588           else
589             {
590               target = NULL;
591               PathCalculator pc(s, true, 10, -1);
592               guint32 moves1 = 0, turns1 = 0, moves2 = 0, turns2 = 0;
593               guint32 left1 = 0, left2 = 0;
594               Path *target1_path = NULL;
595               Path *target2_path = NULL;
596               City *target1;
597               if (Rnd::rand() % 3 == 0)
598                 target1 = Citylist::getInstance()->getClosestEnemyCity(s);
599               else
600                 target1 = Citylist::getInstance()->getNearestEnemyCity(s->getPos());
601               City *target2 = Citylist::getInstance()->getNearestForeignCity(s->getPos());
602               if (target1)
603                 target1_path = pc.calculateToCity(target1, moves1, turns1, left1);
604               else
605                 target1_path = new Path();
606               if (!target2)
607                 {
608                   delete target1_path;
609                   return false; //it's game over and we're still moving
610                 }
611               target2_path = pc.calculateToCity(target2, moves2, turns2, left2);
612 
613               //no enemies?  then go for the nearest foreign city.
614               //if diplomacy isn't on and we hit this, then it's game over
615               if (!target1)
616                 target = target2;
617 
618               //is the enemy city far enough away that a foreign city
619               //outweighs it?
620               else if (target1_path->size() / 13 > target2_path->size())
621                 target = target2;
622               else
623                 target = target1;
624               delete target1_path;
625               delete target2_path;
626 
627               if (target == target2)
628                 {
629                   if (GameScenarioOptions::s_diplomacy == true)
630                     d_diplomacy->needNewEnemy(target->getOwner());
631                   // try to wait a turn until we're at war
632                   if (target1)
633                     target = target1;
634                 }
635 
636               if (!target)    // strange situation
637                 {
638                   std::cerr << "yet another bad situation!!" << std::endl;
639                   stackPark(s);
640                   return true;
641                 }
642 
643               debug("Attacking " << target->getName() << " (" <<
644                     target->getPos().x <<","<< target->getPos().y << ")")
645                 int moves = s->getPath()->calculateToCity(s, target);
646               debug("Moves to enemy city: " << moves);
647 
648               if (moves >= 1)
649                 {
650                   stack_moved |= stackMove(s);
651                   s = d_stacklist->getActivestack();
652                   if (!d_stacklist->getActivestack())
653                     return true;
654                   //if we didn't get there
655                   if (target->getOwner() != s->getOwner())
656                     {
657                       //and the target city is empty
658                       if (target->countDefenders() == 0)
659                         {
660                           //attack it if we can reach it.
661                           Stack *new_stack = NULL;
662                           int moved = stackSplitAndMove(s, new_stack);
663                           stack_moved |=  moved;
664                           if (moved)
665                             {
666                               //either s or new_stack could be dead.
667                               if (d_stacklist->getActivestack() != NULL)
668                                 GameMap::groupStacks(s);
669                               GameMap::groupStacks(target->getPos());
670                               return true;
671                             }
672                         }
673                     }
674                 }
675               else
676                 {
677                   // an enemy city is completely surrouned by other stacks, or the way is blocked by a signle enemy stack
678                   //let us presume this is temporary and just leave the stack here
679                   //for some reason we can't set parked on this thing
680                   //and have it realize it, after we return true.
681                   //why is that?
682                   printf("crap, it happened with a stack at %d,%d\n", s->getPos().x, s->getPos().y);
683                   printf("moves is %d\n", moves);
684                   printf("Destination was %d,%d (%s)\n", target->getPos().x, target->getPos().y, target->getName().c_str());
685                   stackDisband(s);
686                   return true;
687                 }
688 
689               // a stack has died ->restart
690               if (!d_stacklist->getActivestack())
691                 return true;
692 
693               continue;
694             }
695         }
696 
697 
698       // fourth step: maniac players attack everything that is close if they can
699       // reach it or cities otherwise.
700       if (d_maniac)
701         {
702           const Threatlist* threats = d_analysis->getThreatsInOrder(s->getPos());
703           Threatlist::const_iterator tit = threats->begin();
704           const Threat* target = 0;
705 
706           // prefer weak forces (take strong if neccessary) and stop after 10
707           // stacks
708           for (int i = 0; tit != threats->end() && i < 10; tit++, i++)
709             {
710               // in a first step, we only look at enemy stacks
711               if ((*tit)->isCity() || (*tit)->isRuin())
712                 continue;
713 
714               // ignore stacks out of reach
715               Vector<int> threatpos = (*tit)->getClosestPoint(s->getPos());
716               if (threatpos == Vector<int>(-1, -1))
717                 continue;
718 
719               guint32 mp = s->getPath()->calculate(s, threatpos);
720               if ((int)mp <= 0 || mp > s->getMoves())
721                 continue;
722 
723               target = *tit;
724               break;
725 
726             }
727 
728           // now we need to choose. If we found a target, attack it, otherwise
729           // attack the closest city.
730           Vector<int> pos = Vector<int>(-1,-1);
731           if (target)
732             {
733               pos = target->getClosestPoint(s->getPos());
734               debug("Maniac mode, found target at (" <<pos.x <<"," <<pos.y <<")")
735             }
736           else
737             {
738               City *enemy_city =
739                 Citylist::getInstance()->getNearestForeignCity(s->getPos());
740               if (enemy_city)
741                 {
742                   pos  = enemy_city->getPos();
743                   debug("Maniac, found no targets, attacking city " << enemy_city->getName() << " at (" <<pos.x <<"," <<pos.y <<")")
744                 }
745             }
746 
747           if (pos == Vector<int>(-1,-1))
748             return false;
749 
750           int mp = s->getPath()->calculate(s, pos);
751           if (mp > 0)
752             {
753               //printf ("stack %d at %d,%d moving %d with %d moves\n",
754               //s->getId(), s->getPos().x, s->getPos().y,
755               //mp, s->getMoves());
756               bool moved = stackMove(s);
757               //printf("result of move: %d\n", moved);
758               stack_moved |= moved;
759               //in case we lost our stack
760               if (!d_stacklist->getActivestack())
761                 return true;
762               s = d_stacklist->getActivestack();
763             }
764           else
765             {
766               printf ("we're going the wrong way (mp is %d)!!\n", mp);
767               printf ("this means we couldn't calculate a path from %d,%d to %d,%d\n", s->getPos().x, s->getPos().y, pos.x, pos.y);
768               //sleep (10);
769               City *friendly_city =
770                 Citylist::getInstance()->getNearestFriendlyCity(s->getPos());
771               if (friendly_city)
772                 {
773                   mp = s->getPath()->calculate(s, friendly_city->getPos());
774                   if (mp > 0)
775                     {
776                       stack_moved |= stackMove(s);
777                       //in case we lost our stack
778                       if (!d_stacklist->getActivestack())
779                         return true;
780                     }
781                   else
782                     stack_moved |= false;
783                 }
784               else
785                 {
786                   //we can't find anyplace to move to!
787                   //so we stay put.
788                   stack_moved |= false;
789                 }
790             }
791 
792           if (!d_stacklist->getActivestack())
793             return true;
794           continue;
795 
796         }
797       if (abort_requested)
798         break;
799     }
800     return stack_moved;
801 }
802 
chooseTreachery(Stack * stack,Player * player,Vector<int> pos)803 bool AI_Fast::chooseTreachery (Stack *stack, Player *player, Vector <int> pos)
804 {
805   (void) stack;
806   (void) player;
807   (void) pos;
808   return true;
809 }
810 
chooseHero(HeroProto * hero,City * city,int gold)811 bool AI_Fast::chooseHero(HeroProto *hero, City *city, int gold)
812 {
813   (void) hero;
814   (void) city;
815   (void) gold;
816   return true;
817 }
818 
chooseReward(Ruin * ruin,Sage * sage,Stack * stack)819 Reward *AI_Fast::chooseReward(Ruin *ruin, Sage *sage, Stack *stack)
820 {
821   (void) ruin;
822   (void) stack;
823   //always pick the money.
824   Reward *reward = NULL;
825   for (Sage::iterator it = sage->begin(); it != sage->end(); it++)
826     if ((*it)->getType() == Reward::GOLD)
827       {
828         reward = (*it);
829         break;
830       }
831   if (!reward)
832     reward = sage->front();
833   sage->selectReward(reward);
834   return reward;
835 }
836 
chooseStat(Hero * hero)837 Army::Stat AI_Fast::chooseStat(Hero *hero)
838 {
839   (void) hero;
840   return Army::STRENGTH;
841 }
842 
chooseQuest(Hero * hero)843 bool AI_Fast::chooseQuest(Hero *hero)
844 {
845   (void) hero;
846   return true;
847 }
848 
computerChooseVisitRuin(Stack * stack,Vector<int> dest,guint32 moves,guint32 turns)849 bool AI_Fast::computerChooseVisitRuin(Stack *stack, Vector<int> dest, guint32 moves, guint32 turns)
850 {
851   (void) turns;
852   if (stack->getPos() == dest)
853     return true;
854   if (moves < stack->getMoves() + 15)
855     return true;
856   else
857     return false;
858 }
859 
computerChoosePickupBag(Stack * stack,Vector<int> dest,guint32 moves,guint32 turns)860 bool AI_Fast::computerChoosePickupBag(Stack *stack, Vector<int> dest, guint32 moves, guint32 turns)
861 {
862   (void) turns;
863   if (stack->getPos() == dest)
864     return true;
865   if (moves < stack->getMoves() + 7)
866     return true;
867   else
868     return false;
869 }
870 
computerChooseVisitTempleForBlessing(Stack * stack,Vector<int> dest,guint32 moves,guint32 turns)871 bool AI_Fast::computerChooseVisitTempleForBlessing(Stack *stack, Vector<int> dest, guint32 moves, guint32 turns)
872 {
873   (void) turns;
874   if (stack->isOnCity() == true)
875     return false;
876   if (stack->getPos() == dest)
877     return true;
878   if (moves < stack->getMoves() + 7)
879     return true;
880   else
881     return false;
882 }
883 
computerChooseVisitTempleForQuest(Stack * stack,Vector<int> dest,guint32 moves,guint32 turns)884 bool AI_Fast::computerChooseVisitTempleForQuest(Stack *stack, Vector<int> dest, guint32 moves, guint32 turns)
885 {
886   (void) turns;
887   if (stack->isOnCity() == true)
888     return false;
889   if (stack->getPos() == dest)
890     return true;
891   if (moves < stack->getMoves() + 15)
892     return true;
893   else
894     return false;
895 }
896 
computerChooseContinueQuest(Stack * stack,Quest * quest,Vector<int> dest,guint32 moves,guint32 turns)897 bool AI_Fast::computerChooseContinueQuest(Stack *stack, Quest *quest, Vector<int> dest, guint32 moves, guint32 turns)
898 {
899   (void) stack;
900   (void) quest;
901   (void) dest;
902   (void) moves;
903   (void) turns;
904   return true;
905 }
906 // End of file
907