BWAPI
SPAR/AIModule/SparAIModule/Utils/Utils.h
Go to the documentation of this file.
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 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines