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


17 Jun 2010 Doxygen 1.4.7