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


Sun Mar 13 2011 Doxygen 1.7.1