/* * This function works like printf, except that it only understands * very few of the standard formats, to be precise %c, %d, %f, %s. * But it also accepts %m, which takes two integers and writes a vertex, * and %C, which takes a color value and writes a color string. */ void gtp_mprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); 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, stdout); break; } case 'd': { int d = va_arg(ap, int); fprintf(stdout, "%d", d); break; } case 'f': { double f = va_arg(ap, double); /* passed as double, not float */ fprintf(stdout, "%f", f); break; } case 's': { char *s = va_arg(ap, char*); fputs(s, stdout); break; } case 'm': { int m = va_arg(ap, int); int n = va_arg(ap, int); gtp_print_vertex(m, n); break; } case 'C': { int color = va_arg(ap, int); if (color == WHITE) fputs("white", stdout); else if (color == BLACK) fputs("black", stdout); else fputs("empty", stdout); break; } default: fprintf(stdout, "\n\nUnknown format character '%c'\n", *fmt); break; } } else putc(*fmt, stdout); }
/* Function: Generate and play the supposedly best move for either color. * Arguments: color to move * Fails: invalid color * Returns: a move coordinate or "PASS" (or "resign" if resignation_allowed) * * Status: GTP version 2 standard command. */ static int gtp_genmove(char *s) { DataGo move; Player color; if (!gtp_decode_color(s, &color)) return gtp_failure("invalid color"); move = game->gen_move(color); if (IS_RESIGN(move)) return gtp_success("resign"); assert(game->play_move(move)); gtp_start_response(GTP_SUCCESS); if (IS_PASS(move)) gtp_print_vertex(-1, -1); else gtp_print_vertex(move.i, move.j); return gtp_finish_response(); }