Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoUctDefaultPriorKnowledge.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoUctDefaultPriorKnowledge.cpp
00003     See GoUctDefaultPriorKnowledge.h
00004 */
00005 //----------------------------------------------------------------------------
00006 
00007 #include "SgSystem.h"
00008 #include "GoUctDefaultPriorKnowledge.h"
00009 
00010 using namespace std;
00011 
00012 //----------------------------------------------------------------------------
00013 
00014 namespace {
00015 
00016 bool SetsAtari(const GoBoard& bd, SgPoint p)
00017 {
00018     SG_ASSERT(bd.IsEmpty(p)); // Already checked
00019     SgBlackWhite opp = SgOppBW(bd.ToPlay());
00020     if (bd.NumNeighbors(p, opp) == 0)
00021         return false;
00022     if (! bd.IsBorder(p + SG_NS) && bd.GetColor(p + SG_NS) == opp
00023         && bd.NumLiberties(p + SG_NS) == 2)
00024         return true;
00025     if (! bd.IsBorder(p - SG_NS) && bd.GetColor(p - SG_NS) == opp
00026         && bd.NumLiberties(p - SG_NS) == 2)
00027         return true;
00028     if (! bd.IsBorder(p + SG_WE) && bd.GetColor(p + SG_WE) == opp
00029         && bd.NumLiberties(p + SG_WE) == 2)
00030         return true;
00031     if (! bd.IsBorder(p - SG_WE) && bd.GetColor(p - SG_WE) == opp
00032         && bd.NumLiberties(p - SG_WE) == 2)
00033         return true;
00034     return false;
00035 }
00036 
00037 } // namespace
00038 
00039 //----------------------------------------------------------------------------
00040 
00041 GoUctKnowledge::GoUctKnowledge(const GoBoard& bd)
00042     : m_bd(bd)
00043 {
00044 }
00045 
00046 GoUctKnowledge::~GoUctKnowledge()
00047 {
00048 }
00049 
00050 void GoUctKnowledge::Add(SgPoint p, float value, size_t count)
00051 {
00052     m_values[p].Add(value, count);
00053 }
00054 
00055 void GoUctKnowledge::Initialize(SgPoint p, float value, size_t count)
00056 {
00057     m_values[p].Initialize(value, count);
00058 }
00059 
00060 void GoUctKnowledge::ClearValues()
00061 {
00062     for (std::size_t i = 0; i < SG_PASS+1; ++i)
00063         m_values[i].Clear();
00064 }
00065 
00066 void GoUctKnowledge::TransferValues(std::vector<SgMoveInfo>& outmoves) const
00067 {
00068     for (std::size_t i = 0; i < outmoves.size(); ++i) 
00069     {
00070         SgMove p = outmoves[i].m_move;
00071         if (m_values[p].IsDefined())
00072         {
00073             outmoves[i].m_count = m_values[p].Count();
00074             outmoves[i].m_value =
00075                 SgUctSearch::InverseEval(m_values[p].Mean());
00076             outmoves[i].m_raveCount = m_values[p].Count();
00077             outmoves[i].m_raveValue = m_values[p].Mean();
00078         }
00079     }
00080 }
00081 
00082 //----------------------------------------------------------------------------
00083 
00084 GoUctDefaultPriorKnowledge::GoUctDefaultPriorKnowledge(const GoBoard& bd,
00085                               const GoUctPlayoutPolicyParam& param)
00086     : GoUctKnowledge(bd),
00087       m_policy(bd, param)
00088 {
00089 }
00090 
00091 void GoUctDefaultPriorKnowledge::AddLocalityBonus(GoPointList& emptyPoints,
00092                                                   bool isSmallBoard)
00093 {
00094     SgPoint last = m_bd.GetLastMove();
00095     if (last != SG_NULLMOVE && last != SG_PASS)
00096     {
00097         SgPointArray<int> dist = GoBoardUtil::CfgDistance(m_bd, last, 3);
00098         const size_t count = (isSmallBoard ? 4 : 5);
00099         for (GoPointList::Iterator it(emptyPoints); it; ++it)
00100         {
00101             const SgPoint p = *it;
00102             switch (dist[p])
00103             {
00104             case 1:
00105                 Add(p, 1.0, count);
00106                 break;
00107             case 2:
00108                 Add(p, 0.6, count);
00109                 break;
00110             case 3:
00111                 Add(p, 0.6, count);
00112                 break;
00113             default:
00114                 Add(p, 0.1, count);
00115                 break;
00116             }
00117         }
00118         Add(SG_PASS, 0.1, count);
00119     }
00120 }
00121 
00122 /** Find global moves that match a playout pattern or set a block into atari.
00123     @param[out] pattern
00124     @param[out] atari
00125     @param[out] empty As a side effect, this function finds all empty points
00126     on the board
00127     @return @c true if any such moves was found
00128 */
00129 bool GoUctDefaultPriorKnowledge::FindGlobalPatternAndAtariMoves(
00130                                                      SgPointSet& pattern,
00131                                                      SgPointSet& atari,
00132                                                      GoPointList& empty) const
00133 {
00134     SG_ASSERT(empty.IsEmpty());
00135     const GoUctPatterns<GoBoard>& patterns = m_policy.Patterns();
00136     bool result = false;
00137     for (GoBoard::Iterator it(m_bd); it; ++it)
00138         if (m_bd.IsEmpty(*it))
00139         {
00140             empty.PushBack(*it);
00141             if (patterns.MatchAny(*it))
00142             {
00143                 pattern.Include(*it);
00144                 result = true;
00145             }
00146             if (SetsAtari(m_bd, *it))
00147             {
00148                 atari.Include(*it);
00149                 result = true;
00150             }
00151         }
00152     return result;
00153 }
00154 
00155 void 
00156 GoUctDefaultPriorKnowledge::ProcessPosition(std::vector<SgMoveInfo>& outmoves)
00157 {
00158     m_policy.StartPlayout();
00159     m_policy.GenerateMove();
00160     GoUctPlayoutPolicyType type = m_policy.MoveType();
00161     bool isFullBoardRandom =
00162         (type == GOUCT_RANDOM || type == GOUCT_FILLBOARD);
00163     SgPointSet pattern;
00164     SgPointSet atari;
00165     GoPointList empty;
00166     bool anyHeuristic = FindGlobalPatternAndAtariMoves(pattern, atari, empty);
00167 
00168     // The initialization values/counts are mainly tuned by selfplay
00169     // experiments and games vs MoGo Rel 3 and GNU Go 3.6 on 9x9 and 19x19.
00170     // If different values are used for the small and large board, the ones
00171     // from the 9x9 experiments are used for board sizes < 15, the ones from
00172     // 19x19 otherwise.
00173     const bool isSmallBoard = (m_bd.Size() < 15);
00174 
00175     Initialize(SG_PASS, 0.1, isSmallBoard ? 9 : 18);
00176     if (isFullBoardRandom && ! anyHeuristic)
00177     {
00178         for (GoBoard::Iterator it(m_bd); it; ++it)
00179         {
00180             SgPoint p = *it;
00181             if (! m_bd.IsEmpty(p))
00182                 continue;
00183             if (GoBoardUtil::SelfAtari(m_bd, *it))
00184                 Initialize(*it, 0.1, isSmallBoard ? 9 : 18);
00185             else
00186                 m_values[p].Clear(); // Don't initialize
00187         }
00188     }
00189     else if (isFullBoardRandom && anyHeuristic)
00190     {
00191         for (GoBoard::Iterator it(m_bd); it; ++it)
00192         {
00193             SgPoint p = *it;
00194             if (! m_bd.IsEmpty(p))
00195                 continue;
00196             if (GoBoardUtil::SelfAtari(m_bd, *it))
00197                 Initialize(*it, 0.1, isSmallBoard ? 9 : 18);
00198             else if (atari[*it])
00199                 Initialize(*it, 1.0, 3);
00200             else if (pattern[*it])
00201                 Initialize(*it, 0.9, 3);
00202             else
00203                 Initialize(*it, 0.5, 3);
00204         }
00205     }
00206     else
00207     {
00208         for (GoBoard::Iterator it(m_bd); it; ++it)
00209         {
00210             SgPoint p = *it;
00211             if (! m_bd.IsEmpty(p))
00212                 continue;
00213             if (GoBoardUtil::SelfAtari(m_bd, *it))
00214                 Initialize(*it, 0.1, isSmallBoard ? 9 : 18);
00215             else if (atari[*it])
00216                 Initialize(*it, 0.8, isSmallBoard ? 9 : 18);
00217             else if (pattern[*it])
00218                 Initialize(*it, 0.6, isSmallBoard ? 9 : 18);
00219             else
00220                 Initialize(*it, 0.4, isSmallBoard ? 9 : 18);
00221         }
00222         GoPointList moves = m_policy.GetEquivalentBestMoves();
00223         for (GoPointList::Iterator it(moves); it; ++it)
00224             Initialize(*it, 1.0, isSmallBoard ? 9 : 18);
00225     }
00226     AddLocalityBonus(empty, isSmallBoard);
00227     m_policy.EndPlayout();
00228 
00229     TransferValues(outmoves);
00230 }
00231 
00232 //----------------------------------------------------------------------------


17 Jun 2010 Doxygen 1.4.7