BWAPI
|
00001 #pragma once 00002 #include "../../Utils/Utils.h" 00003 #include "../../Utils/ReferenceCounted.h" 00004 #include <BWAPI.h> 00005 #include <hash_set> 00006 00007 // Useless #define, only there to mark where we use the facts the unit pointers do not change to uniquely identify enemy units 00008 #define INVARIANT_UNIT_POINTERS_ASSUMPTION 00009 00010 static const int MAX_SUPPLY = 200 * 2; 00011 00012 namespace BWAPI 00013 { 00014 inline std::ostream& operator<<(std::ostream& out, const Position& position) 00015 { 00016 out << "(" << position.x() << ", " << position.y() << ")"; 00017 return out; 00018 } 00019 inline std::ostream& operator<<(std::ostream& out, const Unit& unit) 00020 { 00021 out << unit.getType().getName() << " " << unit.getID(); 00022 return out; 00023 } 00024 inline std::ostream& operator<<(std::ostream& out, const UnitType& unitType) 00025 { 00026 out << unitType.getName(); 00027 return out; 00028 } 00029 inline std::ostream& operator<<(std::ostream& out, const TechType& techType) 00030 { 00031 out << techType.getName(); 00032 return out; 00033 } 00034 inline std::ostream& operator<<(std::ostream& out, const UpgradeType& upgradeType) 00035 { 00036 out << upgradeType.getName(); 00037 return out; 00038 } 00039 } 00040 00041 template<class T> 00042 std::ostream& operator<<(std::ostream& out, const std::list<T>& lst) 00043 { 00044 std::copy(lst.begin(), lst.end(), std::ostream_iterator<T>(out, "; ")); 00045 return out; 00046 } 00047 00048 namespace detail 00049 { 00050 struct PrintObjectDescriptionIfReferenceType 00051 { 00052 template <class T> 00053 static std::string getObjectDescription(const T& object) 00054 { 00055 std::stringstream out; 00056 out << object; 00057 return out.str(); 00058 } 00059 }; 00060 00061 struct PrintObjectDescriptionIfPointerType 00062 { 00063 template <class T> 00064 static std::string getObjectDescription(const T& object) 00065 { 00066 // Assuming there is only one dereference needed 00067 return detail::PrintObjectDescriptionIfReferenceType::getObjectDescription(*object); 00068 } 00069 }; 00070 }; 00071 00072 template<class T> 00073 std::string getObjectDescription(const T& object) 00074 { 00075 return static_if_else<boost::is_pointer<T>::value, 00076 detail::PrintObjectDescriptionIfPointerType, 00077 detail::PrintObjectDescriptionIfReferenceType>::type::getObjectDescription(object); 00078 } 00079 00080 template <class T> 00081 std::string getObjectDescription(const AutoPtr<T>& ptr) 00082 { 00083 return getObjectDescription(*ptr); 00084 } 00085 00086 class UnitWrapperBase 00087 { 00088 public: 00089 struct extract_unit : std::unary_function<UnitWrapperBase,BWAPI::Unit*> 00090 { 00091 BWAPI::Unit* operator()(const UnitWrapperBase& unitWrapper) const 00092 { 00093 return unitWrapper.getUnit(); 00094 } 00095 }; 00096 00097 UnitWrapperBase(BWAPI::Unit* unit) 00098 : m_unit(unit) {} 00099 BWAPI::Unit* getUnit() const 00100 { 00101 return m_unit; 00102 } 00103 operator BWAPI::Unit*() const 00104 { 00105 return m_unit; 00106 } 00107 BWAPI::Unit* operator->() const 00108 { 00109 return m_unit; 00110 } 00111 BWAPI::Unit* operator->() 00112 { 00113 return m_unit; 00114 } 00115 BWAPI::Unit& operator*() const 00116 { 00117 return *m_unit; 00118 } 00119 BWAPI::Unit& operator*() 00120 { 00121 return *m_unit; 00122 } 00123 friend bool operator< (const UnitWrapperBase& wrapper1, const UnitWrapperBase& wrapper2) 00124 { 00125 return wrapper1.m_unit < wrapper2.m_unit; 00126 } 00127 protected: 00128 BWAPI::Unit* m_unit; 00129 }; 00130 struct UnitWrapperBaseCompare 00131 { 00132 bool operator()(const UnitWrapperBase& unit1, const UnitWrapperBase& unit2) const 00133 { 00134 return unit1.getUnit() < unit2.getUnit(); 00135 } 00136 }; 00137 struct UnitWrapperBaseHashCompare : public stdext::hash_compare<UnitWrapperBase, UnitWrapperBaseCompare> 00138 { 00139 size_t operator()(const UnitWrapperBase& unit) const 00140 { 00141 return size_t(unit.getUnit()); 00142 } 00143 bool operator()(const UnitWrapperBase& unit1, const UnitWrapperBase& unit2) const 00144 { 00145 return UnitWrapperBaseCompare()(unit1, unit2); 00146 } 00147 }; 00148 00149 template <class FirstIterator, class SecondIterator> 00150 class general_iterator : public std::iterator<std::forward_iterator_tag, 00151 typename FirstIterator::value_type, 00152 std::ptrdiff_t, 00153 typename FirstIterator::pointer, 00154 typename FirstIterator::reference> 00155 { 00156 static_assert<boost::is_same<typename FirstIterator::value_type, typename SecondIterator::value_type>::value> nested_iterators_must_have_same_value_type; 00157 static_assert<boost::is_same<typename FirstIterator::pointer, typename SecondIterator::pointer>::value> nested_iterators_must_have_same_pointer_type; 00158 static_assert<boost::is_same<typename FirstIterator::reference, typename SecondIterator::reference>::value> nested_iterators_must_have_same_reference_type; 00159 public: 00160 general_iterator(FirstIterator it) 00161 : m_firstIt(it) 00162 , m_useFirst(true) 00163 {} 00164 general_iterator(SecondIterator it) 00165 : m_secondIt(it) 00166 , m_useFirst(false) 00167 {} 00168 template <class OtherFirstIterator, class OtherSecondIterator> 00169 general_iterator(const general_iterator<OtherFirstIterator, OtherSecondIterator>& other) 00170 //: m_firstIt(other.m_useFirst ? other.m_firstIt : FirstIterator()) 00171 //, m_secondIt(other.m_useFirst ? SecondIterator() : other.m_secondIt) 00172 : m_firstIt(other.m_firstIt) 00173 , m_secondIt(other.m_secondIt) 00174 , m_useFirst(other.m_useFirst) 00175 {} 00176 reference operator*() const 00177 { 00178 if (m_useFirst){ 00179 return *m_firstIt; 00180 } 00181 else { 00182 return *m_secondIt; 00183 } 00184 } 00185 general_iterator& operator++() 00186 { 00187 if (m_useFirst){ 00188 ++m_firstIt; 00189 } 00190 else { 00191 ++m_secondIt; 00192 } 00193 return *this; 00194 } 00195 general_iterator operator++(int) 00196 { 00197 general_iterator copy(*this); 00198 ++(*this); 00199 return copy; 00200 } 00201 bool operator== (const general_iterator& other) const 00202 { 00203 if (m_useFirst){ 00204 return m_firstIt == other.m_firstIt; 00205 } 00206 else { 00207 return m_secondIt == other.m_secondIt; 00208 } 00209 } 00210 bool operator!= (const general_iterator& other) const 00211 { 00212 if (m_useFirst){ 00213 return m_firstIt != other.m_firstIt; 00214 } 00215 else { 00216 return m_secondIt != other.m_secondIt; 00217 } 00218 } 00219 general_iterator& operator=(const general_iterator& other) 00220 { 00221 m_firstIt = other.m_firstIt; 00222 m_secondIt = other.m_secondIt; 00223 m_useFirst = other.m_useFirst; 00224 return *this; 00225 } 00226 private: 00227 template <class OtherFirstIterator, class OtherSecondIterator> friend class general_iterator; 00228 FirstIterator m_firstIt; 00229 SecondIterator m_secondIt; 00230 bool m_useFirst; 00231 }; 00232 00233 template <class IteratorPairsTuple, class ValueType> 00234 class concatenate_iterators : public std::iterator<std::forward_iterator_tag, ValueType> 00235 { 00236 public: 00237 concatenate_iterators(IteratorPairsTuple iteratorPairsTuple) 00238 : m_iteratorPairsTuple(iteratorPairsTuple) 00239 , m_currentIterator(0) 00240 { 00241 ForEach<0>(*this).findNext(); 00242 } 00243 value_type operator*() const 00244 { 00245 return *ForEachConst<0>(*this); 00246 } 00247 concatenate_iterators& operator++() 00248 { 00249 ++ForEach<0>(*this); 00250 ForEach<0>(*this).findNext(); 00251 return *this; 00252 } 00253 concatenate_iterators operator++(int) 00254 { 00255 concatenate_iterators copy(*this); 00256 ++(*this); 00257 return copy; 00258 } 00259 bool operator== (const concatenate_iterators& other) const 00260 { 00261 return m_currentIterator == other.m_currentIterator 00262 && ForEachConst<0>(*this) == other; 00263 } 00264 bool operator!= (const concatenate_iterators& other) const 00265 { 00266 return m_currentIterator != other.m_currentIterator 00267 || ForEachConst<0>(*this) != other; 00268 } 00269 concatenate_iterators& operator=(const concatenate_iterators& other) 00270 { 00271 m_currentIterator = other.m_currentIterator; 00272 m_iteratorPairsTuple = other.m_iteratorPairsTuple; 00273 return *this; 00274 } 00275 private: 00276 template <size_t i> 00277 struct ForEachConst 00278 { 00279 ForEachConst(const concatenate_iterators& it) 00280 : m_it(it) 00281 {} 00282 bool operator==(const concatenate_iterators& other) const 00283 { 00284 return m_it.m_iteratorPairsTuple.get<i>().first == other.m_iteratorPairsTuple.get<i>().first 00285 && m_it.m_iteratorPairsTuple.get<i>().second == other.m_iteratorPairsTuple.get<i>().second 00286 && ForEachConst<i+1>(m_it) == other; 00287 } 00288 bool operator!=(const concatenate_iterators& other) const 00289 { 00290 return m_it.m_iteratorPairsTuple.get<i>().first != other.m_iteratorPairsTuple.get<i>().first 00291 || m_it.m_iteratorPairsTuple.get<i>().second != other.m_iteratorPairsTuple.get<i>().second 00292 || ForEachConst<i+1>(m_it) != other; 00293 } 00294 value_type operator*() const 00295 { 00296 if (i == m_it.m_currentIterator) 00297 return *m_it.m_iteratorPairsTuple.get<i>().first; 00298 else 00299 return *ForEachConst<i+1>(m_it); 00300 } 00301 private: 00302 const concatenate_iterators& m_it; 00303 }; 00304 template <> 00305 struct ForEachConst<boost::tuples::length<IteratorPairsTuple>::value> 00306 { 00307 ForEachConst(const concatenate_iterators&){} 00308 bool operator==(const concatenate_iterators&) const { return true; } 00309 bool operator!=(const concatenate_iterators&) const { return false; } 00310 value_type operator*() const { throw std::runtime_error("Internal error: invalid current iterator"); } 00311 }; 00312 00313 template <size_t i> 00314 struct ForEach 00315 { 00316 ForEach(concatenate_iterators& it) 00317 : m_it(it) 00318 {} 00319 void operator++() 00320 { 00321 if (i == m_it.m_currentIterator) 00322 ++m_it.m_iteratorPairsTuple.get<i>().first; 00323 else 00324 ++ForEach<i+1>(m_it); 00325 } 00326 void findNext() 00327 { 00328 if (i < m_it.m_currentIterator) 00329 ForEach<i+1>(m_it).findNext(); 00330 else if (m_it.m_iteratorPairsTuple.get<i>().first == m_it.m_iteratorPairsTuple.get<i>().second) 00331 ForEach<i+1>(m_it).findNext(); 00332 else 00333 m_it.m_currentIterator = i; 00334 } 00335 private: 00336 concatenate_iterators& m_it; 00337 }; 00338 template <> 00339 struct ForEach<boost::tuples::length<IteratorPairsTuple>::value> 00340 { 00341 ForEach(concatenate_iterators& it) 00342 : m_it(it) 00343 {} 00344 void operator++() { throw std::runtime_error("Internal error: invalid current iterator"); } 00345 void findNext() { m_it.m_currentIterator = boost::tuples::length<IteratorPairsTuple>::value; } 00346 private: 00347 concatenate_iterators& m_it; 00348 }; 00349 00350 size_t m_currentIterator; 00351 IteratorPairsTuple m_iteratorPairsTuple; 00352 };