Ticket #199: gunnar_7_13.9.diff

File gunnar_7_13.9.diff, 2.2 KB (added by gunnar, 3 years ago)

Avoid overvaluation of eyespaces which are split by a single stone in atari, plus tuning.

  • engine/optics.c

    diff --git a/engine/optics.c b/engine/optics.c
    index 195fcf1..bd88db9 100644
    a b compute_eyes_pessimistic(int pos, struct eyevalue *value, 
    782782  int effective_eyesize; 
    783783  int bulk_score = 0; 
    784784  signed char chainlinks[BOARDMAX]; 
     785  int contains_inset = 0; 
    785786 
    786787  /* Stones inside eyespace which do not coincide with a false eye or 
    787788   * a halfeye. 
    compute_eyes_pessimistic(int pos, struct eyevalue *value, 
    815816        if (!chainlinks[neighbor]) { 
    816817          bulk_score += 4; 
    817818          mark_string(neighbor, chainlinks, 1); 
     819          /* In a position like this 
     820           * 
     821           * |OOO 
     822           * |X.O 
     823           * |OXO 
     824           * |.OO 
     825           * |.O 
     826           * |OO 
     827           * 
     828           * it would make sense to treat this as a single eyespace 
     829           * but the stone in atari on the edge splits it up in two 
     830           * separate eyespaces which are evaluated as 2222 and 1111 
     831           * respectively. Since they together in fact are 1122 this 
     832           * is way off. The best solution would be to to merge the 
     833           * eyespaces but since support for evaluating such eyespaces 
     834           * is missing we try to workaround it by setting pessimistic 
     835           * min to zero for both detected eyespaces. 
     836           * 
     837           * The code below does the detection of such stones called 
     838           * inset. Modification of pessimistic min is done later in 
     839           * the function. 
     840           */ 
     841          if (countlib(neighbor) == 1 
     842              && attack(neighbor, NULL) != 0) { 
     843            int is_inset = 1; 
     844            int splits_eyespace = 0; 
     845            int m; 
     846 
     847            for (m = 0; m < 4; m++) { 
     848              if (ON_BOARD(neighbor + delta[m])) { 
     849                if (eye[neighbor + delta[m]].color == eye[pos].color) { 
     850                  if (eye[neighbor + delta[m]].origin != pos) 
     851                    splits_eyespace = 1; 
     852                } 
     853                else 
     854                  is_inset = 0; 
     855              } 
     856            } 
     857            contains_inset |= (is_inset & splits_eyespace); 
     858          } 
    818859        } 
    819860      } 
    820861      else if (!ON_BOARD(neighbor)) 
    compute_eyes_pessimistic(int pos, struct eyevalue *value, 
    878919    DEBUG(DEBUG_EYES, "  pessimistic min revised to 1 (interior stones)\n"); 
    879920  } 
    880921 
     922  if (contains_inset) { 
     923    *pessimistic_min = 0; 
     924    DEBUG(DEBUG_EYES, "  pessimistic min revised to 0 (contains inset)\n"); 
     925  } 
     926 
    881927  if (attack_point 
    882928      && *attack_point == NO_MOVE 
    883929      && max_eyes(value) != *pessimistic_min) {