void decide_eye(int pos) { int color; struct eyevalue value; int attack_point; int defense_point; int eyepos; SGFTree tree; reset_engine(); silent_examine_position(BLACK, EXAMINE_DRAGONS_WITHOUT_OWL); if (black_eye[pos].color == BLACK_BORDER) color = BLACK; else if (white_eye[pos].color == WHITE_BORDER) color = WHITE; else { gprintf("The eye at %1m is not of a single color.\n", pos); return; } if (printboard) showboard(0); /* Enable sgf output. */ if (*outfilename) sgffile_begindump(&tree); count_variations = 1; if (black_eye[pos].color == BLACK_BORDER) { eyepos = black_eye[pos].origin; compute_eyes(eyepos, &value, &attack_point, &defense_point, black_eye, half_eye, 0, EMPTY); gprintf("Black eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value)); if (eye_move_urgency(&value) > 0) { gprintf(" vital points: %1m (attack) %1m (defense)\n", attack_point, defense_point); } } if (white_eye[pos].color == WHITE_BORDER) { eyepos = white_eye[pos].origin; compute_eyes(eyepos, &value, &attack_point, &defense_point, white_eye, half_eye, 0, EMPTY); gprintf("White eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value)); if (eye_move_urgency(&value) > 0) { gprintf(" vital points: %1m (attack) %1m (defense)\n", attack_point, defense_point); } } /* Finish sgf output. */ sgffile_enddump(outfilename); count_variations = 0; }
void decide_dragon_data(int pos) { if (board[pos] == EMPTY) { fprintf(stderr, "gnugo: --decide-dragon-data called on an empty vertex\n"); return ; } reset_engine(); silent_examine_position(board[pos], FULL_EXAMINE_DRAGONS); gprintf("Dragon at %1m:\n", pos); report_dragon(stderr, pos); }
void decide_semeai(int apos, int bpos) { SGFTree tree; int resulta, resultb, move, result_certain; int color = board[apos]; if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) { gprintf("gnugo: --decide-semeai called on invalid data\n"); return; } /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL); gprintf("finished examine_position\n"); count_variations = 1; if (*outfilename) sgffile_begindump(&tree); gprintf("Analyzing semeai between %1m and %1m, %C moves first\n", apos, bpos, board[apos]); owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, &result_certain); gprintf("Semeai defense of %1m: result %s %1m\n", apos, result_to_string(resulta), move); gprintf("Semeai attack of %1m: result %s %1m\n", bpos, result_to_string(resultb), move); gprintf("%d nodes%s\n\n", count_variations, result_certain ? "" : ", uncertain result"); gprintf("Analyzing semeai between %1m and %1m, %C moves first\n", bpos, apos, board[bpos]); owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, &result_certain); gprintf("Semeai defense of %1m: result %s %1m\n", bpos, result_to_string(resultb), move); gprintf("Semeai attack of %1m: result %s %1m\n", apos, result_to_string(resulta), move); gprintf("%d nodes%s\n", count_variations, result_certain ? "" : ", uncertain result"); sgffile_enddump(outfilename); count_variations = 0; }
void decide_tactical_semeai(int apos, int bpos) { SGFTree tree; int resulta, resultb, move; int color = board[apos]; if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) { gprintf("gnugo: --decide-semeai called on invalid data\n"); return; } /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(board[apos], EXAMINE_DRAGONS_WITHOUT_OWL); gprintf("finished examine_position\n"); count_variations = 1; /* We want to see the reading performed, not just a result picked * from the cache. Thus we clear the cache here. */ reading_cache_clear(); if (*outfilename) sgffile_begindump(&tree); owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, 0); gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n", color == BLACK ? "black" : "white", move, apos, safety_to_string(resulta), bpos, safety_to_string(resultb), count_variations); owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, 0); gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n", color == BLACK ? "white" : "black", move, apos, safety_to_string(resulta), bpos, safety_to_string(resultb), count_variations); sgffile_enddump(outfilename); count_variations = 0; }
void decide_surrounded(int pos) { int surround_status; if (board[pos] == EMPTY) { fprintf(stderr, "location must not be empty!\n"); return; } /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(board[pos], EXAMINE_ALL); surround_status = compute_surroundings(pos, NO_MOVE, 1, NULL); if (surround_status == 1) gprintf("the dragon at %1m is SURROUNDED!\n", pos); else if (surround_status == 2) gprintf("the dragon at %1m is WEAKLY SURROUNDED!\n", pos); else gprintf("the dragon at %1m is not surrounded.\n", pos); }
void decide_combination(int color) { int attack_move; char defense_moves[BOARDMAX]; SGFTree tree; int first = 1; int pos; /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(color, EXAMINE_ALL); if (*outfilename) sgffile_begindump(&tree); count_variations = 1; if (atari_atari(color, &attack_move, defense_moves, verbose)) { gprintf("Combination attack for %C at %1m, defense at ", color, attack_move); for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (ON_BOARD(pos) && defense_moves[pos]) { if (first) first = 0; else gprintf(", "); gprintf("%1m", pos); } } gprintf("\n"); } else gprintf("No Combination attack for %C\n", color); sgffile_enddump(outfilename); count_variations = 0; }
void decide_position(int color) { int pos; int move = NO_MOVE; int acode = 0, dcode = 0; int kworm; static const char *snames[] = {"dead", "alive", "critical", "unknown"}; SGFTree tree; /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(color, EXAMINE_DRAGONS_WITHOUT_OWL); /* We want to see the reading performed, not just a result picked * from the cache. Thus we clear the cache here. */ reading_cache_clear(); if (*outfilename) sgffile_begindump(&tree); count_variations = 1; for (pos = BOARDMIN; pos < BOARDMAX; pos++) { if (!ON_BOARD(pos) || dragon[pos].origin != pos || board[pos] == EMPTY || DRAGON2(pos).escape_route >= 6) continue; gprintf("\nanalyzing %1m\n", pos); gprintf("status=%s, escape=%d\n", snames[dragon[pos].crude_status], DRAGON2(pos).escape_route); acode = owl_attack(pos, &move, NULL, &kworm); if (acode) { if (acode == WIN) { if (move == NO_MOVE) gprintf("%1m is dead as it stands\n", pos); else gprintf("%1m can be attacked at %1m (%d variations)\n", pos, move, count_variations); } else if (acode == KO_A) gprintf("%1m can be attacked with ko (good) at %1m (%d variations)\n", pos, move, count_variations); else if (acode == KO_B) gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)\n", pos, move, count_variations); else if (acode == GAIN) gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", pos, kworm, move, count_variations); count_variations = 1; dcode = owl_defend(pos, &move, NULL, &kworm); if (dcode) { if (dcode == WIN) { if (move == NO_MOVE) gprintf("%1m is alive as it stands\n", pos); else gprintf("%1m can be defended at %1m (%d variations)\n", pos, move, count_variations); } else if (dcode == KO_A) gprintf("%1m can be defended with ko (good) at %1m (%d variations)\n", pos, move, count_variations); else if (dcode == KO_B) gprintf("%1m can be defended with ko (bad) at %1m (%d variations)\n", pos, move, count_variations); else if (dcode == LOSS) gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", pos, kworm, move, count_variations); } else gprintf("%1m cannot be defended (%d variations)\n", pos, count_variations); } else gprintf("%1m cannot be attacked (%d variations)\n", pos, count_variations); if (acode) { if (dcode) gprintf("status of %1m revised to CRITICAL\n", pos); else gprintf("status of %1m revised to DEAD\n", pos); } else gprintf("status of %1m revised to ALIVE\n", pos); } sgffile_enddump(outfilename); count_variations = 0; }
void decide_owl(int pos) { int move = NO_MOVE; int acode, dcode; SGFTree tree; int result_certain; int kworm; if (board[pos] == EMPTY) { fprintf(stderr, "gnugo: --decide-dragon called on an empty vertex\n"); return ; } /* Prepare pattern matcher and reading code. */ reset_engine(); silent_examine_position(board[pos], EXAMINE_DRAGONS_WITHOUT_OWL); gprintf("finished examine_position\n"); /* We want to see the reading performed, not just a result picked * from the cache. Thus we clear the cache here. */ reading_cache_clear(); if (*outfilename) sgffile_begindump(&tree); count_variations = 1; acode = owl_attack(pos, &move, &result_certain, &kworm); if (acode) { if (acode == WIN) { if (move == NO_MOVE) gprintf("%1m is dead as it stands", pos); else gprintf("%1m can be attacked at %1m (%d variations)", pos, move, count_variations); } else if (acode == KO_A) gprintf("%1m can be attacked with ko (good) at %1m (%d variations)", pos, move, count_variations); else if (acode == KO_B) gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)", pos, move, count_variations); else if (acode == GAIN) gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", pos, kworm, move, count_variations); } else gprintf("%1m cannot be attacked (%d variations)", pos, count_variations); if (result_certain) gprintf("\n"); else gprintf(" result uncertain\n"); reading_cache_clear(); count_variations = 1; dcode = owl_defend(pos, &move, &result_certain, &kworm); if (dcode) { if (dcode == WIN) { if (move == NO_MOVE) gprintf("%1m is alive as it stands", pos); else gprintf("%1m can be defended at %1m (%d variations)", pos, move, count_variations); } else if (dcode == KO_A) gprintf("%1m can be defended with ko (good) at %1m (%d variations)", pos, move, count_variations); else if (dcode == KO_B) gprintf("%1m can be defended with ko (bad) at %1m (%d variations)", pos, move, count_variations); else if (dcode == LOSS) gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", pos, kworm, move, count_variations); } else gprintf("%1m cannot be defended (%d variations)", pos, count_variations); if (result_certain) gprintf("\n"); else gprintf(" result uncertain\n"); sgffile_enddump(outfilename); count_variations = 0; }
void do_play_ascii(Gameinfo *gameinfo) { int m, num; float fnum; int passes = 0; /* two passes and its over */ int tmp; char line[80]; char *line_ptr = line; char *command; char *tmpstring; int state = 1; if (have_time_settings()) clock_on = 1; while (state == 1) { state = 0; /* No score is estimated yet. */ current_score_estimate = NO_SCORE; /* Allow resignation at interface level (the engine may still be not * allowed to resign. */ resignation_allowed = 1; printf("\nBeginning ASCII mode game.\n\n"); gameinfo_print(gameinfo); /* Does the computer play first? If so, make a move. */ if (gameinfo->computer_player == gameinfo->to_move) state = computer_move(gameinfo, &passes); /* main ASCII Play loop */ while (state == 0) { /* Display game board. */ if (opt_showboard) ascii_showboard(); #if !READLINE /* Print the prompt */ mprintf("%s(%d): ", color_to_string(gameinfo->to_move), movenum + 1); /* Read a line of input. */ line_ptr = line; if (!fgets(line, 80, stdin)) return; #else snprintf(line, 79, "%s(%d): ", color_to_string(gameinfo->to_move), movenum + 1); if (!(line_ptr = readline(line))) return; add_history(line_ptr); #endif while (state == 0 && (command = strtok(line_ptr, ";"), line_ptr = 0, command)) { /* Get the command or move. */ switch (get_command(command)) { case RESIGN: state = ascii_endgame(gameinfo, 1); break; case END: case EXIT: case QUIT: return; case HELP: show_commands(); break; case CMD_HELPDEBUG: printf(DEBUG_COMMANDS); break; case SHOWBOARD: opt_showboard = !opt_showboard; break; case INFO: printf("\n"); gameinfo_print(gameinfo); break; case SETBOARDSIZE: if (sgf_initialized) { printf("Boardsize cannot be changed after record is started!\n"); break; } command += 10; if (sscanf(command, "%d", &num) != 1) { printf("\nInvalid command syntax!\n"); break; } if (!check_boardsize(num, stdout)) break; /* Init board. */ board_size = num; clear_board(); /* In case max handicap changes on smaller board. */ gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); sgfOverwritePropertyInt(sgftree.root, "SZ", board_size); sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); break; case SETHANDICAP: if (sgf_initialized) { printf("Handicap cannot be changed after game is started!\n"); break; } command += 9; if (sscanf(command, "%d", &num) != 1) { printf("\nInvalid command syntax!\n"); break; } if (num < 0 || num > MAX_HANDICAP) { printf("\nInvalid handicap: %d\n", num); break; } /* Init board. */ clear_board(); /* Place stones on board but don't record sgf * in case we change more info. */ gameinfo->handicap = place_fixed_handicap(num); printf("\nSet handicap to %d\n", gameinfo->handicap); gameinfo->to_move = (gameinfo->handicap ? WHITE : BLACK); break; case FREEHANDICAP: if (sgf_initialized) { printf("Handicap cannot be changed after game is started!\n"); break; } while (*command && *command != ' ') command++; ascii_free_handicap(gameinfo, command); break; case SETKOMI: if (sgf_initialized) { printf("Komi cannot be modified after game record is started!\n"); break; } command += 5; if (sscanf(command, "%f", &fnum) != 1) { printf("\nInvalid command syntax!\n"); break; } komi = fnum; printf("\nSet Komi to %.1f\n", komi); break; case SETDEPTH: command += 6; if (sscanf(command, "%d", &num) != 1) { printf("\nInvalid command syntax!\n"); break; } mandated_depth = num; printf("\nSet depth to %d\n", mandated_depth); break; case SETLEVEL: command += 6; if (sscanf(command, "%d", &num) != 1) { printf("\nInvalid command syntax!\n"); break; } set_level(num); printf("\nSet level to %d\n", num); break; case DISPLAY: if (!opt_showboard) ascii_showboard(); break; case FORCE: command += 6; /* skip the force part... */ switch (get_command(command)) { case MOVE: state = do_move(gameinfo, command, &passes, 1); break; case PASS: state = do_pass(gameinfo, &passes, 1); break; default: printf("Illegal forced move: %s %d\n", command, get_command(command)); break; } break; case MOVE: state = do_move(gameinfo, command, &passes, 0); break; case PASS: state = do_pass(gameinfo, &passes, 0); break; case PLAY: command += 5; if (sscanf(command, "%d", &num) != 1) { printf("\nInvalid command syntax!\n"); break; } if (num >= 0) for (m = 0; m < num; m++) { gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); state = computer_move(gameinfo, &passes); if (state) break; if (passes >= 2) break; } else { printf("\nInvalid number of moves specified: %d\n", num); break; } break; case PLAYBLACK: if (gameinfo->computer_player == WHITE) gameinfo->computer_player = BLACK; if (gameinfo->computer_player == gameinfo->to_move) state = computer_move(gameinfo, &passes); break; case PLAYWHITE: if (gameinfo->computer_player == BLACK) gameinfo->computer_player = WHITE; if (gameinfo->computer_player == gameinfo->to_move) state = computer_move(gameinfo, &passes); break; case SWITCH: gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player); state = computer_move(gameinfo, &passes); break; case UNDO: case CMD_BACK: if (undo_move(1)) { sgftreeAddComment(&sgftree, "undone"); sgftreeBack(&sgftree); gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); } else printf("\nCan't undo.\n"); break; case CMD_FORWARD: if (sgftreeForward(&sgftree)) gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, gameinfo->to_move); else printf("\nEnd of game tree.\n"); break; case CMD_LAST: while (sgftreeForward(&sgftree)) gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, gameinfo->to_move); break; case COMMENT: printf("\nEnter comment. Press ENTER when ready.\n"); fgets(line, 80, stdin); sgftreeAddComment(&sgftree, line); break; case SCORE: showscore = !showscore; if (!showscore) current_score_estimate = NO_SCORE; break; case CMD_DEAD: silent_examine_position(FULL_EXAMINE_DRAGONS); showdead = !showdead; break; case CMD_CAPTURE: strtok(command, " "); showcapture(strtok(NULL, " ")); break; case CMD_DEFEND: strtok(command, " "); showdefense(strtok(NULL, " ")); break; case CMD_SHOWMOYO: tmp = printmoyo; printmoyo = PRINTMOYO_MOYO; silent_examine_position(EXAMINE_DRAGONS); printmoyo = tmp; break; case CMD_SHOWTERRI: tmp = printmoyo; printmoyo = PRINTMOYO_TERRITORY; silent_examine_position(EXAMINE_DRAGONS); printmoyo = tmp; break; case CMD_SHOWAREA: tmp = printmoyo; printmoyo = PRINTMOYO_AREA; silent_examine_position(EXAMINE_DRAGONS); printmoyo = tmp; break; case CMD_SHOWDRAGONS: silent_examine_position(EXAMINE_DRAGONS); showboard(1); break; case CMD_GOTO: strtok(command, " "); ascii_goto(gameinfo, strtok(NULL, " ")); break; case CMD_SAVE: strtok(command, " "); tmpstring = strtok(NULL, " "); if (tmpstring) { /* discard newline */ tmpstring[strlen(tmpstring) - 1] = 0; /* make sure we are saving proper handicap */ init_sgf(gameinfo); writesgf(sgftree.root, tmpstring); printf("You may resume the game"); printf(" with -l %s --mode ascii\n", tmpstring); printf("or load %s\n", tmpstring); } else printf("Please specify filename\n"); break; case CMD_LOAD: strtok(command, " "); tmpstring = strtok(NULL, " "); if (tmpstring) { /* discard newline */ tmpstring[strlen(tmpstring) - 1] = 0; if (!sgftree_readfile(&sgftree, tmpstring)) { fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring); break; } /* to avoid changing handicap etc. */ if (gameinfo_play_sgftree(gameinfo, &sgftree, NULL) == EMPTY) fprintf(stderr, "Cannot load '%s'\n", tmpstring); else { sgf_initialized = 1; sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap); } } else printf("Please specify a filename\n"); break; case CMD_LISTDRAGONS: silent_examine_position(EXAMINE_DRAGONS); show_dragons(); break; default: printf("\nInvalid command: %s", command); break; } if (passes >= 2) state = ascii_endgame(gameinfo, 0); } #if READLINE free(line_ptr); #endif } sgffile_output(&sgftree); passes = 0; /* Play a different game next time. */ update_random_seed(); /* Free the sgf tree and prepare for a new game. */ sgfFreeNode(sgftree.root); sgftree_clear(&sgftree); sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap); sgf_initialized = 0; gameinfo_clear(gameinfo); } }