bool GoEyeUtil::NumberOfMoveToEye(const GoBoard& board, SgBlackWhite color, SgPoint p, int& number) { SG_ASSERT(board.IsEmpty(p)); SgBlackWhite att = SgOppBW(color); // attacker if ( board.Line(p) == 1) // corner or edge { if ( board.Num8Neighbors(p, att) > 0 ) return false; else { number = board.Num8EmptyNeighbors(p); return true; } } else // in center { if ( board.Num8Neighbors(p, att) >= 2 ) return false; else if ( board.NumNeighbors(p, att) > 0 ) return false; else // only 0 or 1 attacker point and not in NB4 { number = board.Num8EmptyNeighbors(p); return true; } } }
bool GoEyeUtil::IsVitalPt(const SgPointSet& points, SgPoint p, SgBlackWhite opp, const GoBoard& bd) { // in corridors a vital point has 2 nbs, in big ones it may have 3 or 4. // but: 2 in following // example: unsettled nakade, non-flat points are all occupied by opp. // .a a is vital Point. // o. // . int numNb = bd.NumEmptyNeighbors(p) + bd.NumNeighbors(p, opp); if (numNb >= 2) { if (numNb >= 4) /* */ return true; /* */ int nu = IsTreeShape(points) ? 2 : 3; if (numNb >= nu) { if (numNb == 2 && bd.IsEmpty(p)) return IsSplitPt(p, points); else return true; } } return false; }
bool GoEyeUtil::IsPossibleEye(const GoBoard& board, SgBlackWhite color, SgPoint p) { bool isPossibleEye = false; SG_ASSERT(board.GetColor(p) != color); const SgBlackWhite opp = SgOppBW(color); if (board.Line(p) == 1) // corner or edge { const int nuOwn = (board.Pos(p) == 1) ? 2 : 4; if ( board.Num8Neighbors(p, color) == nuOwn && board.Num8EmptyNeighbors(p) == 1 ) { isPossibleEye = true; } } else // in center { // have all neighbors, and 2 diagonals, and can get a third if ( board.NumNeighbors(p, color) == 4 && board.NumDiagonals(p, color) == 2 && board.NumEmptyDiagonals(p) > 0 ) { isPossibleEye = true; } // have 3 of 4 neighbors, can get the 4th, and have enough diagonals else if ( board.NumNeighbors(p, color) == 3 && board.NumNeighbors(p, opp) == 0 && board.NumDiagonals(p, color) >= 3 ) { isPossibleEye = true; } } return isPossibleEye; }