Пример #1
0
void 
vgprintf(FILE *outputfile, const char *fmt, va_list ap)
{
  if (fmt[0] == '%' && fmt[1] == 'o')
    fmt += 2;  /* cancel indent */
  else if (stackp > 0)
    fprintf(outputfile, "%.*s", stackp*2, "                                ");

  for (; *fmt; ++fmt) {
    if (*fmt == '%') {
      switch (*++fmt) {
      case 'c':
      {
	/* rules of promotion => passed as int, not char */
	int c = va_arg(ap, int);
	putc(c, outputfile);
	break;
      }
      case 'd':
      {
	int d = va_arg(ap, int);
	fprintf(outputfile, "%d", d);
	break;
      }
      case 'x':
      {
	unsigned int d = va_arg(ap, unsigned int);
	fprintf(outputfile, "%x", d);
	break;
      }
      case 'f':
      {
	double f = va_arg(ap, double); /* passed as double, not float */
	fprintf(outputfile, "%.2f", f);
	break;
      }
      case 's':
      {
	char *s = va_arg(ap, char *);
	fputs(s, outputfile);
	break;
      }
      case '2':
        fmt++;
        if (*fmt != 'm' && *fmt != 'M') {
	  fprintf(outputfile, "\n\nUnknown format string '2%c'\n", *fmt);
	  break;
        }
        /* else fall through - 2 modifier on %m is default. */
      case 'm':
      case 'M':
      {
	char movename[4];
	int m = va_arg(ap, int);
	int n = va_arg(ap, int);
	if (m == -1 && n == -1)
	  fputs("PASS", outputfile);
	else if (!ON_BOARD2(m, n))
	  fprintf(outputfile, "[%d,%d]", m, n);
	else {
	  /* Generate the move name. */
	  if (n < 8)
	    movename[0] = n + 65;
	  else
	    movename[0] = n + 66;
	  if (*fmt == 'm')
	    sprintf(movename+1, "%d", board_size - m);
	  else
	    sprintf(movename+1, "%-2d", board_size - m);
	  fputs(movename, outputfile);
	}
	break;
      }
      case '1':
      fmt++;
      if (*fmt != 'm' && *fmt != 'M') {
	fprintf(outputfile, "\n\nUnknown format string '1%c'\n", *fmt);
	break;
      }
      else {
	char movename[4];
	int pos = va_arg(ap, int);
	int m = I(pos);
	int n = J(pos);
	if (pos == NO_MOVE)
	  fputs("PASS", outputfile);
	else if (!ON_BOARD1(pos))
	  fprintf(outputfile, "[%d]", pos);
	else {
	  /* Generate the move name. */
	  if (n < 8)
	    movename[0] = n + 65;
	  else
	    movename[0] = n + 66;
	  if (*fmt == 'm')
	    sprintf(movename + 1, "%d", board_size - m);
	  else
	    sprintf(movename + 1, "%-2d", board_size - m);
	  fputs(movename, outputfile);
	}
	break;
      }
      case 'H':
      {
	unsigned long h = va_arg(ap, unsigned long);
	fprintf(outputfile, "%lx", h);
	break;
      }
      case 'C':
      {
	int color = va_arg(ap, int);
	fputs(color_to_string(color), outputfile);
	break;
      }
      default:
	fprintf(outputfile, "\n\nUnknown format character '%c'\n", *fmt);
	break;
      }
    }
    else
      putc(*fmt, outputfile);
  }
Пример #2
0
static void compute_active_owl_area(struct persistent_cache_entry *entry,
				    const char goal[BOARDMAX],
				    int goal_color)
{
  int k, r;
  int pos;
  int other = OTHER_COLOR(goal_color);
  signed char active[BOARDMAX];

  /* We let the active area be the goal +
   * distance four expansion through empty intersections and own stones +
   * adjacent opponent strings +
   * liberties and neighbors of adjacent opponent strings with less than
   * five liberties +
   * liberties and neighbors of low liberty neighbors of adjacent opponent
   * strings with less than five liberties.
   */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++)
    if (ON_BOARD(pos))
      active[pos] = (goal[pos] != 0);

  /* Also add critical moves to the active area. */
  if (ON_BOARD1(entry->move))
    active[entry->move] = 1;

  if (ON_BOARD1(entry->move2))
    active[entry->move2] = 1;

  /* Distance four expansion through empty intersections and own stones. */
  for (k = 1; k < 5; k++) {
    for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
      if (!ON_BOARD(pos) || board[pos] == other || active[pos] > 0) 
	continue;
      if ((ON_BOARD(SOUTH(pos)) && active[SOUTH(pos)] == k)
	  || (ON_BOARD(WEST(pos)) && active[WEST(pos)] == k)
	  || (ON_BOARD(NORTH(pos)) && active[NORTH(pos)] == k)
	  || (ON_BOARD(EAST(pos)) && active[EAST(pos)] == k)) {
	if (board[pos] == EMPTY)
	  active[pos] = k + 1;
	else
	  signed_mark_string(pos, active, (signed char) (k + 1));
      }
    }
  }
  
  /* Adjacent opponent strings. */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    if (board[pos] != other || active[pos] != 0) 
      continue;
    for (r = 0; r < 4; r++) {
      int pos2 = pos + delta[r];
      if (ON_BOARD(pos2) && board[pos2] != other && active[pos2] != 0) {
	signed_mark_string(pos, active, 1);
	break;
      }
    }
  }
  
  /* Liberties of adjacent opponent strings with less than five liberties +
   * liberties of low liberty neighbors of adjacent opponent strings
   * with less than five liberties.
   */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    if (board[pos] == other && active[pos] > 0 && countlib(pos) < 5) {
      int libs[4];
      int liberties = findlib(pos, 4, libs);
      int adjs[MAXCHAIN];
      int adj;
      for (r = 0; r < liberties; r++)
	active[libs[r]] = 1;
      
      /* Also add liberties of neighbor strings if these are three
       * or less.
       */
      adj = chainlinks(pos, adjs);
      for (r = 0; r < adj; r++) {
	signed_mark_string(adjs[r], active, -1);
	if (countlib(adjs[r]) <= 3) {
	  int s;
	  int adjs2[MAXCHAIN];
	  int adj2;
	  liberties = findlib(adjs[r], 3, libs);
	  for (s = 0; s < liberties; s++)
	    active[libs[s]] = 1;
	  adj2 = chainlinks(pos, adjs2);
	  for (s = 0; s < adj2; s++)
	    signed_mark_string(adjs2[s], active, -1);
	}
      }
    }
  }
  
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    int value = board[pos];
    if (!ON_BOARD(pos))
      continue;
    if (!active[pos])
      value = GRAY;
    else if (IS_STONE(board[pos]) && countlib(pos) > 4 && active[pos] > 0)
      value |= HIGH_LIBERTY_BIT;
    
    entry->board[pos] = value;
  }
}
Пример #3
0
static void 
showchar(int i, int j, int empty, int xo)
{
  struct dragon_data *d;  /* dragon data at (i, j) */
  struct dragon_data2 *d2;
  int x;
  ASSERT_ON_BOARD2(i, j);
  x = BOARD(i, j);
  d = &(dragon[POS(i, j)]);
  d2 = &(dragon2[d->id]);

  if (x == EMPTY) {
    if (xo != 2)
      fprintf(stderr, " %c", empty);
    else {
      int empty_color;
      char empty_char;
      
      if (black_eye[POS(i, j)].color == BLACK) {
	if (white_eye[POS(i, j)].color == WHITE)
	  empty_color = domain_colors[3];
	else
	  empty_color = domain_colors[1];

	if (black_eye[POS(i, j)].marginal)
	  empty_char = '!';
	else
	  empty_char = 'x';
      }
      else if (white_eye[POS(i, j)].color == WHITE) {
	empty_color = domain_colors[2];
	if (white_eye[POS(i, j)].marginal)
	  empty_char = '!';
	else
	  empty_char = 'o';
      }
      else {
	empty_color = domain_colors[0];
	empty_char = '.';
      }

      write_color_char(empty_color, empty_char);
    }
  }
  else {
    int w;

    if (xo == 0 || ! ON_BOARD1(d->origin)) {
      fprintf(stderr, " %c", BOARD(i, j) == BLACK ? 'X' : 'O');
      return;
    }

    /* Figure out ascii character for this dragon. This is the
     * dragon number allocated to the origin of this worm. */

    w = dragon_num[d->origin];
    if (!w) {
      /* Not yet allocated - allocate next one. */
      /* Count upwards for black, downwards for white to reduce confusion. */
      if (BOARD(i, j) == BLACK)
	w = dragon_num[d->origin] = next_black++;
      else
	w = dragon_num[d->origin] = next_white--; 
    }

    w = w%26 + (BOARD(i, j) == BLACK ? 'A' : 'a');
    
    /* Now draw it. */
    if (xo == 1)
      write_color_char(colors[BOARD(i, j)][d->crude_status], w);
    else if (xo == 2) {
      if (BOARD(i, j) == BLACK)
	write_color_char(domain_colors[1], 'X');
      else
	write_color_char(domain_colors[2], 'O');
    }
    else if (xo == 3)
      write_color_char(colors[BOARD(i, j)][d2->owl_status], w);
    else if (xo == 4)
      write_color_char(colors[BOARD(i, j)][d->status], w);
  }
}
void
store_persistent_owl_cache(int routine, int apos, int bpos, int cpos,
			   int result, int move, int move2, int certain,
			   int tactical_nodes,
			   char goal[BOARDMAX], int goal_color)
{
  char active[BOARDMAX];
  int pos;
  int k;
  int r;
  int other = OTHER_COLOR(goal_color);
  gg_assert(stackp == 0);

  /* If cache is full, first try to purge it. */
  if (persistent_owl_cache_size == MAX_OWL_CACHE_SIZE)
    purge_persistent_owl_cache();

  /* FIXME: Kick out oldest or least expensive entry instead of giving up. */
  if (persistent_owl_cache_size == MAX_OWL_CACHE_SIZE) {
    TRACE_OWL_PERFORMANCE("Persistent owl cache full.\n");
    return;
  }

  persistent_owl_cache[persistent_owl_cache_size].boardsize  	 = board_size;
  persistent_owl_cache[persistent_owl_cache_size].routine    	 = routine;
  persistent_owl_cache[persistent_owl_cache_size].apos	     	 = apos;
  persistent_owl_cache[persistent_owl_cache_size].bpos	     	 = bpos;
  persistent_owl_cache[persistent_owl_cache_size].cpos	     	 = cpos;
  persistent_owl_cache[persistent_owl_cache_size].result     	 = result;
  persistent_owl_cache[persistent_owl_cache_size].result_certain = certain;
  persistent_owl_cache[persistent_owl_cache_size].move	         = move;
  persistent_owl_cache[persistent_owl_cache_size].move2	         = move2;
  persistent_owl_cache[persistent_owl_cache_size].tactical_nodes =
    tactical_nodes;
  persistent_owl_cache[persistent_owl_cache_size].movenum = movenum;
  
  /* Remains to set the board. We let the active area be
   * the goal +
   * distance four expansion through empty intersections and own stones +
   * adjacent opponent strings +
   * liberties of adjacent opponent strings with less than five liberties +
   * liberties of low liberty neighbors of adjacent opponent strings
   * with less than five liberties.
   */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++)
    if (ON_BOARD(pos))
      active[pos] = (goal[pos] != 0);

  /* Also add critical moves to the active area. */
  if (ON_BOARD1(move))
    active[move] = 1;

  if (ON_BOARD1(move2))
    active[move2] = 1;

  /* Distance four expansion through empty intersections and own stones. */
  for (k = 1; k < 5; k++) {
    for (pos = BOARDMIN; pos < BOARDMAX; pos++){
      if (!ON_BOARD(pos) || board[pos] == other || active[pos] != 0) 
	continue;
      if ((ON_BOARD(SOUTH(pos)) && active[SOUTH(pos)] == k)
	  || (ON_BOARD(WEST(pos)) && active[WEST(pos)] == k)
	  || (ON_BOARD(NORTH(pos)) && active[NORTH(pos)] == k)
	  || (ON_BOARD(EAST(pos)) && active[EAST(pos)] == k)) {
	if (board[pos] == EMPTY)
	  active[pos] = k + 1;
	else
	  mark_string(pos, active, (char) (k + 1));
      }
    }
  }
  
  /* Adjacent opponent strings. */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    if (board[pos] != other || active[pos] != 0) 
      continue;
    for (r = 0; r < 4; r++) {
      int pos2 = pos + delta[r];
      if (ON_BOARD(pos2) && board[pos2] != other && active[pos2] != 0) {
	mark_string(pos, active, (char) 1);
	break;
      }
    }
  }
  
  /* Liberties of adjacent opponent strings with less than five liberties +
   * liberties of low liberty neighbors of adjacent opponent strings
   * with less than five liberties.
   */
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    if (board[pos] == other && active[pos] != 0 && countlib(pos) < 5) {
      int libs[4];
      int liberties = findlib(pos, 4, libs);
      int adjs[MAXCHAIN];
      int adj;
      for (r = 0; r < liberties; r++)
	active[libs[r]] = 1;
      
      /* Also add liberties of neighbor strings if these are three
       * or less.
       */
      adj = chainlinks(pos, adjs);
      for (r = 0; r < adj; r++) {
	if (countlib(adjs[r]) <= 3) {
	  int s;
	  liberties = findlib(adjs[r], 3, libs);
	  for (s = 0; s < liberties; s++)
	    active[libs[s]] = 1;
	}
      }
    }
  }
  
  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    int value = board[pos];
    if (!ON_BOARD(pos))
      continue;
    if (!active[pos])
      value = GRAY;
    else if (IS_STONE(board[pos]) && countlib(pos) > 4)
      value |= HIGH_LIBERTY_BIT;
    
    persistent_owl_cache[persistent_owl_cache_size].board[pos] = value;
  }

  if (debug & DEBUG_OWL_PERSISTENT_CACHE) {
    gprintf("%o Stored result in cache (entry %d):\n",
	    persistent_owl_cache_size);
    print_persistent_owl_cache_entry(persistent_owl_cache_size);
  }
  
  persistent_owl_cache_size++;
}