1 // Copyright (C) 2004 John Farrell
2 // Copyright (C) 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2005 Andrea Paternesi
4 // Copyright (C) 2007, 2009 Ben Asselstine
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Library General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "Threatlist.h"
28 #include "AICityInfo.h"
32 //#define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl<<flush;}
35 Threatlist::Threatlist()
39 Threatlist::~Threatlist()
43 bool Threatlist::compareValue(const Threat *lhs, const Threat *rhs)
45 return lhs->getValue() > rhs->getValue();
47 void Threatlist::sortByValue()
52 for (Threatlist::iterator it = begin(); it != end(); it++)
56 printf ("%d. %f (%f)\n", count, (*it)->getValue(), (*it)->getStrength());
62 // bubble sort is the easiest thing I remember
70 iterator it = begin();
74 // now loop through the list
75 for (; nextit != end(); it++, nextit++)
76 if ((*it)->value() < (*nextit)->value())
78 // exchange the two threats
80 Threat* tmp = (*nextit);
84 it = insert(nextit, tmp);
90 void Threatlist::sortByDistance(Vector<int> pos)
92 // A simple bubble sort is propably too computationally expensive here.
93 // To reduce the overhead, we first calculate all distances, store them
94 // in another list and sort both lists together.
96 std::list<int> distances;
98 for (iterator it = begin(); it != end(); it++)
100 //int dist = abs((*it)->getClosestPoint(pos).x - pos.x);
101 //if (dist < abs((*it)->getClosestPoint(pos).y - pos.y))
102 //dist = abs((*it)->getClosestPoint(pos).y - pos.y);
103 distances.push_back(dist((*it)->getClosestPoint(pos), pos));
106 // now again a bubble sort :)
114 std::list<int>::iterator dit = distances.begin();
115 std::list<int>::iterator dnextit = distances.begin();
118 iterator it = begin();
119 iterator nextit = it;
122 for (; nextit != end(); it++, nextit++, dit++, dnextit++)
123 if ((*dit) > (*dnextit))
125 // exchange the items in both lists
128 Threat* tmp = (*nextit);
131 it = insert(nextit, tmp);
133 int val = (*dnextit);
134 distances.erase(dnextit);
136 dit = distances.insert(dnextit, val);
141 void Threatlist::addStack(Stack *stack)
143 for (iterator it = begin(); it != end(); it++)
145 Threat *threat = *it;
146 if (threat->Near(stack->getPos(), stack->getOwner()))
148 threat->addStack(stack);
153 Threat *t = new Threat(stack);
157 void Threatlist::addRuin(Ruin *ruin)
159 //if the ruin is abandoned, it is not a threat nor a valuable target
160 if (ruin->isSearched())
163 Threat *t = new Threat(ruin);
167 void Threatlist::findThreats(AICityInfo *info) const
170 Vector<int> location = info->getPos();
172 for (const_iterator it = begin(); it != end(); it++)
174 Threat *threat = *it;
175 Vector<int> closestPoint = threat->getClosestPoint(location);
177 //This happens only if a threat doesn't contain any stacks any longer.
178 if (closestPoint.x == -1)
181 int distToThreat = dist(closestPoint, location);
183 float movesToThreat = ((float) distToThreat + 6.0) / 7.0;
184 debug("moves to " << threat->toString() << " is " << movesToThreat)
186 //Ignore threats too far away
187 if (movesToThreat > 10.0)
190 if (movesToThreat <= 0.0)
193 float strength = threat->getStrength();
197 debug("strength of " << threat->toString() << " is " << strength)
198 float dangerFromThisThreat = strength / movesToThreat;
199 info->addThreat(dangerFromThisThreat, threat);
201 // a side-effect of this calculation is that we calculate the overall
202 // danger from each threat. If a threat threatens multiple cities, it
203 // is considered especially dangerous, so it is okay that we add the
204 // danger multiple times.
205 threat->addDanger(dangerFromThisThreat);
209 void Threatlist::deleteStack(guint32 id)
211 for (Threatlist::iterator it = begin(); it != end(); it++)
212 (*it)->deleteStack(id);
215 void Threatlist::deleteStack(Stack* s)
217 for (Threatlist::iterator it = begin(); it != end(); it++)
218 (*it)->deleteStack(s);
221 string Threatlist::toString() const
225 for (const_iterator it = begin(); it != end(); it++)
235 result = result + " " + (*it)->toString();
241 void Threatlist::flClear()
243 for (iterator it = begin(); it != end(); it++)
249 Threatlist::iterator Threatlist::flErase(iterator object)
252 return erase(object);
255 bool Threatlist::flRemove(Threat* object)
257 iterator threatit = find(begin(), end(), object);
258 if (threatit != end())
267 void Threatlist::changeOwnership(Player *old_owner, Player *new_owner)
269 for (iterator it = begin(); it != end(); it++)
270 if ((*it)->getOwner() == old_owner)
271 (*it)->setOwner(new_owner);