Ticket #196: gunnar_7_12.4b.diff

File gunnar_7_12.4b.diff, 5.0 kB (added by gunnar, 13 months ago)

Second attempt.

  • engine/utils.c

     
    14071407} 
    14081408     
    14091409 
    1410 /* Returns true if a move by (color) fits a shape like: 
    1411  * 
    1412  *  ----- 
    1413  *  O.O*X        (O=color) 
    1414  *  OOXXX 
    1415  * 
    1416  * More specifically the move should have the following properties: 
    1417  * - The move is a self-atari 
    1418  * - The move forms a string of exactly two stones 
    1419  * - When the opponent captures, the capturing stone becomes a single 
    1420  *   stone in atari 
    1421  * - When capturing back the original position is repeated 
    1422  */ 
    1423  
    1424 int 
    1425 send_two_return_one(int move, int color) 
    1426 { 
    1427   int other = OTHER_COLOR(color); 
    1428   int lib1; 
    1429   int lib2; 
    1430  
    1431   /* Try to play the move. */ 
    1432   if (!trymove(move, color, "send_two_return_one-A", NO_MOVE)) 
    1433     return 0; 
    1434  
    1435   /* Does the move leave exactly two stones in atari? */ 
    1436   if (findlib(move, 1, &lib1) > 1 || countstones(move) != 2) { 
    1437     popgo(); 
    1438     return 0; 
    1439   } 
    1440  
    1441   /* Let the opponent capture. This move is guaranteed to be legal. */ 
    1442   trymove(lib1, other, "send_two_return_one-A", NO_MOVE); 
    1443  
    1444   /* Is the capturing string single and in atari? */ 
    1445   if (findlib(lib1, 1, &lib2) > 1 || countstones(lib1) > 1) { 
    1446     popgo(); 
    1447     popgo(); 
    1448     return 0; 
    1449   } 
    1450  
    1451   popgo(); 
    1452   popgo(); 
    1453  
    1454   /* The move to capture back is in lib2. This must be one of the two 
    1455    * captured stones, either the move or the adjacent stone. If it is 
    1456    * the same as the first move, the previous position is not repeated 
    1457    * by capturing back, so we return false. 
    1458    */ 
    1459   if (lib2 == move) 
    1460     return 0; 
    1461  
    1462   /* The move matches the shape. */ 
    1463   return 1; 
    1464 } 
    1465  
    1466  
    14671410/* Returns true if a move by (color) plays into a snapback. */ 
    14681411int 
    14691412playing_into_snapback(int move, int color) 
  • engine/liberty.h

     
    545545int does_defend(int move, int str); 
    546546int double_atari(int move, int color, float *value, 
    547547                 signed char safe_stones[BOARDMAX]); 
    548 int send_two_return_one(int move, int color); 
    549548int playing_into_snapback(int move, int color); 
    550549int play_attack_defend_n(int color, int do_attack, int num_moves, ...); 
    551550int play_attack_defend2_n(int color, int do_attack, int num_moves, ...); 
  • engine/value_moves.c

     
    161161  increase_depth_values(); 
    162162   
    163163  for (ii = BOARDMIN; ii < BOARDMAX; ii++) { 
    164     if (!ON_BOARD(ii)) 
     164    if (board[ii] != EMPTY) 
    165165      continue; 
    166166 
    167167    /* Don't consider send-two-return-one moves here. */ 
  • engine/board.c

     
    27282728} 
    27292729 
    27302730 
     2731/* Returns true if a move by (color) fits a shape like: 
     2732 * 
     2733 *  ----- 
     2734 *  O.O*X        (O=color) 
     2735 *  OOXXX 
     2736 * 
     2737 * More specifically the move should have the following properties: 
     2738 * - The move is a self-atari 
     2739 * - The move forms a string of exactly two stones 
     2740 * - When the opponent captures, the capturing stone becomes a single 
     2741 *   stone in atari 
     2742 * - When capturing back the original position is repeated 
     2743 */ 
     2744 
     2745int 
     2746send_two_return_one(int move, int color) 
     2747{ 
     2748  int other = OTHER_COLOR(color); 
     2749  int lib = NO_MOVE; 
     2750  int friendly_neighbor = NO_MOVE; 
     2751  int k; 
     2752   
     2753  ASSERT1(board[move] == EMPTY, move); 
     2754 
     2755  for (k = 0; k < 4; k++) { 
     2756    int pos = move + delta[k]; 
     2757    if (board[pos] == EMPTY) 
     2758      return 0; 
     2759    if (board[pos] == color) { 
     2760      int s; 
     2761      if (friendly_neighbor != NO_MOVE) 
     2762        return 0; 
     2763      friendly_neighbor = pos; 
     2764      s = string_number[pos]; 
     2765      if (string[s].size != 1 || string[s].liberties != 2) 
     2766        return 0; 
     2767      lib = string_libs[s].list[0] + string_libs[s].list[1] - move; 
     2768    } 
     2769    else if (board[pos] == other 
     2770             && string[string_number[pos]].liberties == 1) 
     2771      return 0; 
     2772  } 
     2773   
     2774  if (friendly_neighbor == NO_MOVE) 
     2775    return 0; 
     2776 
     2777  for (k = 0; k < 4; k++) { 
     2778    int pos = lib + delta[k]; 
     2779    if (board[pos] == EMPTY || board[pos] == other) 
     2780      return 0; 
     2781    if (board[pos] == color && 
     2782        string[string_number[pos]].liberties < 2) 
     2783      return 0; 
     2784  } 
     2785   
     2786  return 1; 
     2787} 
     2788 
     2789 
    27312790/* 
    27322791 * Find the origin of a worm, i.e. the point with the 
    27332792 * smallest 1D board coordinate. The idea is to have a canonical 
  • engine/board.h

     
    345345int findstones(int str, int maxstones, int *stones); 
    346346int count_adjacent_stones(int str1, int str2, int maxstones); 
    347347 
     348/* Detect a special shape. */ 
     349int send_two_return_one(int move, int color); 
     350 
    348351/* Special function for reading.c */ 
    349352void incremental_order_moves(int move, int color, int string, 
    350353                             int *number_edges, int *number_same_string,