Beispiel #1
0
bool GoEyeUtil::CheckInterior(const GoBoard& bd, const SgPointSet& area,
                   SgBlackWhite opp, bool checkBlocks)
{
    bool hasSingleNbPoint = false;
    int nuPoints = 0;
    for (SgSetIterator it(area); it; ++it)
    {
        const SgPoint p(*it);
        if (bd.IsEmpty(p))
        {
            int nuNbs = 0;
            if (area.Contains(p + SG_NS))
                ++nuNbs;
            if (area.Contains(p - SG_NS))
                ++nuNbs;
            if (area.Contains(p + SG_WE))
                ++nuNbs;
            if (area.Contains(p - SG_WE))
                ++nuNbs;
            if (nuNbs == 1)
                hasSingleNbPoint = true;
            else if (nuNbs > 2)
                return false;
        }
        else if (p == bd.Anchor(p))
        {
            if (bd.GetColor(p) != opp)
            // if own stones on inside: not a tree shape.
                return false;
            int nuLibs = bd.NumLiberties(p);
            if (nuLibs == 1)
                hasSingleNbPoint = true;
            else if (checkBlocks && nuLibs > 2)
                return false;
        }
        ++nuPoints;
    }
    return nuPoints == 1 || hasSingleNbPoint;
}
Beispiel #2
0
void GoLadderUtil::FindLadderEscapeMoves(const GoBoard& bd, SgPoint prey, 
                           SgVector<SgPoint>& escapeMoves)
{
    SG_ASSERT(bd.NumLiberties(prey) == 1);
    SG_ASSERT(escapeMoves.IsEmpty());
    
    SgPoint p = bd.TheLiberty(prey);
    SgVector<SgPoint> candidates;
    candidates.PushBack(p);
    if (IsLadderEscapeMove(bd, prey, p))
    	escapeMoves.PushBack(p);
    for (GoAdjBlockIterator<GoBoard> it(bd, prey, 1); it; ++it)
    {
        // check if prey can escape by capturing *it on p.
        SgPoint p = bd.TheLiberty(*it);
        if (! candidates.Contains(p))
        {
		    candidates.PushBack(p);
        	if (IsLadderEscapeMove(bd, prey, p))
            	escapeMoves.PushBack(p);
        }
    }
}                           
Beispiel #3
0
bool GoLadderUtil::IsLadderEscapeMove(const GoBoard& constBd, 
									   SgPoint prey, SgPoint firstMove)
{
    SG_ASSERT(constBd.NumLiberties(prey) == 1);
    GoModBoard mbd(constBd);
    GoBoard& bd = mbd.Board();
    const SgBlackWhite defender = bd.GetStone(prey);
    const SgBlackWhite attacker = SgOppBW(defender);
    GoRestoreToPlay r(bd);
    bd.SetToPlay(defender);
    if (PlayIfLegal(bd, firstMove, defender))
    {
	    GoLadder ladder;
        bool isCapture = ladder.Ladder(bd, prey, attacker, 
                                       0, false/*twoLibIsEscape*/
                                      ) < 0;
    	bd.Undo();
        return ! isCapture;
    }
    else
    	return false;

}
Beispiel #4
0
bool GoEyeUtil::NumberOfMoveToEye2(const GoBoard& board, SgBlackWhite color,
                                   SgPoint p, int& nummoves)
{
    nummoves = 0;
    bool capturing = false;
    SgVector<SgPoint> usedpoints;
    usedpoints.PushBack(p);
    SgPointSet counted;

    // Can never turn own stone into an eye
    if (board.IsColor(p, color))
        return false;
    
    // If opponent stone then it must be captured to make eye
    if (board.IsColor(p, SgOppBW(color)))
    {
        capturing = true;
    
        // If it is obviously safe then it can never be an eye
        if (SinglePointSafe2(board, p)) // Quick, naive safety test
            return false;

        for (GoBoard::LibertyIterator libit(board, p); libit; ++libit)
            counted.Include(*libit);
    }

    // Count immediate adjacencies
    for (SgNb4Iterator nb(p); nb; ++nb)
    {
        SgPoint adj = *nb;
        
        // Empty points must be filled
        if (board.IsColor(adj, SG_EMPTY))
        {
            counted.Include(adj);
        }
        
        // If adjacent opponent then can never be an eye
        else if (board.IsColor(adj, SgOppBW(color)))
        {
            if (capturing)
                counted.Include(adj); // must capture and then fill
            else
                return false;
        }
    }

    // Up to one diagonal can be ignored: estimate most costly
    SgPoint toignore = SG_NULLPOINT;
    int maxcost = 0;
    int infcost = 1000;
    if (board.Line(p) > 1)
    {
        for (SgNb4DiagIterator nbd(p); nbd; ++nbd)
        {
            SgPoint diag = *nbd;
            int cost = 0;

            if (  board.IsColor(diag, SG_EMPTY)
               && ! IsSinglePointEye2(board, diag, color, usedpoints))
            {
                cost = 1;
            }
            
            else if (board.IsColor(diag, SgOppBW(color)))
            {
                // quick safety test
                if (SinglePointSafe2(board, diag))
                    cost = infcost;
                else
                    cost = board.NumLiberties(diag);
            }

            if (cost > maxcost)
            {
                maxcost = cost;
                toignore = diag;
            }
        }
    }

    // Now mark points that must be played to secure diagonals
    for (SgNb4DiagIterator nbd(p); nbd; ++nbd)
    {
        SgPoint diag = *nbd;
        if (diag == toignore)
            continue;
        
        // Empty points must be filled (unless they are eyes)
        if (  board.IsColor(diag, SG_EMPTY)
           && ! IsSinglePointEye2(board, diag, color, usedpoints))
        {
            counted.Include(diag);
        }
        
        // Opponent stones on diagonals must be captured and filled
        else if (board.IsColor(diag, SgOppBW(color)))
        {
            if (SinglePointSafe2(board, diag))
                return false;
            else
            {
                counted.Include(diag);
                for (GoBoard::LibertyIterator libit(board, diag); libit;
                     ++libit)
                    counted.Include(*libit);
            }
        }
    }

    nummoves = counted.Size();
    return true;
}