00001 //---------------------------------------------------------------------------- 00002 /** @file SgMiaiStrategy.cpp 00003 See SgMiaiStrategy.h */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgMiaiStrategy.h" 00008 00009 #include "SgWrite.h" 00010 00011 //---------------------------------------------------------------------------- 00012 00013 SgPoint SgMiaiPairUtil::Other(const SgMiaiPair& pair, SgPoint p) 00014 { 00015 SG_ASSERT(pair.first == p || pair.second == p); 00016 return pair.first == p ? pair.second : pair.first; 00017 } 00018 00019 //---------------------------------------------------------------------------- 00020 00021 void SgMiaiStrategy::Write(std::ostream& stream) const 00022 { 00023 SgStrategy::Write(stream); 00024 stream << "Miai Strategies: "; 00025 for (SgVectorIterator<SgMiaiPair> it(m_miaiStrategies); it; ++it) 00026 stream << '(' << SgWritePoint((*it).first) 00027 << "-" << SgWritePoint((*it).second) 00028 << ") "; 00029 stream << "\n" << SgWritePointList(m_openThreats, "open threats", false) 00030 << "Broken: " << m_failed 00031 << '\n'; 00032 } 00033 00034 void SgMiaiStrategy::AddPair(const SgMiaiPair& m) 00035 { 00036 #ifndef NDEBUG // check that points are new. 00037 SgPointSet dependency = Dependency(); 00038 SG_ASSERT(! dependency.Contains(m.first)); 00039 SG_ASSERT(! dependency.Contains(m.second)); 00040 SG_ASSERT(m.first != m.second); 00041 // SG_PASS, NullMove are not valid miai Points. 00042 SG_ASSERT(SgPointUtil::InBoardRange(m.first)); 00043 SG_ASSERT(SgPointUtil::InBoardRange(m.second)); 00044 #endif 00045 m_miaiStrategies.PushBack(m); 00046 } 00047 00048 00049 void SgMiaiStrategy::Clear() 00050 { 00051 SgStrategy::Clear(); 00052 m_miaiStrategies.Clear(); 00053 m_openThreats.Clear(); 00054 m_failed = false; 00055 SG_ASSERT(Dependency().IsEmpty()); 00056 } 00057 00058 SgPointSet SgMiaiStrategy::Dependency() const 00059 { 00060 SgPointSet dependency; 00061 for (SgVectorIterator<SgMiaiPair> it(m_miaiStrategies); it; ++it) 00062 { 00063 dependency.Include((*it).first); 00064 dependency.Include((*it).second); 00065 } 00066 return dependency; 00067 } 00068 00069 SgStrategyStatus SgMiaiStrategy::Status() const 00070 { 00071 if (m_failed) 00072 return SGSTRATEGY_FAILED; 00073 else if (m_openThreats.IsEmpty()) 00074 return SGSTRATEGY_ACHIEVED; 00075 else if (m_openThreats.IsLength(1)) 00076 return SGSTRATEGY_THREATENED; 00077 else 00078 return SGSTRATEGY_FAILED; 00079 } 00080 00081 void SgMiaiStrategy::StrategyFailed() 00082 { 00083 m_failed = true; 00084 m_openThreats.Clear(); 00085 m_miaiStrategies.Clear(); 00086 } 00087 00088 void SgMiaiStrategy::ExecuteMove(const SgPoint p, SgBlackWhite player) 00089 { 00090 if (m_failed) 00091 /* */ return; /* */ 00092 00093 SgVector<SgPoint> fixedThreats; 00094 for (SgVectorIterator<SgPoint> it(m_openThreats); it; ++it) 00095 if (p == *it) 00096 { 00097 if (player == Player()) 00098 fixedThreats.PushBack(*it); 00099 else 00100 { 00101 StrategyFailed(); 00102 break; 00103 } 00104 } 00105 00106 if (m_failed) 00107 { 00108 /* */ return; /* */ 00109 } 00110 00111 SgVector<SgMiaiPair> toChange; 00112 for (SgVectorIterator<SgMiaiPair> it(m_miaiStrategies); it; ++it) 00113 if (p == (*it).first || p == (*it).second) 00114 toChange.PushBack(*it); 00115 00116 m_miaiStrategies.Exclude(toChange); 00117 if (player == Player()) 00118 { 00119 m_openThreats.Exclude(fixedThreats); 00120 // All toChange strategies have been achieved - remove. 00121 } 00122 else 00123 // move other endpoint of toChange to open threats 00124 for (SgVectorIterator<SgMiaiPair> it(toChange); it; ++it) 00125 { 00126 m_openThreats.PushBack(SgMiaiPairUtil::Other(*it, p)); 00127 } 00128 } 00129 00130 bool SgMiaiStrategy::HasOverlappingMiaiPairs() const 00131 { 00132 SgPointSet used; 00133 for (SgVectorIterator<SgMiaiPair> it(m_miaiStrategies); it; ++it) 00134 { 00135 const SgPoint p1 = (*it).first; 00136 const SgPoint p2 = (*it).second; 00137 if (used[p1] || used[p2]) 00138 /* */ return true; /* */ 00139 00140 used.Include(p1); 00141 used.Include(p2); 00142 } 00143 return false; 00144 } 00145 00146 const SgVector<SgPoint>& SgMiaiStrategy::OpenThreats() const 00147 { 00148 return m_openThreats; 00149 } 00150 00151 SgPoint SgMiaiStrategy::OpenThreatMove() const 00152 { 00153 SG_ASSERT(m_openThreats.MaxLength(1)); 00154 return m_openThreats.IsEmpty() ? SG_NULLPOINT : 00155 m_openThreats.Back(); 00156 } 00157 00158 void SgMiaiStrategy::UndoMove() 00159 { 00160 SG_ASSERT(false); 00161 }