00001
00002
00003
00004
00005
00006
00007 #include "SgSystem.h"
00008 #include "GoUctDefaultRootFilter.h"
00009
00010 #include "GoBensonSolver.h"
00011 #include "GoBoard.h"
00012 #include "GoBoardUtil.h"
00013 #include "GoModBoard.h"
00014 #include "GoSafetySolver.h"
00015 #include "SgWrite.h"
00016
00017 using namespace std;
00018
00019
00020
00021
00022
00023
00024 bool IsEmptyEdge(const GoBoard& bd, SgPoint p)
00025 {
00026 if (bd.Occupied(p))
00027 return false;
00028 int size = bd.Size();
00029 int col = SgPointUtil::Col(p);
00030 int row = SgPointUtil::Row(p);
00031 if (! (col == 1 || col == size || row == 1 || row == size))
00032 return false;
00033 for (int deltaCol = -4; deltaCol <= 4; ++deltaCol)
00034 for (int deltaRow = -4; deltaRow <= 4; ++deltaRow)
00035 {
00036 if (col + deltaCol < 1 || col + deltaCol > size
00037 || row + deltaRow < 1 || row + deltaRow > size
00038 || abs(deltaCol) + abs(deltaRow) > 4)
00039 continue;
00040 if (bd.Occupied(SgPointUtil::Pt(col + deltaCol,
00041 row + deltaRow)))
00042 return false;
00043 }
00044 return true;
00045 }
00046
00047
00048
00049 GoUctDefaultRootFilter::GoUctDefaultRootFilter(const GoBoard& bd)
00050 : m_bd(bd),
00051 m_checkLadders(true),
00052 m_minLadderLength(6)
00053 {
00054 }
00055
00056 vector<SgPoint> GoUctDefaultRootFilter::Get()
00057 {
00058 vector<SgPoint> rootFilter;
00059 SgBlackWhite toPlay = m_bd.ToPlay();
00060 SgBlackWhite opp = SgOppBW(toPlay);
00061
00062
00063
00064 GoModBoard modBoard(m_bd);
00065 GoBoard& bd = modBoard.Board();
00066
00067 SgBWSet alternateSafe;
00068 bool isAllAlternateSafe = false;
00069
00070
00071
00072
00073
00074
00075 GoSafetySolver safetySolver(bd);
00076 safetySolver.FindSafePoints(&alternateSafe);
00077 isAllAlternateSafe = (alternateSafe.Both() == bd.AllPoints());
00078
00079
00080
00081
00082 GoBensonSolver bensonSolver(bd);
00083 SgBWSet unconditionalSafe;
00084 bensonSolver.FindSafePoints(&unconditionalSafe);
00085
00086 for (GoBoard::Iterator it(bd); it; ++it)
00087 {
00088 SgPoint p = *it;
00089 if (m_bd.IsLegal(p))
00090 {
00091 bool isUnconditionalSafe = unconditionalSafe[toPlay].Contains(p);
00092 bool isUnconditionalSafeOpp = unconditionalSafe[opp].Contains(p);
00093 bool isAlternateSafeOpp = alternateSafe[opp].Contains(p);
00094 bool hasOppNeighbors = bd.HasNeighbors(p, opp);
00095
00096
00097
00098
00099 if ((isAllAlternateSafe && isAlternateSafeOpp)
00100 || isUnconditionalSafeOpp
00101 || (isUnconditionalSafe && ! hasOppNeighbors))
00102 rootFilter.push_back(p);
00103 }
00104 }
00105
00106
00107 if (m_checkLadders)
00108 for (GoBlockIterator it(m_bd); it; ++it)
00109 {
00110 SgPoint p = *it;
00111 if (m_bd.GetStone(p) == toPlay && m_bd.InAtari(p))
00112 {
00113 if (m_ladder.Ladder(m_bd, p, toPlay, &m_ladderSequence,
00114 false) < 0)
00115 {
00116 if (m_ladderSequence.Length() >= m_minLadderLength)
00117 rootFilter.push_back(m_bd.TheLiberty(p));
00118 }
00119 }
00120
00121 }
00122
00123
00124 for (GoBoard::Iterator it(m_bd); it; ++it)
00125 {
00126 SgPoint p = *it;
00127 if (IsEmptyEdge(m_bd, p))
00128 rootFilter.push_back(p);
00129 }
00130
00131 return rootFilter;
00132 }
00133
00134