00001
00002
00003
00004
00005
00006
00007 #include "SgSystem.h"
00008 #include "GoInfluence.h"
00009
00010 #include "SgNbIterator.h"
00011
00012
00013 namespace {
00014
00015
00016
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 }
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