int legal_go(float *b, char *ko, int p, int r, int c) { if (b[r*19 + c]) return 0; char curr[91]; char next[91]; board_to_string(curr, b); move_go(b, p, r, c); board_to_string(next, b); string_to_board(curr, b); if(memcmp(next, ko, 91) == 0) return 0; return 1; }
static void print_board(int *board, int w, int h) { if (verbose) { char *repr = board_to_string(board, w, h); printv("%s\n", repr); free(repr); } }
/* Looks up a previously stored state, or generates a new one. No assumptions are made about whether the board state is in reduced form already. Never fails. If the memory is full it allocates a new state regardless. If the state is found and returned it's OpenMP lock is first set. Thread-safe. RETURNS the state information */ tt_stats * tt_lookup_create( const board * b, bool is_black, u64 hash ){ u32 key = (u32)(hash % ((u64)number_of_buckets)); omp_lock_t * bucket_lock = is_black ? &b_table_lock : &w_table_lock; omp_set_lock(bucket_lock); tt_stats * ret = find_state(hash, b, is_black); if(ret == NULL) /* doesnt exist */ { if(states_in_use >= max_allocated_states) { /* It is possible in theory for a complex ko to produce a situation where freeing the game tree that is not reachable doesn't free any states. */ tt_log_status(); char * s = alloc(); board_to_string(s, b->p, b->last_played, b->last_eaten); flog_warn("tt", s); release(s); flog_warn("tt", "memory exceeded on root lookup"); } ret = create_state(hash); memcpy(ret->p, b->p, TOTAL_BOARD_SIZ); ret->last_eaten_passed = (b->last_played == PASS) ? PASS : b->last_eaten; omp_set_lock(&ret->lock); if(is_black) { ret->next = b_stats_table[key]; b_stats_table[key] = ret; } else { ret->next = w_stats_table[key]; w_stats_table[key] = ret; } omp_unset_lock(bucket_lock); } else /* update */ { omp_set_lock(&ret->lock); omp_unset_lock(bucket_lock); } return ret; }
int getMoveForPosition(ChessBoard * board) { std::pair<std::multimap<HASHKEY, Coord>::iterator, std::multimap<HASHKEY, Coord>::iterator> positionStartEnd; cerr << board_to_string(board) << endl; positionStartEnd = openingBook.equal_range(board->zobristHashKey); std::vector<Coord> coords; int totalWeight = 0; for(std::multimap<HASHKEY, Coord>::iterator itPosition = positionStartEnd.first; itPosition != positionStartEnd.second; ++itPosition) { coords.push_back(itPosition->second); totalWeight += itPosition->second.weight; } // select a move given the weights if (coords.empty()) return -1; Coord theCoord; if (coords.size() == 1) theCoord = coords.front(); else { int whichOne = rand() % totalWeight; int weightSoFar = 0; for(std::vector<Coord>::iterator itCoords = coords.begin(); itCoords != coords.end(); ++itCoords) { if (itCoords->weight + weightSoFar > whichOne) { theCoord = *itCoords; break; } weightSoFar += itCoords->weight; } // convert it to a move } if (!MoveIsLegal(board, theCoord.move)) { cerr << "move from opening book: " << MoveToString(theCoord.move) << " is not legal!" << endl; return -1; } LOG4CPLUS_DEBUG(logger, "book move " << MoveToString(theCoord.move)); return theCoord.move; }
void self_go(char *filename, char *weightfile, char *f2, char *w2, int multi) { network net = parse_network_cfg(filename); if(weightfile){ load_weights(&net, weightfile); } network net2 = net; if(f2){ net2 = parse_network_cfg(f2); if(w2){ load_weights(&net2, w2); } } srand(time(0)); char boards[300][93]; int count = 0; set_batch_network(&net, 1); set_batch_network(&net2, 1); float *board = calloc(19*19, sizeof(float)); char *one = calloc(91, sizeof(char)); char *two = calloc(91, sizeof(char)); int done = 0; int player = 1; int p1 = 0; int p2 = 0; int total = 0; while(1){ if (done || count >= 300){ float score = score_game(board); int i = (score > 0)? 0 : 1; if((score > 0) == (total%2==0)) ++p1; else ++p2; ++total; fprintf(stderr, "Total: %d, Player 1: %f, Player 2: %f\n", total, (float)p1/total, (float)p2/total); int j; for(; i < count; i += 2){ for(j = 0; j < 93; ++j){ printf("%c", boards[i][j]); } printf("\n"); } memset(board, 0, 19*19*sizeof(float)); player = 1; done = 0; count = 0; fflush(stdout); fflush(stderr); } //print_board(board, 1, 0); //sleep(1); network use = ((total%2==0) == (player==1)) ? net : net2; int index = generate_move(use, player, board, multi, .1, .7, two, 0); if(index < 0){ done = 1; continue; } int row = index / 19; int col = index % 19; char *swap = two; two = one; one = swap; if(player < 0) flip_board(board); boards[count][0] = row; boards[count][1] = col; board_to_string(boards[count] + 2, board); if(player < 0) flip_board(board); ++count; move_go(board, player, row, col); board_to_string(one, board); player = -player; } }
void engine_go(char *filename, char *weightfile, int multi) { network net = parse_network_cfg(filename); if(weightfile){ load_weights(&net, weightfile); } srand(time(0)); set_batch_network(&net, 1); float *board = calloc(19*19, sizeof(float)); char *one = calloc(91, sizeof(char)); char *two = calloc(91, sizeof(char)); int passed = 0; while(1){ char buff[256]; int id = 0; int has_id = (scanf("%d", &id) == 1); scanf("%s", buff); if (feof(stdin)) break; char ids[256]; sprintf(ids, "%d", id); //fprintf(stderr, "%s\n", buff); if (!has_id) ids[0] = 0; if (!strcmp(buff, "protocol_version")){ printf("=%s 2\n\n", ids); } else if (!strcmp(buff, "name")){ printf("=%s DarkGo\n\n", ids); } else if (!strcmp(buff, "version")){ printf("=%s 1.0\n\n", ids); } else if (!strcmp(buff, "known_command")){ char comm[256]; scanf("%s", comm); int known = (!strcmp(comm, "protocol_version") || !strcmp(comm, "name") || !strcmp(comm, "version") || !strcmp(comm, "known_command") || !strcmp(comm, "list_commands") || !strcmp(comm, "quit") || !strcmp(comm, "boardsize") || !strcmp(comm, "clear_board") || !strcmp(comm, "komi") || !strcmp(comm, "final_status_list") || !strcmp(comm, "play") || !strcmp(comm, "genmove")); if(known) printf("=%s true\n\n", ids); else printf("=%s false\n\n", ids); } else if (!strcmp(buff, "list_commands")){ printf("=%s protocol_version\nname\nversion\nknown_command\nlist_commands\nquit\nboardsize\nclear_board\nkomi\nplay\ngenmove\nfinal_status_list\n\n", ids); } else if (!strcmp(buff, "quit")){ break; } else if (!strcmp(buff, "boardsize")){ int boardsize = 0; scanf("%d", &boardsize); //fprintf(stderr, "%d\n", boardsize); if(boardsize != 19){ printf("?%s unacceptable size\n\n", ids); } else { printf("=%s \n\n", ids); } } else if (!strcmp(buff, "clear_board")){ passed = 0; memset(board, 0, 19*19*sizeof(float)); printf("=%s \n\n", ids); } else if (!strcmp(buff, "komi")){ float komi = 0; scanf("%f", &komi); printf("=%s \n\n", ids); } else if (!strcmp(buff, "play")){ char color[256]; scanf("%s ", color); char c; int r; int count = scanf("%c%d", &c, &r); int player = (color[0] == 'b' || color[0] == 'B') ? 1 : -1; if(c == 'p' && count < 2) { passed = 1; printf("=%s \n\n", ids); char *line = fgetl(stdin); free(line); fflush(stdout); fflush(stderr); continue; } else { passed = 0; } if(c >= 'A' && c <= 'Z') c = c - 'A'; if(c >= 'a' && c <= 'z') c = c - 'a'; if(c >= 8) --c; r = 19 - r; fprintf(stderr, "move: %d %d\n", r, c); char *swap = two; two = one; one = swap; move_go(board, player, r, c); board_to_string(one, board); printf("=%s \n\n", ids); print_board(board, 1, 0); } else if (!strcmp(buff, "genmove")){ char color[256]; scanf("%s", color); int player = (color[0] == 'b' || color[0] == 'B') ? 1 : -1; int index = generate_move(net, player, board, multi, .1, .7, two, 1); if(passed || index < 0){ printf("=%s pass\n\n", ids); passed = 0; } else { int row = index / 19; int col = index % 19; char *swap = two; two = one; one = swap; move_go(board, player, row, col); board_to_string(one, board); row = 19 - row; if (col >= 8) ++col; printf("=%s %c%d\n\n", ids, 'A' + col, row); print_board(board, 1, 0); } } else if (!strcmp(buff, "p")){ //print_board(board, 1, 0); } else if (!strcmp(buff, "final_status_list")){ char type[256]; scanf("%s", type); fprintf(stderr, "final_status\n"); char *line = fgetl(stdin); free(line); if(type[0] == 'd' || type[0] == 'D'){ FILE *f = fopen("game.txt", "w"); int i, j; int count = 2; fprintf(f, "boardsize 19\n"); fprintf(f, "clear_board\n"); for(j = 0; j < 19; ++j){ for(i = 0; i < 19; ++i){ if(board[j*19 + i] == 1) fprintf(f, "play black %c%d\n", 'A'+i+(i>=8), 19-j); if(board[j*19 + i] == -1) fprintf(f, "play white %c%d\n", 'A'+i+(i>=8), 19-j); if(board[j*19 + i]) ++count; } } fprintf(f, "final_status_list dead\n"); fclose(f); FILE *p = popen("./gnugo --mode gtp < game.txt", "r"); for(i = 0; i < count; ++i){ free(fgetl(p)); free(fgetl(p)); } char *l = 0; while((l = fgetl(p))){ printf("%s\n", l); free(l); } } else { printf("?%s unknown command\n\n", ids); } } else { char *line = fgetl(stdin); free(line); printf("?%s unknown command\n\n", ids); } fflush(stdout); fflush(stderr); } }
static char *game_text_format(game_state *state) { const int w = state->shared->params.w; const int h = state->shared->params.h; return board_to_string(state->board, w, h); }