www.delorie.com/gnu/docs/gnugo/gnugo_146.html   search  
 
Buy GNU books!


GNU Go Documentation

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.4 Helper Functions

Helper functions can be provided to assist the matcher in deciding whether to accept a pattern, register move reasons, and setting various move values. The helper is supplied with the compiled pattern entry in the table, and the (absolute) position on the board of the `*' point.

One difficulty is that the helper must be able to cope with all the possible transformations of the pattern. To help with this, the OFFSET macro is used to transform relative pattern coordinates to absolute board locations.

The actual helper functions are in `helpers.c'. They are declared in `patterns.h'.

As an example to show how to write a helper function, we consider a hypothetical helper called wedge_helper. Such a helper used to exist, but has been replaced by a constraint. Due to its simplicity it's still a good example. The helper begins with a comment:

 
/*

?O.           ?Ob
.X*           aX*
?O.           ?Oc

:8,C,wedge_helper
*/

The image on the left is the actual pattern. On the right we've taken this image and added letters to label apos, bpos, and cpos. The position of *, the point where GNU Go will move if the pattern is adopted, is passed through the parameter move.

 
int 
wedge_helper(ARGS)
{
  int apos, bpos, cpos;
  int other = OTHER_COLOR(color);
  int success = 0;
  
  apos = OFFSET(0, -2);
  bpos = OFFSET(-1, 0);
  cpos = OFFSET(1, 0);

  if (TRYMOVE(move, color)) {
    if (TRYMOVE(apos, other)) {
      if (board[apos] == EMPTY || attack(apos, NULL))
        success = 1;
      else if (TRYMOVE(bpos, color)) {
        if (!safe_move(cpos, other))
          success = 1;
        popgo();
      }
      popgo();
    }
    popgo();
  }
  
  return success;
}

The OFFSET lines tell GNU Go the positions of the three stones at `a', `b', and `c'. To decide whether the pattern guarantees a connection, we do some reading. First we use the TRYMOVE macro to place an `O' at `move' and let `X' draw back to `a'. Then we ask whether `O' can capture these stones by calling attack(). The test if there is a stone at `a' before calling attack() is in this position not really necessary but it's good practice to do so, because if the attacked stone should happen to already have been captured while placing stones, GNU Go would crash with an assertion failure.

If this attack fails we let `O' connect at `b' and use the safe_move() function to examine whether a cut by `X' at `c' could be immediately captured. Before we return the result we need to remove the stones we placed from the reading stack. This is done with the function popgo().


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003