00001 //---------------------------------------------------------------------------- 00002 /** @file GoInfluence.cpp 00003 See GoInfluence.h 00004 */ 00005 //---------------------------------------------------------------------------- 00006 00007 #include "SgSystem.h" 00008 #include "GoInfluence.h" 00009 00010 #include "SgNbIterator.h" 00011 00012 //---------------------------------------------------------------------------- 00013 namespace { 00014 //---------------------------------------------------------------------------- 00015 00016 /** Spread influence */ 00017 void Spread(const GoBoard& bd, SgPoint p, const SgPointSet& stopPts, 00018 int val, SgPointArray<int>& influence) 00019 { 00020 influence[p] += val; 00021 val /= 2; 00022 if (val > 0) 00023 for (SgNb4Iterator it(p); it; ++it) 00024 if (bd.IsValidPoint(*it) && ! stopPts.Contains(*it)) 00025 Spread(bd, *it, stopPts, val, influence); 00026 } 00027 00028 //---------------------------------------------------------------------------- 00029 } // namespace 00030 //---------------------------------------------------------------------------- 00031 00032 void GoInfluence::FindInfluence(const GoBoard& board, 00033 int nuExpand, 00034 int nuShrink, 00035 SgBWSet* influence) 00036 { 00037 SgBWSet result = SgBWSet(board.All(SG_BLACK), board.All(SG_WHITE)); 00038 SgBWSet next; 00039 const int size = board.Size(); 00040 for (int i = 1; i <= nuExpand; ++i) 00041 { 00042 for (SgBlackWhite c = SG_BLACK; c <= SG_WHITE; ++c) 00043 { 00044 SgBlackWhite opp = SgOppBW(c); 00045 next[c] = result[c].Border(size) - result[opp]; 00046 } 00047 result[SG_BLACK] |= (next[SG_BLACK] - next[SG_WHITE]); 00048 result[SG_WHITE] |= (next[SG_WHITE] - next[SG_BLACK]); 00049 } 00050 00051 for (int i = 1; i <= nuShrink; ++i) 00052 { 00053 result[SG_BLACK] = result[SG_BLACK].Kernel(size); 00054 result[SG_WHITE] = result[SG_WHITE].Kernel(size); 00055 } 00056 00057 *influence = result; 00058 } 00059 00060 int GoInfluence::Influence(const GoBoard& board, 00061 SgBlackWhite color, 00062 int nuExpand, 00063 int nuShrink) 00064 { 00065 SgBWSet result; 00066 FindInfluence(board, nuExpand, nuShrink, &result); 00067 return result[color].Size(); 00068 } 00069 00070 00071 void GoInfluence::ComputeInfluence(const GoBoard& bd, 00072 const SgBWSet& stopPts, 00073 SgBWArray<SgPointArray<int> >* influence) 00074 { 00075 const int MAX_INFLUENCE = 64; 00076 for (SgBWIterator it; it; ++it) 00077 { 00078 SgBlackWhite color = *it; 00079 ((*influence)[color]).Fill(0); 00080 for (GoBoard::Iterator it(bd); it; ++it) 00081 { 00082 SgPoint p(*it); 00083 if (bd.IsColor(p, color)) 00084 Spread(bd, p, stopPts[color], MAX_INFLUENCE, 00085 (*influence)[color]); 00086 } 00087 } 00088 } 00089 00090