Exemplo n.º 1
0
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;  
}
Exemplo n.º 2
0
int main()
{
  int color = 1;
  int z;

  srand( (unsigned)time( NULL ) );
  for (;;) {
    z = play_one_move(color);
    printf("moves=%4d, color=%d, z=%d\n",moves, color, get81(z));
    print_board();

    record[moves] = z;
    moves++;
    if ( moves == MAX_MOVES ) {
      printf("max moves!\n");
      break;
    }
    if ( z == 0 && moves >= 2 && record[moves-2] == 0 ) {
      printf("two pass\n");
      break;
    } 

    color = flip_color(color);
  }

  return 0;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
void hexbright::print_number(long number) {
  // reverse number (so it prints from left to right)
  BOOL negative = false;
  if(number<0) {
    number = 0-number;
    negative = true;
  }
  _color = GLED;
  _number=1; // to guarantee printing when dealing with trailing zeros (100 can't be stored as 001, use 1001)
  do {
    _number = _number * 10 + (number%10);
    number = number/10;
    _color = flip_color(_color);
  }  while(number>0);
  if(negative) {
    set_led(flip_color(_color), 500);
    print_wait_time = 600/update_delay;
  }
}
Exemplo n.º 5
0
// put stone. success returns 0. in playout, fill_eye_err = 1.
int put_stone(int tz, int color, int fill_eye_err)
{
	int around[4][3];
	int un_col = flip_color(color);
	int space = 0;
	int wall = 0;
	int mycol_safe = 0;
	int capture_sum = 0;
	int ko_maybe = 0;
	int liberty, stone;
	int i;

	if (tz == 0) { ko_z = 0; return 0; }  // pass

	// count 4 neighbor's liberty and stones.
	for (i = 0; i<4; i++) {
		int z, c, liberty, stone;
		around[i][0] = around[i][1] = around[i][2] = 0;
		z = tz + dir4[i];
		c = board[z];  // color
		if (c == 0) space++;
		if (c == 3) wall++;
		if (c == 0 || c == 3) continue;
		count_liberty(z, &liberty, &stone);
		around[i][0] = liberty;
		around[i][1] = stone;
		around[i][2] = c;
		if (c == un_col && liberty == 1) { capture_sum += stone; ko_maybe = z; }
		if (c == color  && liberty >= 2) mycol_safe++;
	}

	if (capture_sum == 0 && space == 0 && mycol_safe == 0) return 1; // suicide
	if (tz == ko_z) return 2; // ko
	if (wall + mycol_safe == 4 && fill_eye_err) return 3; // eye
	if (board[tz] != 0) return 4;

	for (i = 0; i<4; i++) {
		int lib = around[i][0];
		int c = around[i][2];
		if (c == un_col && lib == 1 && board[tz + dir4[i]]) {
			take_stone(tz + dir4[i], un_col);
		}
	}

	board[tz] = color;

	count_liberty(tz, &liberty, &stone);
	if (capture_sum == 1 && stone == 1 && liberty == 1) ko_z = ko_maybe;
	else ko_z = 0;
	return 0;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
void hexbright::update_number() {
  if(_number>0) { // we have something to do...
#ifdef DEBUG
    if(DEBUG==DEBUG_NUMBER) {
      static int last_printed = 0;
      if(last_printed != _number) {
        last_printed = _number;
        Serial.print("number remaining (read from right to left): ");
        Serial.println(_number);
      }
    }
#endif
    if(!print_wait_time) {
      if(_number==1) { // minimum delay between printing numbers
        print_wait_time = 2500/update_delay;
        _number = 0;
        return;
      } else {
        print_wait_time = 300/update_delay;
      }
      if(_number/10*10==_number) {
#if (DEBUG==DEBUG_NUMBER)
        Serial.println("zero");
#endif
        //        print_wait_time = 500/update_delay;
        set_led(_color, 400);
      } else {
        set_led(_color, 120);
        _number--;
      }
      if(_number && !(_number%10)) { // next digit?
        print_wait_time = 600/update_delay;
        _color = flip_color(_color);
        _number = _number/10;
      }
    }
  }
  
  if(print_wait_time) {
    print_wait_time--;
  }
}
Exemplo n.º 8
0
void selfplay()
{
  int color = 1;
  int z,search;
  
  for (;;) {
    if ( color == 1 ) {
      search = SEARCH_UCT; //SEARCH_PRIMITIVE;
    } else {
      search = SEARCH_UCT;
    }
    z = get_computer_move(color, search);
    add_moves(z, color);
    if ( z == 0 && moves > 1 && record[moves-2] == 0 ) break;
    if ( moves > 300 ) break;  // too long
    color = flip_color(color);
  }

  print_sgf();
}
Exemplo n.º 9
0
static struct npr_rbtree_node *
insert(struct npr_rbtree *t, struct npr_rbtree_node *n,
       npr_rbtree_key_t key,
       npr_rbtree_value_t v,
       int *insert_new)
{
    if (n == NULL) {
        n = alloc_node(t);
        n->left = NULL;
        n->right = NULL;
        n->v = v;
        n->key = key;
        n->color = RED;
        *insert_new = 1;

        return n;
    }

    if (is_red(n->left) && is_red(n->right)) {
        flip_color(n);
    }

    if (key == n->key) {
        n->v = v;
    } else if (key < n->key) {
        n->left = insert(t, n->left, key, v, insert_new);
    } else {
        n->right = insert(t, n->right, key, v, insert_new);
    }

    if (is_red(n->right)) {
        n = rotate_left(n);
    }

    if (is_red(n->left) && is_red(n->left->left)) {
        n = rotate_right(n);
    }

    return n;
}
Exemplo n.º 10
0
void update_rave(NODE *pN, int color, int current_depth, double win)
{
  int played_color[BOARD_MAX];
  int i,z;
  int c = color;
  
  memset(played_color, 0, sizeof(played_color));
  for (i=current_depth; i<depth; i++) {
    z = path[i];
    if ( played_color[z] == 0 ) played_color[z] = c;
    c = flip_color(c);
  }

  played_color[0] = 0;	// ignore pass

  for (i=0; i<pN->child_num; i++) {
    CHILD *c = &pN->child[i];
    if ( c->z == ILLEGAL_Z ) continue;
    if ( played_color[c->z] != color ) continue;
    c->rave_rate = (c->rave_games * c->rave_rate + win) / (c->rave_games + 1);
    c->rave_games++;
    pN->child_rave_games_sum++;
  }
}
Exemplo n.º 11
0
Arquivo: main.cpp Projeto: snonaka/go
int main()
{
	int color = 1;	// 現在の手番の色。黒が1で白が2
	int tesuu = 0;	// 手数
    hama[0] = 0;
    hama[1] = 0;
    bool pray_pass = false;
	srand( (unsigned)time( NULL ) );
    
    char str[256];
    char playstr[256];
    // stdoutをバッファリングしないように。GTPで通信に失敗するので。
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);  // stderrに書くとGoGuiに表示される。
    
    //loop:
	// 盤面初期化
	{int i,x,y; for (i=0;i<BOARD_MAX;i++) board[i] = 3;	for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) board[get_z(x,y)] = 0; }
    
    //	static int score_sum;
    //	static int loop_count;
    
	for (;;) {
        if ( fgets(str, 256, stdin)==NULL ) break;  // 標準入力から読む
        //fprintf(stderr, playstr);
        //strcpy(playstr,str);
        if      ( strstr(str,"boardsize")   ) {
            send_gtp("= \n\n");    // "boardsize 19" 19路盤
        }
        else if ( strstr(str,"clear_board") ) {
            for (int i=0;i<BOARD_MAX;i++) board[i] = 3;
            for (int y=0;y<B_SIZE;y++)
                for (int x=0;x<B_SIZE;x++)
                    board[get_z(x,y)] = 0;
            tesuu = 0;
            color = 1;
            hama[0] = 0;
            hama[1] = 0;
            pray_pass = false;
            node_num = 0;
            send_gtp("= \n\n");   
        }
        else if ( strstr(str,"name")        ) send_gtp("= ayasam\n\n");
        else if ( strstr(str,"version")     ) send_gtp("= 0.0.1\n\n");
        else if ( strstr(str,"genmove w")   ) {
            if (pray_pass) {
                send_gtp("= pass\n\n");
            } else {
                color = 2;
                clock_t bt = clock();
                all_playouts = 0;	// playout回数を初期化
                #if 0	// 0 でUCT探索
                    int z = select_best_move(color);	// 原始モンテカルロ
                #else
                    int z = select_best_uct(color);		// UCT
                #endif
                int err = move(z,color);	// 打ってみる
                if ( err != 0 ) { 
                    show_board();
                    fprintf( stderr, "Err!\n");
                    char mvstr[8];
                    change_z_str(mvstr, z);
                    fprintf(stderr, "%s\n", mvstr);
                    exit(0);
                }
                kifu[tesuu] = z;
                tesuu++;
                print_board();
                char gtstr[12] = "= ";
                char mvstr[8];
                change_z_str(mvstr, z);
                strcat(gtstr, mvstr);
                strcat(gtstr, "\n\n");
                send_gtp(gtstr);
                fprintf(stderr,"play_xy = %s,手数=%d,色=%d,all_playouts=%d\n",mvstr,tesuu,color,all_playouts);
                double t = (double)(clock()+1 - bt) / CLOCKS_PER_SEC;
                fprintf(stderr,"%.1f 秒, %.0f playout/秒\n",t,all_playouts/t);
            }
        }
        else if ( strstr(str,"genmove b")   ) {
            if (pray_pass) {
                send_gtp("= pass\n\n");
            } else {
                color = 1;
                clock_t bt = clock();
                all_playouts = 0;	// playout回数を初期化
                #if 0	// 0 でUCT探索
                    int z = select_best_move(color);	// 原始モンテカルロ
                #else
                    int z = select_best_uct(color);		// UCT
                #endif
                int err = move(z,color);	// 打ってみる
                if ( err != 0 ) { 
                    show_board();
                    fprintf( stderr, "Err!\n");
                    char mvstr[8];
                    change_z_str(mvstr, z);
                    fprintf(stderr, "%s\n", mvstr);
                    exit(0);
                }
                kifu[tesuu] = z;
                tesuu++;
                print_board();
                char gtstr[12] = "= ";
                char mvstr[8];
                change_z_str(mvstr, z);
                strcat(gtstr, mvstr);
                strcat(gtstr, "\n\n");
                send_gtp(gtstr);
                fprintf(stderr,"play_xy = %s,手数=%d,色=%d,all_playouts=%d\n",mvstr,tesuu,color,all_playouts);
                double t = (double)(clock()+1 - bt) / CLOCKS_PER_SEC;
                fprintf(stderr,"%.1f 秒, %.0f playout/秒\n",t,all_playouts/t);
            }
        }
        // 相手の手を受信 "play W D17" のように来る
        else if ( strstr(str,"play")        ) {
            char *tp;
            tp = strtok(str, " ");
            tp = strtok(NULL, " ");
            if (strstr(tp, "W") || strstr(tp, "w")) {
                color = 2;
            } else {
                color = 1;
            }
            if (tp) {
                tp = strtok(NULL, " ");
                int z = change_str_z(tp);
                int err = play_move(z,color);	// 打ってみる
                if ( (err != 0) && (err != 3) ) { 
                    show_board();
                    fprintf( stderr, "Err!\n");
                    char mvstr[8];
                    change_z_str(mvstr, z);
                    fprintf(stderr, "%s\n", mvstr);
                    strcat(playstr,"Error!:");
                    if (err == 1) {
                        strcat(playstr,"1");   
                    } else if (err == 2) {
                        strcat(playstr,"2");
                    } else if (err == 3) {
                        strcat(playstr,"3");
                    } else if (err == 4) {
                        strcat(playstr,"4");
                    }
                    strcat(playstr," ");
                    strcat(playstr,tp);
                    strcat(playstr," -> ");
                    strcat(playstr,mvstr);
                    strcat(playstr,"\n");
                    exit(0);
                }
                kifu[tesuu] = z;
                tesuu++;
                if (z == 0) {
                    pray_pass = true;
                } else {
                    pray_pass = false;
                }
                print_board();
            }
            send_gtp("= \n\n");
        }
        else if ( strstr(str, "showboard")) {
            show_board();
            send_gtp("= \n\n");
        }
        else if ( strstr(str, "quit")) {
            send_gtp("= \n\n");
            break;
        }
        else if ( strstr(str,"test")) {
            for (int n=0;;n++) {
                for (int i=0;i<BOARD_MAX;i++) board[i] = 3;
                for (int y=0;y<B_SIZE;y++)
                    for (int x=0;x<B_SIZE;x++)
                        board[get_z(x,y)] = 0;
                tesuu = 0;
                color = 1;
                hama[0] = 0;
                hama[1] = 0;
                pray_pass = false;
            
                while (true) {
                    if (pray_pass) {
                        break;
                    } else {
                        clock_t bt = clock();
                        all_playouts = 0;	// playout回数を初期化
                        #if 0	// 0 でUCT探索
                            int z = select_best_move(color);	// 原始モンテカルロ
                        #else
                            int z = select_best_uct(color);		// UCT
                        #endif
                        int err = move(z,color);	// 打ってみる
                        if ( err != 0 ) { 
                            show_board();
                            fprintf( stderr, "Err!\n");
                            char mvstr[8];
                            change_z_str(mvstr, z);
                            fprintf(stderr, "%s\n", mvstr);
                            exit(0);
                        }
                        //kifu[tesuu] = z;
                        tesuu++;
                        //print_board();
                        //char gtstr[12] = "= ";
                        char mvstr[8];
                        change_z_str(mvstr, z);
                        //strcat(gtstr, mvstr);
                        //strcat(gtstr, "\n\n");
                        //send_gtp(gtstr);
                        fprintf(stderr,"play_xy = %s,手数=%d,色=%d,all_playouts=%d\n",mvstr,tesuu,color,all_playouts);
                        double t = (double)(clock()+1 - bt) / CLOCKS_PER_SEC;
                        fprintf(stderr,"%.1f 秒, %.0f playout/秒\n",t,all_playouts/t);
                        color = flip_color(color);
                        if (z == 0) {
                            pray_pass = true;
                        }
                    }
                }
                print_board();
                printf("%d end\n", n);
            }
        }
        else {
            send_gtp("= \n\n");  // それ以外のコマンドにはOKを返す
        }
        show_board();
	}
    /*
     // 自己対戦のテスト用
     int score = count_score(1);
     score_sum += score;
     loop_count++;
     FILE *fp = fopen("out.txt","a+");
     fprintf(fp,"Last Score=%d,%d,%d,tesuu=%d\n",score,score_sum,loop_count,tesuu);
     fclose(fp);
     printf("Last Score=%d,%d,%d,tesuu=%d\n",score,score_sum,loop_count,tesuu); color = 1; tesuu = 0; goto loop;
     */
	// SGFで棋譜を吐き出す
    /*
	printf("(;GM[1]SZ[%d]\r\n",B_SIZE); 
	for (int i=0; i<tesuu; i++) {
		int z = kifu[i];
		int y = z / WIDTH;
		int x = z - y*WIDTH;
		if ( z == 0 ) x = y = 20;
		char *sStone[2] = { "B", "W" };
		printf(";%s[%c%c]",sStone[i&1], x+'a'-1, y+'a'-1 );
		if ( ((i+1)%10)==0 ) printf("\r\n");
	}
	printf("\r\n)\r\n"); 
     */
    
	return 0;
}