static bool GivenGroupLives()

in go/board.cc [911:976]


static bool GivenGroupLives(const Board *board, short group_idx) {
  const Group *g = &board->_groups[group_idx];
  // At least two liberties.
  if (g->liberties == 1) return false;

  // Case 1: Two true eyes.
  Coord eyes[BOARD_SIZE * BOARD_SIZE];
  int eye_count = 0;

  TRAVERSE(board, group_idx, c) {
    FOR4(c, _, cc) {
      if (IsTrueEye(board, cc, g->color)) {
        // Candidate true eyes. Need to double check whether they combined can live.
        bool dup = false;
        for (int i = 0; i < eye_count; ++i) {
          if (eyes[i] == cc) {
            dup = true;
            break;
          }
        }
        if (!dup) eyes[eye_count ++] = cc;
      }
    } ENDFOR4
  } ENDTRAVERSE

  if (eye_count <= 1) return false;

  // Check if there exists at least two eyes, so that each eye is:
  // 1. If at the boundary, surrounded by either other candidate true eye, or self stones.
  // 2. If at the center, surrounded by either other candidate true eye, or self stones and at most one enemy stone.
  int true_eye_count = 0;
  // Coord true_eyes[2];
  for (int i = 0; i < eye_count; ++i) {
    int off_board_count = 0;
    int territory_count = 0;

    FORDIAG4(eyes[i], _, cc) {
      Stone s = board->_infos[cc].color;
      if (s == S_OFF_BOARD) {
        off_board_count ++;
      }
      else if (s == S_EMPTY) {
        for (int j = 0; j < eye_count; j ++) {
          if (eyes[j] == cc) {
            territory_count ++;
            break;
          }
        }
      } else if (s == g->color) {
        territory_count ++;
      }
    } ENDFORDIAG4
    if (   (off_board_count >= 1 && off_board_count + territory_count == 4)
        || (off_board_count == 0 && off_board_count + territory_count >= 3)) {
      // true_eyes[true_eye_count ++] = eyes[i];
      true_eye_count ++;
    }
    if (true_eye_count >= 2) {
      // char buf1[100], buf2[100];
      // printf("True Eyes: %s, %s\n", get_move_str(true_eyes[0], S_EMPTY, buf1), get_move_str(true_eyes[1], S_EMPTY, buf2));
      break;
    }
  }

  return true_eye_count >= 2 ? true : false;
}