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