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 
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 /** Return true, if point is on edge line and no stone is within a
00022     Manhattan distance of 4.
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     // Safe territory
00063 
00064     GoModBoard modBoard(m_bd);
00065     GoBoard& bd = modBoard.Board();
00066 
00067     SgBWSet alternateSafe;
00068     bool isAllAlternateSafe = false;
00069     // Alternate safety is used to prune moves only in opponent territory
00070     // and only if everything is alive under alternate play. This ensures that
00071     // capturing moves that are not liberties of dead blocks and ko threats
00072     // will not be pruned. This alternate safety pruning is not going to
00073     // improve or worsen playing strength, but may cause earlier passes,
00074     // which is nice in games against humans
00075     GoSafetySolver safetySolver(bd);
00076     safetySolver.FindSafePoints(&alternateSafe);
00077     isAllAlternateSafe = (alternateSafe.Both() == bd.AllPoints());
00078 
00079     // Benson solver guarantees that capturing moves of dead blocks are
00080     // liberties of the dead blocks and that no move in Benson safe territory
00081     // is a ko threat
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             // Always generate capturing moves in own safe territory, even
00096             // if current rules do no use CaptureDead(), because the UCT
00097             // player always scores with Tromp-Taylor after two passes in the
00098             // in-tree phase
00099             if ((isAllAlternateSafe && isAlternateSafeOpp)
00100                 || isUnconditionalSafeOpp
00101                 || (isUnconditionalSafe && ! hasOppNeighbors))
00102                 rootFilter.push_back(p);
00103         }
00104     }
00105 
00106     // Loosing ladder defense moves
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/*twoLibIsEscape*/) < 0)
00115                 {
00116                     if (m_ladderSequence.Length() >= m_minLadderLength)
00117                         rootFilter.push_back(m_bd.TheLiberty(p));
00118                 }
00119             }
00120 
00121         }
00122 
00123     // Moves on edge line, if no stone is near
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 //----------------------------------------------------------------------------


17 Jun 2010 Doxygen 1.4.7