/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define _XOPEN_SOURCE 500
#include <readline/history.h>
#include <readline/readline.h>
#define DEBUG_COMMANDS "\
No debug commands in two player mode\n\
#define MASTER_FIFO_NAME "/tmp/sgkgo-fifo-master"
#define SLAVE_FIFO_NAME "/tmp/sgkgo-fifo-slave"
#define RESETCOLOR "\x1B[0m"
#define WHITECOLOR "\x1B[41m"
#define BLACKCOLOR "\x1B[44m"
#define TILE1COLOR "\x1B[47m"
#define TILE2COLOR "\x1B[107m"
#define TILE3COLOR "\x1B[43m"
/* some options for the twoplayer interface */
static int opt_showboard
= 1;
static int resignation_allowed
;
/* Unreasonable score used to detect missing information. */
/* 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
, 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);
/* If sgf game info is written can't reset parameters like handicap, etc. */
static int sgf_initialized
;
* Create letterbar for the top and bottom of the ANSI board.
make_letterbar(int boardsize
, char* letterbar
)
for (i
= 0; i
< boardsize
; i
++) {
if (i
+ letteroffset
>= 'I')
strcat(letterbar
, spaces
);
sprintf(letter
, "%c", i
+ letteroffset
);
strcat(letterbar
, letter
);
/* This array contains +'s and -'s for the empty board positions.
* hspot_size contains the board size that the grid has been
static char hspots
[MAX_BOARD
][MAX_BOARD
];
* Mark the handicap spots on the board.
set_handicap_spots(int boardsize
)
if (hspot_size
== boardsize
)
memset(hspots
, '.', sizeof(hspots
));
hspots
[boardsize
- 2][1] = '+';
hspots
[1][boardsize
- 2] = '+';
hspots
[boardsize
- 2][boardsize
- 2] = '+';
hspots
[boardsize
/ 2][boardsize
/ 2] = '+';
/* If the board size is even, no center handicap spots. */
if (boardsize
> 2 && boardsize
< 12) {
/* Place the outer 4 only. */
hspots
[boardsize
- 3][2] = '+';
hspots
[2][boardsize
- 3] = '+';
hspots
[boardsize
- 3][boardsize
- 3] = '+';
/* Place the outer 4 only. */
hspots
[boardsize
- 4][3] = '+';
hspots
[3][boardsize
- 4] = '+';
hspots
[boardsize
- 4][boardsize
- 4] = '+';
if (boardsize
> 2 && boardsize
< 12) {
/* Place the outer 4... */
hspots
[boardsize
- 3][2] = '+';
hspots
[2][boardsize
- 3] = '+';
hspots
[boardsize
- 3][boardsize
- 3] = '+';
/* ...and the middle one. */
hspots
[boardsize
/ 2][boardsize
/ 2] = '+';
} else if (boardsize
> 12) {
/* Place the outer 4... */
hspots
[boardsize
- 4][3] = '+';
hspots
[3][boardsize
- 4] = '+';
hspots
[boardsize
- 4][boardsize
- 4] = '+';
/* ...and the inner 4... */
hspots
[3][boardsize
/ 2] = '+';
hspots
[boardsize
/ 2][3] = '+';
hspots
[boardsize
/ 2][boardsize
- 4] = '+';
hspots
[boardsize
- 4][boardsize
/ 2] = '+';
/* ...and the middle one. */
hspots
[boardsize
/ 2][boardsize
/ 2] = '+';
* Display the board position when playing in ANSI.
twoplayer_showboard(void)
int last_move
= get_last_move();
make_letterbar(board_size
, letterbar
);
set_handicap_spots(board_size
);
printf(" White (" WHITECOLOR
" " RESETCOLOR
") has captured %d pieces\n", black_captured
);
printf(" Black (" BLACKCOLOR
" " RESETCOLOR
") has captured %d pieces\n", white_captured
);
if (current_score_estimate
== NO_SCORE
)
printf(" No score estimate is available yet.\n");
else if (current_score_estimate
< 0)
printf(" Estimated score: Black is ahead by %d\n",
-current_score_estimate
);
else if (current_score_estimate
> 0)
printf(" Estimated score: White is ahead by %d\n",
printf(" Estimated score: Even!\n");
if (get_last_player() != EMPTY
) {
gfprintf(stdout
, " Last move: %s %1m",
get_last_player() == WHITE
? "White" : "Black",
for (i
= 0; i
< board_size
; i
++) {
printf(" %2d", board_size
- i
);
for (j
= 0; j
< board_size
; j
++) {
if (POS(i
, j
) == last_move
)
dead
= (dragon_status(POS(i
, j
)) == DEAD
) && showdead
;
switch (BOARD(i
, j
) + pos_is_move
+ last_pos_was_move
) {
printf(BLACKCOLOR
" " RESETCOLOR
);
printf(WHITECOLOR
" " RESETCOLOR
);
printf(BLACKCOLOR
"()" RESETCOLOR
);
printf(WHITECOLOR
"()" RESETCOLOR
);
printf(TILE1COLOR
" " RESETCOLOR
);
printf(TILE2COLOR
" " RESETCOLOR
);
printf(TILE2COLOR
" " RESETCOLOR
);
printf(TILE1COLOR
" " RESETCOLOR
);
fprintf(stderr
, "Illegal board value %d\n", (int)BOARD(i
, j
));
if (last_pos_was_move
== 0) {
printf(" %2d", board_size
- i
);
printf(" %1d", board_size
- i
);
printf("%2d", board_size
- i
);
printf("%1d", board_size
- i
);
printf("%s\n\n", letterbar
);
} /* end twoplayer_showboard */
printf(" comment Write a comment to outputfile\n");
printf(" depth <num> Set depth for reading\n");
printf(" display Display game board\n");
printf(" exit Exit GNU Go\n");
printf(" level <amount> Playing level (default = 10)\n");
printf(" help Display this help menu\n");
printf(" helpdebug Display debug help menu\n");
printf(" info Display program settings\n");
printf(" pass Pass on your move\n");
printf(" quit Exit GNU Go\n");
printf(" save <file> Save the current game\n");
printf(" score Toggle display of score On/Off\n");
printf(" showboard Toggle display of board On/Off\n");
printf(" <move> A move of the format <letter><number>");
enum commands
{ INVALID
= -1,
* Check if we have a valid command.
get_command(char* command
)
/* Check to see if a move was input. */
if (!((sscanf(command
, "%c%d", &c
, &d
) != 2)
|| ((c
= toupper((int)c
)) < 'A')
|| ((c
= toupper((int)c
)) > 'Z')
/* Kill leading spaces. */
while (command
[0] == ' ')
if (!strncmp(command
, "playblack", 9))
if (!strncmp(command
, "playwhite", 9))
if (!strncmp(command
, "showboard", 9))
if (!strncmp(command
, "showdragons", 9))
if (!strncmp(command
, "listdragons", 9))
if (!strncmp(command
, "boardsize", 9))
if (!strncmp(command
, "freehandicap", 9))
if (!strncmp(command
, "handicap", 5))
if (!strncmp(command
, "display", 7))
if (!strncmp(command
, "helpdebug", 7))
if (!strncmp(command
, "resign", 6))
if (!strncmp(command
, "showmoyo", 6))
if (!strncmp(command
, "showterri", 6))
if (!strncmp(command
, "showarea", 6))
if (!strncmp(command
, "depth", 5))
if (!strncmp(command
, "switch", 5))
if (!strncmp(command
, "komi", 4))
if (!strncmp(command
, "play", 4))
if (!strncmp(command
, "info", 4))
if (!strncmp(command
, "force", 4))
if (!strncmp(command
, "level", 5))
if (!strncmp(command
, "pass", 4))
if (!strncmp(command
, "save", 3))
if (!strncmp(command
, "load", 3))
if (!strncmp(command
, "end", 3))
if (!strncmp(command
, "move", 3))
if (!strncmp(command
, "undo", 3))
if (!strncmp(command
, "comment", 3))
if (!strncmp(command
, "score", 3))
if (!strncmp(command
, "dead", 3))
if (!strncmp(command
, "capture", 3))
if (!strncmp(command
, "defend", 3))
if (!strncmp(command
, "exit", 4))
if (!strncmp(command
, "quit", 4))
if (!strncmp(command
, "help", 1))
if (!strncmp(command
, "back", 2))
if (!strncmp(command
, "forward", 2))
if (!strncmp(command
, "last", 2))
if (!strncmp(command
, "goto", 2))
if (!strncmp(command
, "game", 2))
if (!strncmp(command
, "count", 3))
if (!strncmp(command
, "continue", 4))
/* No valid command was found. */
init_sgf(Gameinfo
* ginfo
)
sgf_write_header(sgftree
.root
, 1, get_random_seed(), komi
,
ginfo
->handicap
, get_level(), chinese_rules
);
sgffile_recordboard(sgftree
.root
);
* Communication with second player.
twoplayer_recv_move(int fd
)
printf("\nWaiting to receive move from other player...\n");
if (read(fd
, &move
, sizeof(move
)) != sizeof(int)) {
printf(WHITECOLOR
" " RESETCOLOR
);
printf(WHITECOLOR
" " RESETCOLOR
);
printf("Unrecoverable error. Save game if desired, then quit.");
printf(WHITECOLOR
" " RESETCOLOR
);
printf(WHITECOLOR
" " RESETCOLOR
);
twoplayer_send_move(int move
, int fd
)
write(fd
, &move
, sizeof(move
));
* Generate the computer move.
computer_move(Gameinfo
* gameinfo
, int* passes
, int receive_fifo_fd
)
int resignation_declined
= 0;
float upper_bound
, lower_bound
;
move
= twoplayer_recv_move(receive_fifo_fd
);
gnugo_estimate_score(&upper_bound
, &lower_bound
);
current_score_estimate
= (int)((lower_bound
+ upper_bound
) / 2.0);
mprintf("%s(%d): %1m\n", color_to_string(gameinfo
->to_move
),
gnugo_play_move(move
, gameinfo
->to_move
);
sgftreeAddPlay(&sgftree
, gameinfo
->to_move
, I(move
), J(move
));
if (resignation_declined
)
sgftreeAddComment(&sgftree
, "GNU Go resignation was declined");
sgffile_output(&sgftree
);
gameinfo
->to_move
= OTHER_COLOR(gameinfo
->to_move
);
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
);
printf("\nInvalid move: %s\n", command
);
if (!is_allowed_move(move
, gameinfo
->to_move
)) {
printf("\nIllegal move: %s", command
);
twoplayer_send_move(move
,transmit_fifo_fd
);
TRACE("\nyour move: %1m\n\n", move
);
gnugo_play_move(move
, gameinfo
->to_move
);
sgffile_add_debuginfo(sgftree
.lastnode
, 0.0);
sgftreeAddPlay(&sgftree
, gameinfo
->to_move
, I(move
), J(move
));
sgffile_output(&sgftree
);
gameinfo
->computer_player
= OTHER_COLOR(gameinfo
->computer_player
);
gameinfo
->to_move
= OTHER_COLOR(gameinfo
->to_move
);
sgftreeAddComment(&sgftree
, "forced");
gameinfo
->to_move
= OTHER_COLOR(gameinfo
->to_move
);
return computer_move(gameinfo
, passes
, receive_fifo_fd
);
do_pass(Gameinfo
* gameinfo
, int* passes
, int force
,
int transmit_fifo_fd
, int receive_fifo_fd
)
twoplayer_send_move(NO_MOVE
,transmit_fifo_fd
);
gnugo_play_move(PASS_MOVE
, gameinfo
->to_move
);
sgffile_add_debuginfo(sgftree
.lastnode
, 0.0);
sgftreeAddPlay(&sgftree
, gameinfo
->to_move
, -1, -1);
sgffile_output(&sgftree
);
gameinfo
->to_move
= OTHER_COLOR(gameinfo
->to_move
);
gameinfo
->computer_player
= OTHER_COLOR(gameinfo
->computer_player
);
sgftreeAddComment(&sgftree
, "forced");
return computer_move(gameinfo
, passes
, receive_fifo_fd
);
* Play a game using ANSI client.
void play_twoplayer(SGFTree
* tree
, Gameinfo
* gameinfo
, char* filename
, char* until
)
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
);
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
);
printf("ERROR: Failed to create both master and slave FIFO.\n");
// Allow both master and slave to attempt removal. Ignore error code since
// this is a best-effort situation for now.
unlink(MASTER_FIFO_NAME
);
setvbuf(stdout
, (char*)NULL
, _IONBF
, 0); /* No buffering. */
/* No need to check for failure here since that was already done
* when it was loaded in main().
* FIXME: Why do we load the game again?
gameinfo_play_sgftree(gameinfo
, &sgftree
, until
);
if (sgfGetIntProperty(sgftree
.root
, "SZ", &sz
))
if (gameinfo
->handicap
== 0)
gameinfo
->to_move
= BLACK
;
gameinfo
->handicap
= place_fixed_handicap(gameinfo
->handicap
);
gameinfo
->to_move
= WHITE
;
do_play_twoplayer(gameinfo
, transmit_fifo_fd
, receive_fifo_fd
);
printf("\nThanks! for playing GNU Go.\n\n");
/* main() frees the tree and we might have changed it. */
void do_play_twoplayer(Gameinfo
* gameinfo
, int transmit_fifo_fd
, int receive_fifo_fd
)
int passes
= 0; /* two passes and its over */
if (have_time_settings())
/* No score is estimated yet. */
current_score_estimate
= NO_SCORE
;
/* Allow resignation at interface level (the engine may still be not
printf("\nBeginning two player 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
, receive_fifo_fd
);
/* main ANSI Play loop */
/* Display game board. */
mprintf("%s(%d): ", color_to_string(gameinfo
->to_move
), movenum
+ 1);
/* Read a line of input. */
if (!fgets(line
, 80, stdin
))
snprintf(line
, 79, "%s(%d): ",
color_to_string(gameinfo
->to_move
), movenum
+ 1);
if (!(line_ptr
= readline(line
)))
&& (command
= strtok(line_ptr
, ";"), line_ptr
= 0, command
)) {
/* Get the command or move. */
switch (get_command(command
)) {
//state = twoplayer_endgame(gameinfo, 1);
opt_showboard
= !opt_showboard
;
gameinfo_print(gameinfo
);
printf("Board size modification prohibited in two player mode.\n");
// printf("Boardsize cannot be changed after record is started!\n");
//if (sscanf(command, "%d", &num) != 1) {
// printf("\nInvalid command syntax!\n");
//if (!check_boardsize(num, stdout))
///* 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("Handicap modification prohibited in two player mode.\n");
// printf("Handicap cannot be changed after game is started!\n");
//if (sscanf(command, "%d", &num) != 1) {
// printf("\nInvalid command syntax!\n");
//if (num < 0 || num > MAX_HANDICAP) {
// printf("\nInvalid handicap: %d\n", num);
///* 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");
// printf("Handicap cannot be changed after game is started!\n");
//while (*command && *command != ' ')
//twoplayer_free_handicap(gameinfo, command);
printf("Komi modification prohibited in two player mode.\n");
// printf("Komi cannot be modified after game record is started!\n");
//if (sscanf(command, "%f", &fnum) != 1) {
// printf("\nInvalid command syntax!\n");
//printf("\nSet Komi to %.1f\n", komi);
if (sscanf(command
, "%d", &num
) != 1) {
printf("\nInvalid command syntax!\n");
printf("\nSet depth to %d\n", mandated_depth
);
if (sscanf(command
, "%d", &num
) != 1) {
printf("\nInvalid command syntax!\n");
printf("\nSet level to %d\n", num
);
//command += 6; /* skip the force part... */
//switch (get_command(command)) {
// state = do_move(gameinfo, command, &passes, 1);
// state = do_pass(gameinfo, &passes, 1);
// printf("Illegal forced move: %s %d\n", command,
// get_command(command));
state
= do_move(gameinfo
, command
, &passes
, 0, transmit_fifo_fd
, receive_fifo_fd
);
state
= do_pass(gameinfo
, &passes
, 0, transmit_fifo_fd
, receive_fifo_fd
);
printf("Invalid command in two player mode.\n");
//if (sscanf(command, "%d", &num) != 1) {
// printf("\nInvalid command syntax!\n");
// for (m = 0; m < num; m++) {
// gameinfo->computer_player
// = OTHER_COLOR(gameinfo->computer_player);
// state = computer_move(gameinfo, &passes);
// printf("\nInvalid number of moves specified: %d\n", num);
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);
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);
printf("Invalid command in two player mode.\n");
//gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player);
//state = computer_move(gameinfo, &passes);
printf("No undo in two player mode.\n");
// sgftreeAddComment(&sgftree, "undone");
// sgftreeBack(&sgftree);
// gameinfo->to_move = OTHER_COLOR(gameinfo->to_move);
// printf("\nCan't undo.\n");
printf("Invalid command in two player mode.\n");
//if (sgftreeForward(&sgftree))
// gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode,
// printf("\nEnd of game tree.\n");
printf("Invalid command in two player mode.\n");
//while (sgftreeForward(&sgftree))
// gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode,
printf("\nEnter comment. Press ENTER when ready.\n");
sgftreeAddComment(&sgftree
, line
);
current_score_estimate
= NO_SCORE
;
printf("Invalid command in two player mode.\n");
//silent_examine_position(FULL_EXAMINE_DRAGONS);
printf("Invalid command in two player mode.\n");
//showcapture(strtok(NULL, " "));
printf("Invalid command in two player mode.\n");
//showdefense(strtok(NULL, " "));
printf("Invalid command in two player mode.\n");
//printmoyo = PRINTMOYO_MOYO;
//silent_examine_position(EXAMINE_DRAGONS);
printf("Invalid command in two player mode.\n");
//printmoyo = PRINTMOYO_TERRITORY;
//silent_examine_position(EXAMINE_DRAGONS);
printf("Invalid command in two player mode.\n");
//printmoyo = PRINTMOYO_AREA;
//silent_examine_position(EXAMINE_DRAGONS);
printf("Invalid command in two player mode.\n");
//silent_examine_position(EXAMINE_DRAGONS);
printf("Invalid command in two player mode.\n");
//twoplayer_goto(gameinfo, strtok(NULL, " "));
tmpstring
= strtok(NULL
, " ");
tmpstring
[strlen(tmpstring
) - 1] = 0;
/* make sure we are saving proper handicap */
writesgf(sgftree
.root
, 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);
printf("Please specify filename\n");
printf("Invalid command in two player mode.\n");
//tmpstring = strtok(NULL, " ");
// tmpstring[strlen(tmpstring) - 1] = 0;
// if (!sgftree_readfile(&sgftree, tmpstring)) {
// fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
// /* to avoid changing handicap etc. */
// if (gameinfo_play_sgftree(gameinfo, &sgftree, NULL) == EMPTY)
// fprintf(stderr, "Cannot load '%s'\n", tmpstring);
// sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
// printf("Please specify a filename\n");
printf("Invalid command in two player mode.\n");
//silent_examine_position(EXAMINE_DRAGONS);
printf("\nInvalid command: %s", command
);
twoplayer_send_move(NO_MOVE
,transmit_fifo_fd
);
state
= twoplayer_endgame(gameinfo
, 0);
sgffile_output(&sgftree
);
/* Play a different game next time. */
/* Free the sgf tree and prepare for a new game. */
sgfFreeNode(sgftree
.root
);
sgftreeCreateHeaderNode(&sgftree
, board_size
, komi
, gameinfo
->handicap
);
gameinfo_clear(gameinfo
);
/* Communicates with user after a game has ended. */
twoplayer_endgame(Gameinfo
* gameinfo
, int reason
)
if (reason
== 0) { /* Two passes, game is over. */
who_wins(gameinfo
->computer_player
, stdout
);
printf("\nIf you disagree, we may count the game together.\n");
sgftreeWriteResult(&sgftree
, (white_score
+ black_score
) / 2.0, 1);
int color
= OTHER_COLOR(gameinfo
->to_move
);
if (reason
== 1) /* Our opponent has resigned. */
printf("GNU Go wins by resignation.\n");
else /* We have resigned. */
printf("You win by resignation.\n");
printf("Result: %c+Resign\n\n", color
== WHITE
? 'W' : 'B');
sgftreeWriteResult(&sgftree
, color
== WHITE
? 1000.0 : -1000.0, 1);
printf("You may optionally save the game as an SGF file.\n\n");
printf("Type \"save <filename>\" to save,\n");
printf(" \"count\" to recount,\n");
printf(" \"continue\" to decline resignation and continue the game,\n");
printf(" \"quit\" to quit\n");
printf(" or \"game\" to play again\n");
if (!fgets(line
, 80, stdin
))
command
= strtok(line_ptr
, "");
switch (get_command(command
)) {
tmpstring
= strtok(NULL
, " ");
tmpstring
[strlen(tmpstring
) - 1] = 0;
writesgf(sgftree
.root
, tmpstring
);
printf("Please specify filename\n");
twoplayer_count(gameinfo
);
/* twoplayer_count() scores the game.
twoplayer_count(Gameinfo
* gameinfo
)
printf("\nGame over. Let's count!.\n");
printf("Dead stones are marked with small letters (x,o).\n");
printf("\nIf you don't agree, enter the location of a group\n");
printf("to toggle its state or \"done\".\n");
if (!fgets(line
, 12, stdin
))
return; /* EOF or some error */
line
[i
] = tolower((int)line
[i
]);
if (!strncmp(line
, "done", 4))
else if (!strncmp(line
, "quit", 4))
else if (!strncmp(line
, "xyzzy", 5)) {
printf("\nYou are in a debris room filled with stuff washed in from the\n");
printf("surface. A low wide passage with cobbles becomes plugged\n");
printf("with mud and debris here, but an awkward canyon leads\n");
printf("upward and west. A note on the wall says:\n");
printf(" Magic Word \"XYZZY\"\n\n");
printf("You are inside a building, a well house for a large spring.\n\n");
} else if (!strncmp(line
, "help", 4)) {
printf("\nIf there are dead stones on the board I will remove them.\n");
printf("You must tell me where they are. Type the coordinates of a\n");
printf("dead group, or type \"done\"\n");
} else if (!strncmp(line
, "undo", 4)) {
printf("UNDO not allowed anymore. The status of the stones now\n");
printf("toggles after entering the location of it.\n");
int pos
= string_to_location(board_size
, line
);
if (pos
== NO_MOVE
|| board
[pos
] == EMPTY
)
enum dragon_status status
= dragon_status(pos
);
status
= (status
== DEAD
) ? ALIVE
: DEAD
;
change_dragon_status(pos
, status
);
who_wins(gameinfo
->computer_player
, stdout
);
//showcapture(char* line)
// str = string_to_location(board_size, line);
// if (str == NO_MOVE || board[str] == EMPTY) {
// printf("\ninvalid point!\n");
// if (attack(str, &move))
// mprintf("\nSuccessful attack of %1m at %1m\n", str, move);
// mprintf("\n%1m cannot be attacked\n", str);
//showdefense(char* line)
// str = string_to_location(board_size, line);
// if (str == NO_MOVE || board[str] == EMPTY) {
// printf("\ninvalid point!\n");
// if (attack(str, NULL)) {
// if (find_defense(str, &move))
// mprintf("\nSuccessful defense of %1m at %1m\n", str, move);
// mprintf("\n%1m cannot be defended\n", str);
// mprintf("\nThere is no need to defend %1m\n", str);
//twoplayer_goto(Gameinfo* gameinfo, char* line)
// const char* movenumber = line;
// if (!strncmp(line, "last", 4))
// else if (!strncmp(line, "first", 4))
// printf("goto %s\n", movenumber);
// gameinfo_play_sgftree(gameinfo, &sgftree, movenumber);
//twoplayer_free_handicap(Gameinfo* gameinfo, char* handicap_string)
// 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");
// handi = place_free_handicap(handi);
// printf("\nPlaced %d stones of free handicap.\n", handi);
// } else { /* User is to place handicap */
// 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)) {
// printf("\nNothing to undo.\n");
// remove_stone(stones[--handi]);
// gprintf("\nRemoved the stone at %m.\n", I(stones[handi]),
// } else if (!strncmp(line, "clear", 5)) {
// } 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");
// int pos = string_to_location(board_size, line);
// if (board[pos] != EMPTY)
// printf("\nThere's already a stone there.\n");
// add_stone(pos, BLACK);
// stones[handi++] = pos;
// printf("\nInvalid command: %s", line);
// gameinfo->handicap = handi;
// gameinfo->to_move = (handi ? WHITE : BLACK);