Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoUctDefaultRootFilter.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoUctDefaultRootFilter.cpp
00003     See GoUctDefaultRootFilter.h */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "GoUctDefaultRootFilter.h"
00008 
00009 #include "GoBensonSolver.h"
00010 #include "GoBoard.h"
00011 #include "GoBoardUtil.h"
00012 #include "GoModBoard.h"
00013 #include "GoSafetySolver.h"
00014 #include "SgWrite.h"
00015 
00016 using namespace std;
00017 
00018 //----------------------------------------------------------------------------
00019 
00020 /** Return true, if point is on edge line and no stone is within a
00021     Manhattan distance of 4. */
00022 bool IsEmptyEdge(const GoBoard& bd, SgPoint p)
00023 {
00024     if (bd.Occupied(p))
00025         return false;
00026     int size = bd.Size();
00027     int col = SgPointUtil::Col(p);
00028     int row = SgPointUtil::Row(p);
00029     if (! (col == 1 || col == size || row == 1 || row == size))
00030         return false;
00031     for (int deltaCol = -4; deltaCol <= 4; ++deltaCol)
00032         for (int deltaRow = -4; deltaRow <= 4; ++deltaRow)
00033         {
00034             if (col + deltaCol < 1 || col + deltaCol > size
00035                 || row + deltaRow < 1 || row + deltaRow > size
00036                 || abs(deltaCol) + abs(deltaRow) > 4)
00037                 continue;
00038             if (bd.Occupied(SgPointUtil::Pt(col + deltaCol,
00039                                             row + deltaRow)))
00040                 return false;
00041         }
00042     return true;
00043 }
00044 
00045 //----------------------------------------------------------------------------
00046 
00047 GoUctDefaultRootFilter::GoUctDefaultRootFilter(const GoBoard& bd)
00048     : m_bd(bd),
00049       m_checkLadders(true),
00050       m_minLadderLength(6)
00051 {
00052 }
00053 
00054 vector<SgPoint> GoUctDefaultRootFilter::Get()
00055 {
00056     vector<SgPoint> rootFilter;
00057     SgBlackWhite toPlay = m_bd.ToPlay();
00058     SgBlackWhite opp = SgOppBW(toPlay);
00059 
00060     // Safe territory
00061 
00062     GoModBoard modBoard(m_bd);
00063     GoBoard& bd = modBoard.Board();
00064 
00065     SgBWSet alternateSafe;
00066     bool isAllAlternateSafe = false;
00067     // Alternate safety is used to prune moves only in opponent territory
00068     // and only if everything is alive under alternate play. This ensures that
00069     // capturing moves that are not liberties of dead blocks and ko threats
00070     // will not be pruned. This alternate safety pruning is not going to
00071     // improve or worsen playing strength, but may cause earlier passes,
00072     // which is nice in games against humans
00073     GoSafetySolver safetySolver(bd);
00074     safetySolver.FindSafePoints(&alternateSafe);
00075     isAllAlternateSafe = (alternateSafe.Both() == bd.AllPoints());
00076 
00077     // Benson solver guarantees that capturing moves of dead blocks are
00078     // liberties of the dead blocks and that no move in Benson safe territory
00079     // is a ko threat
00080     GoBensonSolver bensonSolver(bd);
00081     SgBWSet unconditionalSafe;
00082     bensonSolver.FindSafePoints(&unconditionalSafe);
00083 
00084     for (GoBoard::Iterator it(bd); it; ++it)
00085     {
00086         SgPoint p = *it;
00087         if (m_bd.IsLegal(p))
00088         {
00089             bool isUnconditionalSafe = unconditionalSafe[toPlay].Contains(p);
00090             bool isUnconditionalSafeOpp = unconditionalSafe[opp].Contains(p);
00091             bool isAlternateSafeOpp = alternateSafe[opp].Contains(p);
00092             bool hasOppNeighbors = bd.HasNeighbors(p, opp);
00093             // Always generate capturing moves in own safe territory, even
00094             // if current rules do no use CaptureDead(), because the UCT
00095             // player always scores with Tromp-Taylor after two passes in the
00096             // in-tree phase
00097             if ((isAllAlternateSafe && isAlternateSafeOpp)
00098                 || isUnconditionalSafeOpp
00099                 || (isUnconditionalSafe && ! hasOppNeighbors))
00100                 rootFilter.push_back(p);
00101         }
00102     }
00103 
00104     // Loosing ladder defense moves
00105     if (m_checkLadders)
00106         for (GoBlockIterator it(m_bd); it; ++it)
00107         {
00108             SgPoint p = *it;
00109             if (m_bd.GetStone(p) == toPlay && m_bd.InAtari(p))
00110             {
00111                 if (m_ladder.Ladder(m_bd, p, toPlay, &m_ladderSequence,
00112                                     false/*twoLibIsEscape*/) < 0)
00113                 {
00114                     if (m_ladderSequence.Length() >= m_minLadderLength)
00115                         rootFilter.push_back(m_bd.TheLiberty(p));
00116                 }
00117             }
00118 
00119         }
00120 
00121     // Moves on edge line, if no stone is near
00122     for (GoBoard::Iterator it(m_bd); it; ++it)
00123     {
00124         SgPoint p = *it;
00125         if (IsEmptyEdge(m_bd, p))
00126             rootFilter.push_back(p);
00127     }
00128 
00129     return rootFilter;
00130 }
00131 
00132 //----------------------------------------------------------------------------


Sun Mar 13 2011 Doxygen 1.7.1