SGFNodeP readsgffile(TCHAR *filename) { SGFNodeP root; int tmpi = 0; /*if (strcmp(filename, "-") == 0) sgffile = stdin; else*/ sgffile = CreateFile( filename, // file to open GENERIC_READ, // we just need read access FILE_SHARE_READ, // allow read access for others NULL, // security attributes OPEN_EXISTING, // the file needs to exist 0, // file attribute NULL ); // handle to a template file if (!sgffile) return NULL; nexttoken(); gametree(&root, NULL, LAX); CloseHandle(sgffile); if (sgferr) { fprintf(stderr, "Parse error: %s at position %d\n", sgferr, sgferrpos); return NULL; } /* perform some simple checks on the file */ if (!sgfGetIntProperty(root, "GM", &tmpi)) { fprintf(stderr, "Couldn't find the game type (GM) attribute!\n"); } if (tmpi != 1) { fprintf(stderr, "SGF file might be for game other than go: %d\n", tmpi); fprintf(stderr, "Trying to load anyway.\n"); } if (!sgfGetIntProperty(root, "FF", &tmpi)) { fprintf(stderr, "Can not determine SGF spec version (FF)!\n"); } if (tmpi<3 || tmpi>4) { fprintf(stderr, "Unsupported SGF spec version: %d\n", tmpi); } return root; }
void GTPArchiving_loadSGF( GauGoEngine* engine, int argc, char** argv ) { // Must have exactly 1 argument if( argc != 2 ){ GauGoEngine_sayError( UNKOWN_COMMAND ); return; } char* filename = argv[1]; SGFTree tree; tree.root = NULL; tree.lastnode = NULL; if( !sgftree_readfile( &tree, filename ) ){ GauGoEngine_sayError( FILE_NOT_FOUND ); return; } // Get board size and reset/resize the board accordingly sgftreeForward( &tree ); int size=19; sgfGetIntProperty( tree.lastnode, "SZ", &size ); engine->options.boardSize = size; GauGoEngine_resetBoard( engine ); // Read and play main variation while( sgftreeForward( &tree ) ){ // Pass node if( is_pass_node( tree.lastnode, size ) ){ GauGoEngine_play( engine, PASS ); } else{ if( is_move_node( tree.lastnode ) ){ INTERSECTION move = Board_intersection( engine->board, get_moveY(tree.lastnode->props, size), get_moveX(tree.lastnode->props, size) ); // SGF validation check if( !Board_isLegal(engine->board, move) ){ GauGoEngine_sayError(BAD_DATA); } // Must be able to play GauGoEngine_play( engine, move ); } else if( is_pass_node( tree.lastnode, size ) ){ GauGoEngine_play( engine, PASS ); } } } // Success GauGoEngine_saySuccess(""); }
void play_ascii(SGFTree *tree, Gameinfo *gameinfo, char *filename, char *until) { int sz; setvbuf(stdout, (char *)NULL, _IONBF, 0); /* No buffering. */ sgftree = *tree; if (filename) { /* 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); sgf_initialized = 1; } else { if (sgfGetIntProperty(sgftree.root, "SZ", &sz)) gnugo_clear_board(sz); if (gameinfo->handicap == 0) gameinfo->to_move = BLACK; else { gameinfo->handicap = place_fixed_handicap(gameinfo->handicap); gameinfo->to_move = WHITE; } sgf_initialized = 0; } do_play_ascii(gameinfo); printf("\nThanks! for playing GNU Go.\n\n"); /* main() frees the tree and we might have changed it. */ *tree = sgftree; }