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