BWAPI
SnippyHolloW-BroodwarBotQ-f01ab56/src/Macro/Arbitrator/Arbitrator.h
Go to the documentation of this file.
00001 #pragma once
00002 #include <list>
00003 #include <set>
00004 #include <map>
00005 #include "Macro/Heap.h"
00006 #include "Controller.h"
00007 namespace Arbitrator
00008 {
00009   template <class _Tp,class _Val>
00010   class Arbitrator
00011   {
00012   public:
00013     Arbitrator();
00014     bool setBid(Controller<_Tp,_Val>* c, _Tp obj, _Val bid);
00015     bool setBid(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid);
00016     bool removeBid(Controller<_Tp,_Val>* c, _Tp obj);
00017     bool removeBid(Controller<_Tp,_Val>* c, std::set<_Tp> objs);
00018     bool removeAllBids(Controller<_Tp,_Val>* c);
00019     bool removeController(Controller<_Tp,_Val>* c);
00020     bool accept(Controller<_Tp,_Val>* c, _Tp obj, _Val bid);
00021     bool accept(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid);
00022     bool accept(Controller<_Tp,_Val>* c, _Tp obj);
00023     bool accept(Controller<_Tp,_Val>* c, std::set<_Tp> objs);
00024     bool decline(Controller<_Tp,_Val>* c, _Tp obj, _Val bid);
00025     bool decline(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid);
00026     bool hasBid(_Tp obj) const;
00027     const std::pair<Controller<_Tp,_Val>*, _Val>& getHighestBidder(_Tp obj) const;
00028     const std::list< std::pair<Controller<_Tp,_Val>*, _Val> > getAllBidders(_Tp obj) const;
00029     const std::set<_Tp>& getObjects(Controller<_Tp,_Val>* c) const;
00030     const std::set<_Tp>& getObjectsBidOn(Controller<_Tp,_Val>* c) const;
00031     void onRemoveObject(_Tp obj);
00032     _Val getBid(Controller<_Tp,_Val>* c, _Tp obj) const;
00033     void update();
00034   private:
00035     bool revokeOwnership(_Tp object, _Val bid, Controller<_Tp,_Val>* c = NULL);
00036     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> > bids;
00037     std::map<_Tp,Controller<_Tp,_Val>* > owner;
00038     std::map<Controller<_Tp,_Val>*, std::set<_Tp> > objectsOwned;
00039     std::map<Controller<_Tp,_Val>*, std::set<_Tp> > objectsBidOn;
00040     std::set<_Tp> updatedObjects;
00041     std::set<_Tp> objectsCanIncreaseBid;
00042     std::set<_Tp> unansweredObjects;
00043     std::set<_Tp> emptySet;
00044     Heap<Controller<_Tp,_Val>*, _Val> emptyHeap;
00045     std::pair<Controller<_Tp,_Val>*, _Val> defaultBidder;
00046     bool inUpdate;
00047     bool inOnOffer;
00048     bool inOnRevoke;
00049   };
00050 
00051   template <class _Tp,class _Val>
00052   Arbitrator<_Tp,_Val>::Arbitrator()
00053   {
00054     inUpdate=false;
00055     inOnOffer=false;
00056     inOnRevoke=false;
00057   }
00058   template <class _Tp,class _Val>
00059   //revokes the ownership of obj from its current owner unless the owner is c
00060   bool Arbitrator<_Tp,_Val>::revokeOwnership(_Tp obj, _Val bid, Controller<_Tp,_Val>* c)
00061   {
00062     std::map<_Tp,Controller<_Tp,_Val>* >::iterator ownerIter = owner.find(obj);
00063     if (ownerIter == owner.end())
00064     {
00065       return false;
00066     }
00067     Controller<_Tp,_Val>* theOwner = ownerIter->second;
00068     //remove ownership unless it is this controller
00069     if (theOwner == c)
00070     {
00071       return false;
00072     }
00073     inOnRevoke=true;
00074     theOwner->onRevoke(obj,bid);
00075     inOnRevoke=false;
00076     std::map<Controller<_Tp,_Val>*, std::set<_Tp> >::iterator objectsOwnedIter = objectsOwned.find(theOwner);
00077     if (objectsOwnedIter!=objectsOwned.end())
00078     {
00079       objectsOwnedIter->second.erase(obj);//remove this object from the set of objects owned by the former owner
00080       if (objectsOwnedIter->second.empty())
00081       {
00082         objectsOwned.erase(objectsOwnedIter);
00083       }
00084     }
00085     owner.erase(ownerIter);
00086     return true;
00087   }
00088 
00089   template <class _Tp,class _Val>
00090   bool Arbitrator<_Tp,_Val>::setBid(Controller<_Tp,_Val>* c, _Tp obj, _Val bid)
00091   {
00092     if (c == NULL || obj == NULL)
00093     {
00094       return false;
00095     }
00096 
00097     //can only increase bids of certain objects during update()
00098     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00099     if (bidsIter != bids.end() && bidsIter->second.contains(c) && bid > bidsIter->second.get(c))
00100     {
00101       if (inOnRevoke || (inOnOffer && objectsCanIncreaseBid.find(obj) == objectsCanIncreaseBid.end()))
00102       {
00103         return false;
00104       }
00105     }
00106 
00107     //set the bid for this object and insert the object into the updated set
00108     bids[obj].set(c,bid);
00109     objectsBidOn[c].insert(obj);
00110     updatedObjects.insert(obj);
00111     return true;
00112   }
00113 
00114   template <class _Tp,class _Val>
00115   bool Arbitrator<_Tp,_Val>::setBid(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid)
00116   {
00117     bool result = false;
00118     for (std::set<_Tp>::const_iterator o = objs.begin(); o != objs.end(); o++)
00119     {
00120       result |= setBid(c, *o, bid);
00121     }
00122     return result;
00123   }
00124 
00125   template <class _Tp,class _Val>
00126   bool Arbitrator<_Tp,_Val>::removeBid(Controller<_Tp,_Val>* c, _Tp obj)
00127   {
00128     if (c == NULL || obj == NULL)
00129     {
00130       return false;
00131     }
00132     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00133     if (bidsIter != bids.end() && bidsIter->second.contains(c)) //check to see if the bid exists
00134     {
00135       bidsIter->second.erase(c); //if so, remove the bid
00136       if (bidsIter->second.empty())
00137       {
00138         bids.erase(bidsIter);
00139       }
00140       updatedObjects.insert(obj); //insert the object into the updated set
00141     }
00142     std::map<Controller<_Tp,_Val>*, std::set<_Tp> >::iterator objectsBidOnIter = objectsBidOn.find(c);
00143     if (objectsBidOnIter!=objectsBidOn.end())
00144     {
00145       objectsBidOnIter->second.erase(obj);
00146       if (objectsBidOnIter->second.empty())
00147       {
00148         objectsBidOn.erase(objectsBidOnIter);
00149       }
00150     }
00151     return true;
00152   }
00153 
00154   template <class _Tp,class _Val>
00155   bool Arbitrator<_Tp,_Val>::removeBid(Controller<_Tp,_Val>* c, std::set<_Tp> objs)
00156   {
00157     bool result = false;
00158     for (std::set<_Tp>::const_iterator o = objs.begin(); o != objs.end(); o++)
00159     {
00160       result |= removeBid(c, *o);
00161     }
00162     return result;
00163   }
00164 
00165   template <class _Tp,class _Val>
00166   bool Arbitrator<_Tp,_Val>::removeAllBids(Controller<_Tp,_Val>* c)
00167   {
00168     std::map<Controller<_Tp,_Val>*, std::set<_Tp> >::iterator objectsBidOnIter = objectsBidOn.find(c);
00169     if (objectsBidOnIter == objectsBidOn.end())
00170     {
00171       return false;
00172     }
00173     return removeBid(c,objectsBidOnIter->second);
00174   }
00175 
00176   template <class _Tp,class _Val>
00177   bool Arbitrator<_Tp,_Val>::removeController(Controller<_Tp,_Val>* c)
00178   {
00179     if (c == NULL) return false;
00180     //first - remove all bids
00181     removeAllBids(c);
00182     //second - remove all ownership
00183     std::map<Controller<_Tp,_Val>*, std::set<_Tp> >::iterator objectsOwnedIter = objectsOwned.find(c);
00184     if (objectsOwnedIter != objectsOwned.end())
00185     {
00186       for (std::set<_Tp>::const_iterator o = objectsOwnedIter->second.begin(); o != objectsOwnedIter->second.end(); o++)
00187       {
00188         std::map<_Tp,Controller<_Tp,_Val>* >::iterator ownerIter = owner.find(*o);
00189         if (ownerIter!=owner.end() && ownerIter->second == c)
00190         {
00191           owner.erase(ownerIter);
00192         }
00193       }
00194       objectsOwned.erase(objectsOwnedIter);
00195     }
00196     return true;
00197   }
00198 
00199   template <class _Tp,class _Val>
00200   bool Arbitrator<_Tp,_Val>::decline(Controller<_Tp,_Val>* c, _Tp obj, _Val bid)
00201   {
00202     if (c == NULL || obj == NULL)
00203     {
00204       return false;
00205     }
00206     if (!inOnOffer) //can only call decline from the onOffer() callback
00207     {
00208       return false;
00209     }
00210     if (hasBid(obj)==false || bids[obj].top().first != c) //only the top bidder/controller can decline an object
00211     {
00212       return false;
00213     }
00214     updatedObjects.insert(obj);
00215     unansweredObjects.erase(obj);
00216     objectsCanIncreaseBid.erase(obj);
00217 
00218     //must decrease bid via decline()
00219     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00220     if (bidsIter!=bids.end() && bidsIter->second.contains(c) && bid>=bidsIter->second.get(c))
00221     {
00222       bid = 0;
00223     }
00224     if (bid <= 0) //could be set to 0 from 2 lines above or the user could have called with a bid <= 0
00225     {
00226       if (bidsIter!=bids.end() && bidsIter->second.contains(c))
00227       {
00228         bidsIter->second.erase(c);
00229         if (bidsIter->second.empty())
00230         {
00231           bids.erase(bidsIter);
00232         }
00233       }
00234       return true;
00235     }
00236     bids[obj].set(c, bid);
00237     return true;
00238   }
00239 
00240   template <class _Tp,class _Val>
00241   bool Arbitrator<_Tp,_Val>::decline(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid)
00242   {
00243     bool result = false;
00244     for (std::set<_Tp>::const_iterator o = objs.begin(); o != objs.end(); o++)
00245     {
00246       result |= decline(c, *o, bid);
00247     }
00248     return result;
00249   }
00250 
00251   template <class _Tp,class _Val>
00252   bool Arbitrator<_Tp,_Val>::accept(Controller<_Tp,_Val>* c, _Tp obj)
00253   {
00254     if (c == NULL || obj == NULL)
00255     {
00256       return false;
00257     }
00258     if (!inOnOffer) //can only call accept from the onOffer() callback
00259     {
00260       return false;
00261     }
00262     if (hasBid(obj)==false || bids[obj].top().first != c) //only the top bidder/controller can accept an object
00263     {
00264       return false;
00265     }
00266     unansweredObjects.erase(obj);
00267     inOnOffer=false;
00268     revokeOwnership(obj,bids[obj].top().second,c);
00269     inOnOffer=true;
00270     owner[obj] = c; //set the new owner
00271     objectsOwned[c].insert(obj); //insert this object into the set of objects owned by this controller
00272     return true;
00273   }
00274 
00275   template <class _Tp,class _Val>
00276   bool Arbitrator<_Tp,_Val>::accept(Controller<_Tp,_Val>* c, std::set<_Tp> objs)
00277   {
00278     bool result = false;
00279     for (std::set<_Tp>::const_iterator o = objs.begin(); o != objs.end(); o++)
00280     {
00281       result |= accept(c, *o);
00282     }
00283     return result;
00284   }
00285 
00286   template <class _Tp,class _Val>
00287   bool Arbitrator<_Tp,_Val>::accept(Controller<_Tp,_Val>* c, _Tp obj, _Val bid)
00288   {
00289     //same idea as accept(Controller<_Tp,_Val>* c, _Tp obj), but the controller also specifies a new bid value
00290     if (c == NULL || obj == NULL)
00291     {
00292       return false;
00293     }
00294     if (!inOnOffer) //can only call accept from the onOffer() callback
00295     {
00296       return false;
00297     }
00298     if (hasBid(obj)==false || bids[obj].top().first != c) //only the top bidder/controller can accept an object
00299     {
00300       return false;
00301     }
00302     unansweredObjects.erase(obj);
00303     inOnOffer=false;
00304     revokeOwnership(obj,bids[obj].top().second,c);
00305     inOnOffer=true;
00306     owner[obj] = c; //set the new owner
00307     objectsOwned[c].insert(obj); //insert this object into the set of objects owned by this controller
00308     updatedObjects.insert(obj); //since the object was updated, insert it into the updated objects set
00309 
00310     //cannot decrease bid via accept()
00311     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00312     if (bidsIter!=bids.end() && bidsIter->second.contains(c) && bid<bidsIter->second.get(c))
00313     {
00314       return true;
00315     }
00316 
00317     //update the bid for this object
00318     bids[obj].set(c,bid);
00319     return true;
00320   }
00321 
00322   template <class _Tp,class _Val>
00323   bool Arbitrator<_Tp,_Val>::accept(Controller<_Tp,_Val>* c, std::set<_Tp> objs, _Val bid)
00324   {
00325     bool result = false;
00326     for (std::set<_Tp>::const_iterator o = objs.begin(); o != objs.end(); o++)
00327     {
00328       result |= accept(c, *o, bid);
00329     }
00330     return result;
00331   }
00332 
00333   template <class _Tp,class _Val>
00334   bool Arbitrator<_Tp,_Val>::hasBid(_Tp obj) const
00335   {
00336     //returns true if the given object exists in the bids map
00337     return (bids.find(obj) != bids.end() && !bids.find(obj)->second.empty());
00338   }
00339 
00340   template <class _Tp,class _Val>
00341   const std::pair<Controller<_Tp,_Val>*, _Val>& Arbitrator<_Tp,_Val>::getHighestBidder(_Tp obj) const
00342   {
00343     //returns the controller at the top of the bid heap for this object
00344     if (bids.find(obj) == bids.end())
00345     {
00346       return defaultBidder;
00347     }
00348     return bids.find(obj)->second.top();
00349   }
00350 
00351   template <class _Tp,class _Val>
00352   const std::list< std::pair<Controller<_Tp,_Val>*, _Val> > Arbitrator<_Tp,_Val>::getAllBidders(_Tp obj) const
00353   {
00354     //returns all bidders for this object
00355     std::list< std::pair<Controller<_Tp,_Val>*, _Val> > bidders;
00356     if (bids.find(obj) == bids.end())
00357     {
00358       return bidders; //return empty list if we cannot find this object
00359     }
00360 
00361     Heap<Controller<_Tp,_Val>*, _Val> bid_heap = bids.find(obj)->second; //get the bid heap
00362 
00363     //push the bidders into the bidders list from top to bottom
00364     while(!bid_heap.empty())
00365     {
00366       bidders.push_back(bid_heap.top());
00367       bid_heap.pop();
00368     }
00369     return bidders;
00370   }
00371 
00372   template <class _Tp,class _Val>
00373   const std::set<_Tp>& Arbitrator<_Tp,_Val>::getObjects(Controller<_Tp,_Val>* c) const
00374   {
00375     //returns the set of objects owned by this bidder/controller
00376     if (objectsOwned.find(c) == objectsOwned.end())
00377     {
00378       return emptySet;
00379     }
00380     return objectsOwned.find(c)->second;
00381   }
00382 
00383   template <class _Tp,class _Val>
00384   const std::set<_Tp>& Arbitrator<_Tp,_Val>::getObjectsBidOn(Controller<_Tp,_Val>* c) const
00385   {
00386     //returns the set of objects bid on by this bidder/controller
00387     if (objectsBidOn.find(c) == objectsBidOn.end())
00388     {
00389       return emptySet;
00390     }
00391     return objectsBidOn.find(c)->second;
00392   }
00393 
00394   template <class _Tp,class _Val>
00395   void Arbitrator<_Tp,_Val>::onRemoveObject(_Tp obj)
00396   {
00397     //called from AIModule::onUnitDestroy, remove all memory of the object
00398     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00399     if (bidsIter != bids.end())
00400     {
00401       Heap<Controller<_Tp,_Val>*, _Val> bid_heap=bidsIter->second; //get the bid heap
00402 
00403       //for each bidder, remove this object from the set of objects the bidder has bid on
00404       while(!bid_heap.empty())
00405       {
00406         Controller<_Tp,_Val>* bidder = bid_heap.top().first;
00407         bid_heap.pop();
00408         std::map<Controller<_Tp,_Val>*, std::set<_Tp> >::iterator objectsBidOnIter = objectsBidOn.find(bidder);
00409         if (objectsBidOnIter!=objectsBidOn.end())
00410         {
00411           objectsBidOnIter->second.erase(obj);
00412           if (objectsBidOnIter->second.empty())
00413           {
00414             objectsBidOn.erase(objectsBidOnIter);
00415           }
00416         }
00417       }
00418       bids.erase(bidsIter);
00419     }
00420     _Val temp = 0;
00421     revokeOwnership(obj,temp);
00422 
00423     std::set<_Tp>::iterator updatedObjectsIter = updatedObjects.find(obj);
00424     if (updatedObjectsIter != updatedObjects.end())
00425     {
00426       updatedObjects.erase(updatedObjectsIter);
00427     }
00428   }
00429 
00430   template <class _Tp,class _Val>
00431   _Val Arbitrator<_Tp,_Val>::getBid(Controller<_Tp,_Val>* c, _Tp obj) const
00432   {
00433     //returns the bid the given controller has on the given object
00434 
00435     std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(obj);
00436     if (bidsIter!=bids.end() && bidsIter->second.contains(c))
00437     {
00438       return bidsIter->second.get(c);
00439     }
00440     //else
00441     return _Val(0);
00442   }
00443 
00444   template <class _Tp,class _Val>
00445   void Arbitrator<_Tp,_Val>::update()
00446   {
00447     this->inUpdate=true;
00448     bool first=true;
00449     //first we construct a map for the objects to offer
00450     std::map<Controller<_Tp,_Val>*, std::set<_Tp> > objectsToOffer;
00451 
00452     while(first || !objectsToOffer.empty())
00453     {
00454       first=false;
00455       objectsToOffer.clear();
00456 
00457       this->objectsCanIncreaseBid.clear();
00458 
00459       //go through all the updated objects
00460       for(std::set<_Tp>::iterator i = updatedObjects.begin(); i != updatedObjects.end(); i++)
00461       {
00462         std::map<_Tp,Heap<Controller<_Tp,_Val>*, _Val> >::iterator bidsIter = bids.find(*i);
00463         std::map<_Tp,Controller<_Tp,_Val>* >::iterator ownerIter = owner.find(*i);
00464         if (bidsIter!=bids.end() && !bidsIter->second.empty()) //if there is a bid on this object
00465         {
00466           if (ownerIter == owner.end() || bidsIter->second.top().first != ownerIter->second) //if the top bidder is not the owner
00467             objectsToOffer[bidsIter->second.top().first].insert(*i); //make a note to offer it to the top bidder.
00468         }
00469         else
00470         {
00471           //no bids on this object, remove it from the owner if there is one
00472           if (ownerIter != owner.end())
00473           {
00474             revokeOwnership(*i,0);
00475           }
00476         }
00477       }
00478       //reset updated objects
00479       updatedObjects.clear();
00480 
00481       //offer the objects to the top bidders
00482       for(std::map< Controller<_Tp,_Val>*, std::set<_Tp> >::iterator i = objectsToOffer.begin(); i != objectsToOffer.end(); i++)
00483       {
00484         objectsCanIncreaseBid=i->second;
00485         unansweredObjects=i->second;
00486 
00487         inOnOffer=true;
00488         i->first->onOffer(i->second);
00489         inOnOffer=false;
00490 
00491         //decline all unanswered objects
00492         for(std::set<_Tp>::iterator j=unansweredObjects.begin();j!=unansweredObjects.end();j++)
00493         {
00494           decline(i->first,*j,0);
00495         }
00496       }
00497     }
00498     this->inUpdate=false;
00499   }
00500 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines