X-Git-Url: http://git.subgeniuskitty.com/sgk-go/.git/blobdiff_plain/de03db18673d71781549c0bb7507b8eacd858c34..c541f89afc3888f3f685e7997f37d43206f4a334:/interface/play_twoplayer.c diff --git a/interface/play_twoplayer.c b/interface/play_twoplayer.c index e809cbf..3008925 100644 --- a/interface/play_twoplayer.c +++ b/interface/play_twoplayer.c @@ -24,10 +24,16 @@ #include "gnugo.h" #include +#include #include #include #include #include +#include +#include +#include + +#define _XOPEN_SOURCE 500 #if READLINE #include @@ -40,16 +46,12 @@ #include "sgftree.h" #define DEBUG_COMMANDS "\ -capture try to capture indicated group\n\ -dead Toggle display of dead stones\n\ -defend try to defend indicated group\n\ -listdragons print dragon info \n\ -showarea display area\n\ -showdragons display dragons\n\ -showmoyo display moyo\n\ -showterri display territory\n\ +No debug commands in two player mode\n\ " +#define MASTER_FIFO_NAME "/tmp/sgkgo-fifo-master" +#define SLAVE_FIFO_NAME "/tmp/sgkgo-fifo-slave" + /* ANSI color codes */ #define RESETCOLOR "\x1B[0m" #define WHITECOLOR "\x1B[41m" @@ -71,13 +73,13 @@ static int clock_on = 0; /* Keep track of the score estimated before the last computer move. */ static int current_score_estimate = NO_SCORE; -static void do_play_twoplayer(Gameinfo* gameinfo); +static void do_play_twoplayer(Gameinfo* gameinfo, int transmit_fifo_fd, int receive_fifo_fd); static int twoplayer_endgame(Gameinfo* gameinfo, int reason); static void twoplayer_count(Gameinfo* gameinfo); -static void showcapture(char* line); -static void showdefense(char* line); -static void twoplayer_goto(Gameinfo* gameinfo, char* line); -static void twoplayer_free_handicap(Gameinfo* gameinfo, char* handicap_string); +//static void showcapture(char* line); +//static void showdefense(char* line); +//static void twoplayer_goto(Gameinfo* gameinfo, char* line); +//static void twoplayer_free_handicap(Gameinfo* gameinfo, char* handicap_string); /* If sgf game info is written can't reset parameters like handicap, etc. */ static int sgf_initialized; @@ -320,36 +322,19 @@ static void show_commands(void) { printf("\nCommands:\n"); - printf(" back Take back your last move\n"); - printf(" boardsize Set boardsize (on move 1 only)\n"); printf(" comment Write a comment to outputfile\n"); printf(" depth Set depth for reading\n"); printf(" display Display game board\n"); printf(" exit Exit GNU Go\n"); - printf(" force Force a move for current color\n"); - printf(" forward Go to next node in game tree\n"); - printf(" goto Go to movenum in game tree\n"); printf(" level Playing level (default = 10)\n"); - printf(" handicap Set fixed handicap (on move 1 only)\n"); - printf(" freehandicap Place free handicap (on move 1 only)\n"); - printf(" Omit to place handicap yourself\n"); printf(" help Display this help menu\n"); printf(" helpdebug Display debug help menu\n"); printf(" info Display program settings\n"); - printf(" komi Set komi (on move 1 only)\n"); - printf(" last Goto last node in game tree\n"); printf(" pass Pass on your move\n"); - printf(" play Play moves\n"); - printf(" playblack Play as Black (switch if White)\n"); - printf(" playwhite Play as White (switch if Black)\n"); printf(" quit Exit GNU Go\n"); - printf(" resign Resign the current game\n"); printf(" save Save the current game\n"); - printf(" load Load a game from file\n"); printf(" score Toggle display of score On/Off\n"); printf(" showboard Toggle display of board On/Off\n"); - printf(" switch Switch the color you are playing\n"); - printf(" undo Take the last move back (same as back)\n"); printf(" A move of the format "); printf("\n"); } @@ -530,34 +515,51 @@ init_sgf(Gameinfo* ginfo) sgffile_recordboard(sgftree.root); } +/* + * Communication with second player. + */ + +static int +twoplayer_recv_move(int fd) +{ + int move; + printf("\nWaiting to receive move from other player...\n"); + if (read(fd, &move, sizeof(move)) != sizeof(int)) { + printf("\n"); + printf(WHITECOLOR " " RESETCOLOR); + printf("\n"); + printf(WHITECOLOR " " RESETCOLOR); + printf("Unrecoverable error. Save game if desired, then quit."); + printf(WHITECOLOR " " RESETCOLOR); + printf("\n"); + printf(WHITECOLOR " " RESETCOLOR); + printf("\n"); + printf("\n"); + move = NO_MOVE; + } + return move; +} + +static void +twoplayer_send_move(int move, int fd) +{ + write(fd, &move, sizeof(move)); +} + /* * Generate the computer move. */ static int -computer_move(Gameinfo* gameinfo, int* passes) +computer_move(Gameinfo* gameinfo, int* passes, int receive_fifo_fd) { int move; - float move_value; - int resign; int resignation_declined = 0; float upper_bound, lower_bound; init_sgf(gameinfo); - /* Generate computer move. */ - if (autolevel_on) - adjust_level_offset(gameinfo->to_move); - move = genmove(gameinfo->to_move, &move_value, &resign); - if (resignation_allowed && resign) { - int state = twoplayer_endgame(gameinfo, 2); - if (state != -1) - return state; - - /* The opponent declined resignation. Remember not to resign again. */ - resignation_allowed = 0; - resignation_declined = 1; - } + move = twoplayer_recv_move(receive_fifo_fd); if (showscore) { gnugo_estimate_score(&upper_bound, &lower_bound); @@ -572,7 +574,6 @@ computer_move(Gameinfo* gameinfo, int* passes) *passes = 0; gnugo_play_move(move, gameinfo->to_move); - sgffile_add_debuginfo(sgftree.lastnode, move_value); sgftreeAddPlay(&sgftree, gameinfo->to_move, I(move), J(move)); if (resignation_declined) sgftreeAddComment(&sgftree, "GNU Go resignation was declined"); @@ -587,7 +588,8 @@ computer_move(Gameinfo* gameinfo, int* passes) */ static int -do_move(Gameinfo* gameinfo, char* command, int* passes, int force) +do_move(Gameinfo* gameinfo, char* command, int* passes, int force, + int transmit_fifo_fd, int receive_fifo_fd) { int move = string_to_location(board_size, command); @@ -601,6 +603,8 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force) return 0; } + twoplayer_send_move(move,transmit_fifo_fd); + *passes = 0; TRACE("\nyour move: %1m\n\n", move); init_sgf(gameinfo); @@ -611,7 +615,6 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force) if (opt_showboard) { twoplayer_showboard(); - printf("GNU Go is thinking...\n"); } if (force) { @@ -622,7 +625,7 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force) } gameinfo->to_move = OTHER_COLOR(gameinfo->to_move); - return computer_move(gameinfo, passes); + return computer_move(gameinfo, passes, receive_fifo_fd); } /* @@ -630,8 +633,11 @@ do_move(Gameinfo* gameinfo, char* command, int* passes, int force) */ static int -do_pass(Gameinfo* gameinfo, int* passes, int force) +do_pass(Gameinfo* gameinfo, int* passes, int force, + int transmit_fifo_fd, int receive_fifo_fd) { + twoplayer_send_move(NO_MOVE,transmit_fifo_fd); + (*passes)++; init_sgf(gameinfo); gnugo_play_move(PASS_MOVE, gameinfo->to_move); @@ -646,7 +652,7 @@ do_pass(Gameinfo* gameinfo, int* passes, int force) return 0; } - return computer_move(gameinfo, passes); + return computer_move(gameinfo, passes, receive_fifo_fd); } /* @@ -657,6 +663,27 @@ void play_twoplayer(SGFTree* tree, Gameinfo* gameinfo, char* filename, char* unt { int sz; + int transmit_fifo_fd, receive_fifo_fd; + if (mknod(MASTER_FIFO_NAME, S_IFIFO | 0666, 0) == 0) { + gameinfo->computer_player = WHITE; // We are black, so our opponent is white. + printf("Waiting for other player to connect.\n"); + transmit_fifo_fd = open(MASTER_FIFO_NAME, O_WRONLY); + receive_fifo_fd = open(SLAVE_FIFO_NAME, O_RDONLY); + } else { + gameinfo->computer_player = BLACK; // We are white, so our opponent is black. + if (mknod(SLAVE_FIFO_NAME, S_IFIFO | 0666, 0) == 0) { + receive_fifo_fd = open(MASTER_FIFO_NAME, O_RDONLY); + transmit_fifo_fd = open(SLAVE_FIFO_NAME, O_WRONLY); + } else { + printf("ERROR: Failed to create both master and slave FIFO.\n"); + exit(EXIT_FAILURE); + } + } + // Allow both master and slave to attempt removal. Ignore error code since + // this is a best-effort situation for now. + unlink(MASTER_FIFO_NAME); + unlink(SLAVE_FIFO_NAME); + setvbuf(stdout, (char*)NULL, _IONBF, 0); /* No buffering. */ sgftree = *tree; @@ -681,19 +708,23 @@ void play_twoplayer(SGFTree* tree, Gameinfo* gameinfo, char* filename, char* unt sgf_initialized = 0; } - do_play_twoplayer(gameinfo); + do_play_twoplayer(gameinfo, transmit_fifo_fd, receive_fifo_fd); printf("\nThanks! for playing GNU Go.\n\n"); + close(transmit_fifo_fd); + close(receive_fifo_fd); + /* main() frees the tree and we might have changed it. */ *tree = sgftree; } -void do_play_twoplayer(Gameinfo* gameinfo) +void do_play_twoplayer(Gameinfo* gameinfo, int transmit_fifo_fd, int receive_fifo_fd) { - int m, num; - float fnum; + //int m; + int num; + //float fnum; int passes = 0; /* two passes and its over */ - int tmp; + //int tmp; char line[80]; char* line_ptr = line; char* command; @@ -710,8 +741,8 @@ void do_play_twoplayer(Gameinfo* gameinfo) current_score_estimate = NO_SCORE; /* Allow resignation at interface level (the engine may still be not - * allowed to resign. - */ + * allowed to resign. + */ resignation_allowed = 1; printf("\nBeginning two player game.\n\n"); @@ -719,7 +750,7 @@ void do_play_twoplayer(Gameinfo* gameinfo) /* Does the computer play first? If so, make a move. */ if (gameinfo->computer_player == gameinfo->to_move) - state = computer_move(gameinfo, &passes); + state = computer_move(gameinfo, &passes, receive_fifo_fd); /* main ANSI Play loop */ while (state == 0) { @@ -749,7 +780,7 @@ void do_play_twoplayer(Gameinfo* gameinfo) /* Get the command or move. */ switch (get_command(command)) { case RESIGN: - state = twoplayer_endgame(gameinfo, 1); + //state = twoplayer_endgame(gameinfo, 1); break; case END: @@ -775,71 +806,75 @@ void do_play_twoplayer(Gameinfo* 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); + printf("Board size modification prohibited in two player mode.\n"); + //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); + printf("Handicap modification prohibited in two player mode.\n"); + //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++; - twoplayer_free_handicap(gameinfo, command); + printf("Handicap modification prohibited in two player mode.\n"); + //if (sgf_initialized) { + // printf("Handicap cannot be changed after game is started!\n"); + // break; + //} + //while (*command && *command != ' ') + // command++; + //twoplayer_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); + printf("Komi modification prohibited in two player mode.\n"); + //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: @@ -868,92 +903,100 @@ void do_play_twoplayer(Gameinfo* gameinfo) 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; - } + printf("No!\n"); + //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); + state = do_move(gameinfo, command, &passes, 0, transmit_fifo_fd, receive_fifo_fd); break; case PASS: - state = do_pass(gameinfo, &passes, 0); + state = do_pass(gameinfo, &passes, 0, transmit_fifo_fd, receive_fifo_fd); 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; - } + printf("Invalid command in two player mode.\n"); + //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); + printf("Invalid command in two player mode.\n"); + //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); + printf("Invalid command in two player mode.\n"); + //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); + printf("Invalid command in two player mode.\n"); + //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"); + printf("No undo in two player mode.\n"); + //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"); + printf("Invalid command in two player mode.\n"); + //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); + printf("Invalid command in two player mode.\n"); + //while (sgftreeForward(&sgftree)) + // gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode, + // gameinfo->to_move); break; case COMMENT: @@ -969,49 +1012,57 @@ void do_play_twoplayer(Gameinfo* gameinfo) break; case CMD_DEAD: - silent_examine_position(FULL_EXAMINE_DRAGONS); - showdead = !showdead; + printf("Invalid command in two player mode.\n"); + //silent_examine_position(FULL_EXAMINE_DRAGONS); + //showdead = !showdead; break; case CMD_CAPTURE: - strtok(command, " "); - showcapture(strtok(NULL, " ")); + printf("Invalid command in two player mode.\n"); + //strtok(command, " "); + //showcapture(strtok(NULL, " ")); break; case CMD_DEFEND: - strtok(command, " "); - showdefense(strtok(NULL, " ")); + printf("Invalid command in two player mode.\n"); + //strtok(command, " "); + //showdefense(strtok(NULL, " ")); break; case CMD_SHOWMOYO: - tmp = printmoyo; - printmoyo = PRINTMOYO_MOYO; - silent_examine_position(EXAMINE_DRAGONS); - printmoyo = tmp; + printf("Invalid command in two player mode.\n"); + //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; + printf("Invalid command in two player mode.\n"); + //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; + printf("Invalid command in two player mode.\n"); + //tmp = printmoyo; + //printmoyo = PRINTMOYO_AREA; + //silent_examine_position(EXAMINE_DRAGONS); + //printmoyo = tmp; break; case CMD_SHOWDRAGONS: - silent_examine_position(EXAMINE_DRAGONS); - showboard(1); + printf("Invalid command in two player mode.\n"); + //silent_examine_position(EXAMINE_DRAGONS); + //showboard(1); break; case CMD_GOTO: - strtok(command, " "); - twoplayer_goto(gameinfo, strtok(NULL, " ")); + printf("Invalid command in two player mode.\n"); + //strtok(command, " "); + //twoplayer_goto(gameinfo, strtok(NULL, " ")); break; case CMD_SAVE: @@ -1023,37 +1074,40 @@ void do_play_twoplayer(Gameinfo* gameinfo) /* 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 twoplayer\n", tmpstring); - printf("or load %s\n", tmpstring); + printf("Game saved at %s for offline use.\n", tmpstring); + //printf("You may resume the game"); + //printf(" with -l %s --mode twoplayer\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"); + printf("Invalid command in two player mode.\n"); + //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(); + printf("Invalid command in two player mode.\n"); + //silent_examine_position(EXAMINE_DRAGONS); + //show_dragons(); break; default: @@ -1061,8 +1115,10 @@ void do_play_twoplayer(Gameinfo* gameinfo) break; } - if (passes >= 2) + if (passes >= 2) { + twoplayer_send_move(NO_MOVE,transmit_fifo_fd); state = twoplayer_endgame(gameinfo, 0); + } } #if READLINE free(line_ptr); @@ -1227,133 +1283,133 @@ twoplayer_count(Gameinfo* gameinfo) who_wins(gameinfo->computer_player, stdout); } -static void -showcapture(char* line) -{ - int str; - int move; - - gg_assert(line); - str = string_to_location(board_size, line); - if (str == NO_MOVE || board[str] == EMPTY) { - printf("\ninvalid point!\n"); - return; - } - - if (attack(str, &move)) - mprintf("\nSuccessful attack of %1m at %1m\n", str, move); - else - mprintf("\n%1m cannot be attacked\n", str); -} - -static void -showdefense(char* line) -{ - int str; - int move; - - gg_assert(line); - str = string_to_location(board_size, line); - if (str == NO_MOVE || board[str] == EMPTY) { - printf("\ninvalid point!\n"); - return; - } - - if (attack(str, NULL)) { - if (find_defense(str, &move)) - mprintf("\nSuccessful defense of %1m at %1m\n", str, move); - else - mprintf("\n%1m cannot be defended\n", str); - } else - mprintf("\nThere is no need to defend %1m\n", str); -} - -static void -twoplayer_goto(Gameinfo* gameinfo, char* line) -{ - const char* movenumber = line; - - if (!line) - return; - - if (!strncmp(line, "last", 4)) - movenumber = "9999"; - else if (!strncmp(line, "first", 4)) - movenumber = "1"; - - printf("goto %s\n", movenumber); - gameinfo_play_sgftree(gameinfo, &sgftree, movenumber); -} - -static void -twoplayer_free_handicap(Gameinfo* gameinfo, char* handicap_string) -{ - int handi; - int i; - char line[80]; - int stones[MAX_BOARD * MAX_BOARD]; - - if (sscanf(handicap_string, "%d", &handi) == 1) { - /* GNU Go is to place handicap */ - if (handi < 0 || handi == 1) { - printf("\nInvalid command syntax!\n"); - return; - } - - clear_board(); - handi = place_free_handicap(handi); - printf("\nPlaced %d stones of free handicap.\n", handi); - } else { /* User is to place handicap */ - clear_board(); - handi = 0; - - while (1) { - twoplayer_showboard(); - printf("\nType in coordinates of next handicap stone, or one of the following commands:\n"); - printf(" undo take back the last stone placed\n"); - printf(" clear remove all the stones placed so far\n"); - printf(" done finish placing handicap\n\n"); - printf("You have placed %d handicap stone(s) so far.\n\n", handi); - - if (!fgets(line, 80, stdin)) - return; /* EOF or some error */ - for (i = 0; i < 80; i++) - line[i] = tolower((int)line[i]); - - if (!strncmp(line, "undo", 4)) { - if (!handi) - printf("\nNothing to undo.\n"); - else { - remove_stone(stones[--handi]); - gprintf("\nRemoved the stone at %m.\n", I(stones[handi]), - J(stones[handi])); - } - } else if (!strncmp(line, "clear", 5)) { - clear_board(); - handi = 0; - } else if (!strncmp(line, "done", 4)) { - if (handi == 1) /* Don't bother with checks later */ - printf("\nHandicap cannot be one stone. Either add " - "some more, or delete the only stone.\n"); - else - break; - } else { - int pos = string_to_location(board_size, line); - if (pos != NO_MOVE) { - if (board[pos] != EMPTY) - printf("\nThere's already a stone there.\n"); - else { - add_stone(pos, BLACK); - stones[handi++] = pos; - } - } else - printf("\nInvalid command: %s", line); - } - } - } - gameinfo->handicap = handi; - gameinfo->to_move = (handi ? WHITE : BLACK); -} +//static void +//showcapture(char* line) +//{ +// int str; +// int move; +// +// gg_assert(line); +// str = string_to_location(board_size, line); +// if (str == NO_MOVE || board[str] == EMPTY) { +// printf("\ninvalid point!\n"); +// return; +// } +// +// if (attack(str, &move)) +// mprintf("\nSuccessful attack of %1m at %1m\n", str, move); +// else +// mprintf("\n%1m cannot be attacked\n", str); +//} + +//static void +//showdefense(char* line) +//{ +// int str; +// int move; +// +// gg_assert(line); +// str = string_to_location(board_size, line); +// if (str == NO_MOVE || board[str] == EMPTY) { +// printf("\ninvalid point!\n"); +// return; +// } +// +// if (attack(str, NULL)) { +// if (find_defense(str, &move)) +// mprintf("\nSuccessful defense of %1m at %1m\n", str, move); +// else +// mprintf("\n%1m cannot be defended\n", str); +// } else +// mprintf("\nThere is no need to defend %1m\n", str); +//} + +//static void +//twoplayer_goto(Gameinfo* gameinfo, char* line) +//{ +// const char* movenumber = line; +// +// if (!line) +// return; +// +// if (!strncmp(line, "last", 4)) +// movenumber = "9999"; +// else if (!strncmp(line, "first", 4)) +// movenumber = "1"; +// +// printf("goto %s\n", movenumber); +// gameinfo_play_sgftree(gameinfo, &sgftree, movenumber); +//} + +//static void +//twoplayer_free_handicap(Gameinfo* gameinfo, char* handicap_string) +//{ +// int handi; +// int i; +// char line[80]; +// int stones[MAX_BOARD * MAX_BOARD]; +// +// if (sscanf(handicap_string, "%d", &handi) == 1) { +// /* GNU Go is to place handicap */ +// if (handi < 0 || handi == 1) { +// printf("\nInvalid command syntax!\n"); +// return; +// } +// +// clear_board(); +// handi = place_free_handicap(handi); +// printf("\nPlaced %d stones of free handicap.\n", handi); +// } else { /* User is to place handicap */ +// clear_board(); +// handi = 0; +// +// while (1) { +// twoplayer_showboard(); +// printf("\nType in coordinates of next handicap stone, or one of the following commands:\n"); +// printf(" undo take back the last stone placed\n"); +// printf(" clear remove all the stones placed so far\n"); +// printf(" done finish placing handicap\n\n"); +// printf("You have placed %d handicap stone(s) so far.\n\n", handi); +// +// if (!fgets(line, 80, stdin)) +// return; /* EOF or some error */ +// for (i = 0; i < 80; i++) +// line[i] = tolower((int)line[i]); +// +// if (!strncmp(line, "undo", 4)) { +// if (!handi) +// printf("\nNothing to undo.\n"); +// else { +// remove_stone(stones[--handi]); +// gprintf("\nRemoved the stone at %m.\n", I(stones[handi]), +// J(stones[handi])); +// } +// } else if (!strncmp(line, "clear", 5)) { +// clear_board(); +// handi = 0; +// } else if (!strncmp(line, "done", 4)) { +// if (handi == 1) /* Don't bother with checks later */ +// printf("\nHandicap cannot be one stone. Either add " +// "some more, or delete the only stone.\n"); +// else +// break; +// } else { +// int pos = string_to_location(board_size, line); +// if (pos != NO_MOVE) { +// if (board[pos] != EMPTY) +// printf("\nThere's already a stone there.\n"); +// else { +// add_stone(pos, BLACK); +// stones[handi++] = pos; +// } +// } else +// printf("\nInvalid command: %s", line); +// } +// } +// } +// gameinfo->handicap = handi; +// gameinfo->to_move = (handi ? WHITE : BLACK); +//} /* * Local Variables: