Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

GoStaticLadder.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file GoStaticLadder.cpp
00003     See GoStaticLadder.h */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "SgSystem.h"
00007 #include "GoStaticLadder.h"
00008 
00009 #include "GoBoard.h"
00010 
00011 using namespace std;
00012 
00013 //----------------------------------------------------------------------------
00014 
00015 bool GoStaticLadder::IsEdgeLadder(const GoBoard& bd, SgPoint target,
00016                                   SgBlackWhite toPlay)
00017 {
00018     SgBlackWhite defender = bd.GetColor(target);
00019     int nuLibs = bd.NumLiberties(target);
00020     if (nuLibs > 2)
00021         return false;
00022 
00023     // Get attack and defense point
00024     SgPoint attackPoint = SG_NULLMOVE;
00025     SgPoint defensePoint = SG_NULLMOVE;
00026     if (nuLibs == 1)
00027     {
00028         if (toPlay != defender)
00029             return true;
00030         SgPoint theLiberty = bd.TheLiberty(target);
00031         for (SgNb4Iterator it(theLiberty); it; ++it)
00032             if (bd.IsEmpty(*it))
00033             {
00034                 if (attackPoint == SG_NULLMOVE)
00035                     attackPoint = *it;
00036                 else
00037                 {
00038                     SG_ASSERT(defensePoint == SG_NULLMOVE);
00039                     defensePoint = *it;
00040                 }
00041             }
00042     }
00043     else
00044     {
00045         SG_ASSERT(nuLibs == 2);
00046         if (toPlay == defender)
00047             return false;
00048         GoBoard::LibertyIterator it(bd, target);
00049         defensePoint = *it;
00050         ++it;
00051         attackPoint = *it;
00052     }
00053     if (bd.Line(defensePoint) != 1)
00054     {
00055         if (bd.Line(attackPoint) != 1)
00056             return false;
00057         swap(defensePoint, attackPoint);
00058     }
00059 
00060     // Find direction to run ladder
00061     int col = SgPointUtil::Col(defensePoint);
00062     int delta;
00063     switch (defensePoint - attackPoint)
00064     {
00065     case SG_NS + SG_WE:
00066         delta = (col == bd.Size() ? SG_NS : SG_WE);
00067         break;
00068     case SG_NS - SG_WE:
00069         delta = (col == 1 ? SG_NS : -SG_WE);
00070         break;
00071     case -SG_NS + SG_WE:
00072         delta = (col == bd.Size() ? -SG_NS : SG_WE);
00073         break;
00074     case -SG_NS - SG_WE:
00075         delta = (col == 1 ? -SG_NS : -SG_WE);
00076         break;
00077     default:
00078         return false;
00079     }
00080 
00081     // @todo Check that no block in atari is adjacent to target block (?)
00082 
00083     // Compute ladder
00084     while (true)
00085     {
00086         SG_ASSERT(bd.IsEmpty(defensePoint));
00087         SG_ASSERT(bd.IsEmpty(attackPoint));
00088         int nuNeighborsDefender = bd.NumNeighbors(defensePoint, defender);
00089         if (nuNeighborsDefender > 1)
00090             return false;
00091         if (nuNeighborsDefender == 0
00092             && bd.NumEmptyNeighbors(defensePoint) < 3)
00093             return true;
00094         defensePoint += delta;
00095         attackPoint += delta;
00096         if (! bd.IsEmpty(defensePoint) || ! bd.IsEmpty(attackPoint))
00097             return false;
00098     }
00099 
00100     return true;
00101 }
00102 
00103 bool GoStaticLadder::IsLadder(const GoBoard& bd, SgPoint target,
00104                               SgBlackWhite toPlay)
00105 {
00106     return IsEdgeLadder(bd, target, toPlay);
00107     // @todo Handle ladder with target not on edge
00108 }
00109 
00110 //----------------------------------------------------------------------------


Sun Mar 13 2011 Doxygen 1.7.1