BWAPI
|
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 }