int play_one_move(int color) { int i, z, err; for (i=0; i<100; i++) { z = get_empty_z(); err = put_stone(z, color); if ( err == 0 ) return z; } z = 0; put_stone(0, color); return z; }
int search_uct(int color, int node_n) { NODE *pN = &node[node_n]; CHILD *c = NULL; int select, z, err, win, current_depth; for (;;) { select = select_best_ucb(node_n, color); c = &pN->child[select]; z = c->z; err = put_stone(z, color, FILL_EYE_ERR); if ( err == 0 ) break; c->z = ILLEGAL_Z; // select other move } current_depth = depth; path[depth++] = c->z; // playout in first time. <= 10 can reduce node. if ( c->games <= 0 || depth == D_MAX || (c->z == 0 && depth>=2 && path[depth-2]==0) ) { win = -playout(flip_color(color)); } else { if ( c->next == NODE_EMPTY ) c->next = create_node(c->z); win = -search_uct(flip_color(color), c->next); } update_rave(pN, color, current_depth, win); // update winrate c->rate = (c->rate * c->games + win) / (c->games + 1); c->games++; pN->child_games_sum++; return win; }
int main() { char username_1[20]; // user1 = 흙 char username_2[20]; // user2 = 백 // init board int foo[BOARD_SIZE][BOARD_SIZE] = {0}; // init SIZE*SIZE size // init username init_username(username_1, 1); init_username(username_2, 2); while (1) { print_board(foo); if ( current_turn == BOARD_SIZE * BOARD_SIZE + 1 ) { printf("게임을 종료합니다.\n"); return 0; } printf("---Turn(%2d)---\n", current_turn); printf("[%s]님의 턴입니다.\n", (current_turn%2) ? username_1 : username_2 ); while( put_stone(get_user_input_integer_with_name("ROW"), get_user_input_integer_with_name("COL"), foo) != 0 ) { printf("올바른 위치를 입력하세요.\n"); } print_board(foo); } return 0; }
int Board::move(Move mv, bool useMiai, int& bdset) { //bdset comp. from scratch // put mv.s on board, update connectivity for mv.s // WARNING opt(mv.s) connectivity will be broken if mv.s hits opt miai // useMiai ? miai adjacency : stone adjacency // return opponent miai reply of mv, will be mv.lcn if no miai // WARNING: there are 6 possible miai choices, each consecutive pair conflicts... // right now, selection is made randomly... so might not always find // winning choice .... might be better to // pick a maximal set that maximizes new brdr connectivity int nbr,nbrRoot,cpt; int lcn = mv.lcn; int s = mv.s; assert(brdr[lcn]==BRDR_NIL); put_stone(mv); cpt = lcn; // cpt of s group containing lcn for (int t=0; t<NumNbrs; t++) { // look for absolute nbrs nbr = lcn + Nbr_offsets[t]; if (board[nbr] == s) { nbrRoot = Find(p,nbr); brdr[nbrRoot] |= brdr[cpt]; cpt = Union(p,cpt,nbrRoot); } else if (board[nbr] == GRD) { brdr[cpt] |= brdr[nbr]; } } if (!useMiai) { bdset = brdr[cpt]; return lcn; // no miai, so return lcn } // else return moveMiaiPart(mv, useMiai, bdset,cpt); }
void addMove(int place, int color) { int err = put_stone(place, color, FILL_EYE_OK); if (err != 0) { prt("Err!\n"); exit(0); } }
void add_moves(int z, int color) { int err = put_stone(z, color, FILL_EYE_OK); if ( err != 0 ) { prt("Err!\n"); exit(0); } record[moves] = z; moves++; print_board(); }
int playout(int turn_color) { int color = turn_color; int previous_z = 0; int loop; int loop_max = B_SIZE*B_SIZE + 200; // for triple ko all_playouts++; for (loop=0; loop<loop_max; loop++) { // all empty points are candidates. int empty[BOARD_MAX][2]; // [0]...z, [1]...probability int empty_num = 0; int prob_sum = 0; int x,y,z,err,pr; for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) { int z = get_z(x+1,y+1); if ( board[z] != 0 ) continue; empty[empty_num][0] = z; pr = 100; // pr = get_prob(z, previous_z, color); empty[empty_num][1] = pr; prob_sum += pr; empty_num++; } for (;;) { int i = 0; if ( empty_num == 0 ) { z = 0; } else { int r = rand() % prob_sum; int sum = 0; for (i=0; i<empty_num; i++) { sum += empty[i][1]; // 0,1,2 [0]=1, [1]=1, [2]=1 if ( sum > r ) break; } if ( i==empty_num ) { prt("Err! prob_sum=%d,sum=%d,r=%d,r=%d\n",prob_sum,sum,r,i); exit(0); } z = empty[i][0]; } err = put_stone(z, color, FILL_EYE_ERR); if ( err == 0 ) break; // pass is ok. prob_sum -= empty[i][1]; empty[i][0] = empty[empty_num-1][0]; // err, delete empty[i][1] = empty[empty_num-1][1]; empty_num--; } if ( flag_test_playout ) record[moves++] = z; if ( depth < D_MAX ) path[depth++] = z; if ( z == 0 && previous_z == 0 ) break; // continuous pass previous_z = z; // prt("loop=%d,z=%s,c=%d,empty_num=%d,ko_z=%d\n",loop,get_char_z(z),color,empty_num,ko_z); color = flip_color(color); } return count_score(turn_color); }
/** * ゲームオーバーの手か * @param int pos 手 * @param stone_t turn 現在の手番 * @param stone_t board[][] 盤面 * @return int true:1, false:0 */ int is_terminate_hand(int pos, stone_t turn, const stone_t board[HIGHT][AREA]) { stone_t copy[HIGHT][AREA]; int layer; copy_board(board, copy); layer = put_stone(pos, turn, copy); // 置いてみる return check_win(layer, pos, turn, copy) || is_full(copy); }
int primitive_monte_calro(int color) { int try_num = 30; // number of playout int best_z = 0; double best_value; double win_rate; int x,y,err,i,win_sum,win; int ko_z_copy; int board_copy[BOARD_MAX]; // keep current board ko_z_copy = ko_z; memcpy(board_copy, board, sizeof(board)); best_value = -100; // try all empty point for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) { int z = get_z(x+1,y+1); if ( board[z] != 0 ) continue; err = put_stone(z, color, FILL_EYE_ERR); if ( err != 0 ) continue; win_sum = 0; for (i=0;i<try_num;i++) { int board_copy2[BOARD_MAX]; int ko_z_copy2 = ko_z; memcpy(board_copy2, board, sizeof(board)); win = -playout(flip_color(color)); win_sum += win; ko_z = ko_z_copy2; memcpy(board, board_copy2, sizeof(board)); } win_rate = (double)win_sum / try_num; // print_board(); // prt("z=%d,win=%5.3f\n",get81(z),win_rate); if ( win_rate > best_value ) { best_value = win_rate; best_z = z; // prt("best_z=%d,color=%d,v=%5.3f,try_num=%d\n",get81(best_z),color,best_value,try_num); } ko_z = ko_z_copy; memcpy(board, board_copy, sizeof(board)); // resume board } return best_z; }
int main() { initialize(); int tests = 1000; int passed = 0; fast_srandom(time(0)); for (int i = 0; i < tests; i++) { board_t *b = new board_t; int size = fast_random(max_size - 4) + 5; empty_board(b, size); int steps = 0; bool failed = false; while (true) { stone_t color = steps % 2 == 0 ? STONE_BLACK : STONE_WHITE; index_t pos = gen_move(b, color); if (pos < 0) break; if (!is_legal_move(b, pos, color)) { failed = true; break; } if (pos >= 0) { put_stone(b, pos, color); if (!check_board(b)) { failed = true; break; } } steps++; } delete b; if (failed) { printf("[F]"); } else { printf("[%d]", steps); passed++; } } printf("\n"); printf("Passed %d out of %d random tests\n", passed, tests); return passed == tests ? 0 : 1; }
int solve(Field f, Position p, int flip, int rotate, int i, int nowscore) { if (i >= number_of_stones) { return 0; } int u = i; if (flip == 1) { u += fliped; } u += rot[rotate / 90]; std::vector<Position> next_positions; int score = 0; if (score = put_stone(f, p, u, next_positions)) { score += nowscore; if (score > max_score) { max_score = score; max_score_field = f; fprintf(stderr, "max score %d!\n", score); } f.answer[i] = make_answer(p, flip, rotate); printf("score: %d\n", score); dump_field(f); print_answer(f.answer); int rot_buf[] = {0, 90, 180, 270}; for (auto && f_p : next_positions) { for (int j = i + 1; j < number_of_stones; ++j) { for (auto && s_p : stones[j].fills) { for (int k = 0; k < 4; ++k) { solve(f, Position{f_p.y - s_p.y, f_p.x - s_p.x}, 0, rot_buf[k], j, score); solve(f, Position{f_p.y - s_p.y, f_p.x - s_p.x}, 1, rot_buf[k], j, score); } } } } } return 0; }
int main(void) { FILE *fp; char LineData[MAX]; char *sp=NULL; char *data[MAX]; char *matchToken=";B["; char result[MAX]; char *chp[MAX]; int i=0,num=0,color=1; int kifuNum=0; if((fp=fopen("2015-05-01-9.sgf","r"))==NULL){ printf("file open err!"); exit(0); } while(fgets(LineData,MAX,fp)!=NULL){//LineDataとMAXの配列の大きさが等しくないといけない! sp=strstr(LineData,"RE["); if(sp!= NULL ){ strcpy(result,LineData); //printf("%s",result); sp=NULL; } data[i]=LineData; i++; } kifuNum=i-1; fclose(fp); if(*(data[kifuNum]+1)=='B'){ char *ch = "b"; char *tp; tp=strtok(data[kifuNum],";"); chp[num]=tp; num++; //printf("ch->num: %d a:%d \n",(int)*ch,'a'); //printf( "%d番目に発見しました\n",pointer - data[i-1] ); while(tp!=NULL){ tp=strtok(NULL,";"); if(tp!=NULL){ chp[num]=tp; num++; } } } else{ printf( "発見出来ません\n"); } for(i=0;i<num;i++){ int z; char BW; printf("%s\n",chp[i]); //printf("%c\n",*(chp[i]+2)); //printf("%d\n",(int)*(chp[i]+2)-96); BW = *chp[i]; printf("%c\n",BW); if(BW=='B'){ color=1; } else{ color=2; } z=get_z((int)*(chp[i]+2)-96,(int)*(chp[i]+3)-96); put_stone(z,color,1); print_board(); } return 0; }