Ejemplo n.º 1
0
void update_special_node(int move) {
	// store special node
	int x,y;
	double winrate = 0;
	double c = 0;
	for(y = state.boardsize; y >= 1; y--)
	{
		for(x = 1; x <= state.boardsize; x++)
		{		
			struct Node * nodeThis = 
				hash_get_node(hash_get(move, POS(x,y), goban.hash,
				NODETYPE_POS|NODETYPE_TARGET|NODETYPE_MOVE));

            struct Node *nodeParent =
               hash_get_node(hash_get(0, POS(x,y), goban.hash, NODETYPE_POS|NODETYPE_TARGET));
		
			if (nodeThis->visits)
			{
				double wr = ((double)nodeThis->wins / (double)nodeThis->visits);
				double wrPar = ((double)nodeParent->wins / (double)nodeParent->visits);
                /*double stb = stab(POS(x,y));
				stb = pow(stb, 2);
				stb=1;
				c+=stb;*/
                c += 1;
				wr = exaggerate_winrate(wr, EXAGGERATE_RATE) ;
				wrPar = 1;//exaggerate_winrate(wrPar, EXAGGERATE_RATE) ;

                winrate += wr / wrPar;//((wr - wrPar) + 1) / 2.0;// 0...1 - get_average_rating(move(x,y));
				//out(fileGTP, "Winrate for move %p, at target %p = %f - %f\n",
				//		move, POS(x,y), wr, wrPar);
			}
		}
	}

	winrate /= c;
				//out(fileGTP, "Winrate for move %p, %f\n", move, POS(x,y), winrate);

	hash_set_node_special(hash_get(move, 0, goban.hash, 
				NODETYPE_POS|NODETYPE_MOVE|NODETYPE_SPECIAL), winrate);

}
Ejemplo n.º 2
0
// gets the currently determined best-move from the hashtables
int engine_getbestmove() {
	int bestmove = 0;
	double bestwinrate = 0;
	int x,y;
	for(y = state.boardsize; y >= 1; y--)
	{
		for (x = 1; x <= state.boardsize; x++)
		{
			struct Node *node = hash_get_node(hash_get(
				POS(x,y), 0, goban.hash, 
				NODETYPE_POS|NODETYPE_MOVE|NODETYPE_SPECIAL));
			double winrate = (double) node->wins / (double) node->visits;
			if (winrate > bestwinrate)
			{
				bestwinrate = winrate;
				bestmove = POS(x,y);
			}
		}
	}

	return bestmove;
}
Ejemplo n.º 3
0
uint64_t test_perft_rec(state_t *state, int depth, int verbose)
{
    /* Given a position, it will recursivly apply every possible
     * move for a given depth and count the leaf nodes. */

    if (depth == 0)
    {
        return 1;
    }

    hash_node_t *hash_node = hash_get_node(state->zobrist);
    /* Check if hashing is enabled */
    if (hash_node)
    {
        if (hash_node->hash == state->zobrist && hash_node->depth == depth)
        {
            ++_cache_hits;
            return hash_node->score;
        }
        else
        {
            ++_cache_misses;
        }
    }

    int moves[100];
    int count = 0, count2 = 0;

    move_generate_moves(state, moves, &count);
    move_generate_tactical(state, moves + count, &count2);
    count += count2;

    /* Check for invalid position or board with no pieces :) */
    if (count <= 0)
    {
        return 0;
    }

    uint64_t nodes = 0;

    int i;
    for (i = 0; i < count; ++i)
    {
        make_move(state, moves[i], depth);

        if (move_is_attacked(state, state->king_idx[Flip(state->turn)], state->turn))
        {
            unmake_move(state, moves[i], depth);
            continue;
        }

        uint64_t res = test_perft_rec(state, depth - 1, 0);
        nodes += res;

        if (verbose && res > 0)
        {
            char move_str[16];
            util_move_to_lan(moves[i], move_str);
            printf("%s: %lld\n", move_str, res);
        }

        unmake_move(state, moves[i], depth);
    }

    hash_add_node(state->zobrist, nodes, depth, 0, 0);

    return nodes;
}
Ejemplo n.º 4
0
// recursive function to try a game
int trygame(int depth, int doUpdate) {

	struct Node *parent = (struct Node*)0;
	uint64_t goban_hash = goban.hash;
	int myturn = goban.turn;
	int result;
	int pos;
	int win;
	int x,y;
	int haspoints;
	uint64_t hash;



	if (depth == MAXDEPTH)
		return goban_getOwner(target);

	// see if we can use nt3
	hash = hash_get(0, target, goban.hash, NODETYPE_POS |USE_TARGET);
	parent = hash_get_node(hash);

	pos = get_best_move(
			parent,
			(NODETYPE_POS| USE_TARGET|  NODETYPE_MOVE),
			NULL
	);

	if (parent->visits >= MIN_SPECIAL_VISITS
			&& parent->visits % UPDATE_SPECIAL_RATE == 0) 
	{
		update_special_node(pos);
	}

    if (mode == 1)
    {
       int p;
       for(y = state.boardsize; y >= 1; y--)
           for(x = 1; x <= state.boardsize; x++)
               update_special_node(POS(x,y));

        p = engine_getbestmove();
        if (p) pos = p;
    }

	goban_move(pos);

#if LOG_MOVES_RATE > 0
	if (depth == 0 && tries % LOG_MOVES_RATE == 0)
	{
		out(fileGTP, "Target %p ", target);
	}
	if (depth < 10 && tries % LOG_MOVES_RATE == 0)
		out(fileGTP, "%d%p ", 0, pos);
#endif

	result = trygame(depth+1, parent->visits > 0);

#if LOG_MOVES_RATE > 0
	if (depth == 0 && tries % LOG_MOVES_RATE == 0)
       out(fileGTP, " res=%d, %r\n", result, goban.score);
#endif

	haspoints = 0;
	for(y = state.boardsize; y >= 1; y--)
		for(x = 1; x <= state.boardsize; x++)
		{
			int targ = POS(x,y);
            if (targ != target) continue;
			result = goban_getOwner(targ);
			if (!result) continue;
			haspoints = 1;
		}
    if (!haspoints)
    {
       //out(fileInfo, "Failure getOwner(target)=%d\n", goban_getOwner(POS(7,5)));
       //outboard(fileInfo);
    }
	if (haspoints && doUpdate)
		for(y = state.boardsize; y >= 1; y--)
			for(x=1; x <= state.boardsize; x++)
			{
				int targ = POS(x,y);
                  if (targ != target) continue;
				result = goban_getOwner(targ);
				if (!result) continue;

				win = (result == myturn ? 1 : 0);

				// store nt 3
				hash_set_node(hash_get(pos, targ, goban_hash,
						NODETYPE_POS|NODETYPE_TARGET|NODETYPE_MOVE), win);
				hash_set_node(hash_get(pos, targ, goban_hash,
						NODETYPE_POS|NODETYPE_TARGET), win);

			}

    // update target-agnostic nodes (generic uct)
    if (haspoints && doUpdate && goban.score)
    {
       win = (myturn * goban.score > 0 ? 1 : 0);
       hash_set_node(hash_get(pos, 0, goban_hash,
               NODETYPE_POS|NODETYPE_MOVE), win);
       hash_set_node(hash_get(pos, 0, goban_hash,
               NODETYPE_POS), win);
    }

	if (haspoints && depth == 0)
	{

		for(y = state.boardsize; y >= 1; y--)
			for(x=1; x <= state.boardsize; x++)
			{
				int targ = POS(x,y);
				result = goban_getOwner(targ);
				pos_stat[targ].total++;

				if (result == myturn)
					pos_stat[targ].won++;
				else if (result == -myturn)
					pos_stat[targ].lost++;

			}
		//outboard(fileGTP);
		//update_special_node(pos);
		return 1;
	}
	
	return 0;


	return result;
}
Ejemplo n.º 5
0
// move_info should contain parentvisits; others are filled in
void get_move_value(int move, struct MoveInfo *move_info, int nodetype)
{
	uint64_t hash;
	struct Node * node;
	if (move_info->parent_visits == 0)
	{
		move_info->uct = 0;
/*
		hash = hash_get(move, target, goban.hash, nodetype);
		node = hash_get_node(hash);

		assert(node->wins == 0);
		assert(node->visits == 0);
*/
		return;
	}

	hash = hash_get(move, target, goban.hash, NODETYPE_POS|USE_TARGET|NODETYPE_MOVE);
	node = hash_get_node(hash);

	move_info->wins = node->wins;
	move_info->visits = node->visits;
	if (move_info->visits > 0)
		move_info->winrate = (double)move_info->wins / ((double)move_info->visits);
	else
		move_info->winrate = 0;


	//if (move_info->parent_visits > state.boardsize * state.boardsize * 10)
    if (0)
	{
		hash = hash_get(move, target, goban.hash, NODETYPE_POS|NODETYPE_MOVE|NODETYPE_SPECIAL);
		node = hash_get_node(hash);

		if (node->visits > 0)
			move_info->winrate = (double)node->wins / ((double)node->visits+1);
	}



	//assert(move_info->visits <= move_info->parent_visits);

	move_info->uct = getuct(move_info->winrate, move_info->visits, move_info->parent_visits, nodetype);


	if (0)
	{
		// get the winrate from the special node
		hash = hash_get(move, target, goban.hash, nodetype);
		node = hash_get_node(hash);

		if (node->visits == 0)
		{
			move_info->wins = 0;
			move_info->visits = 0;
			move_info->winrate = 0.0;
		}
		else
		{
			move_info->winrate = (double)node->wins / ((double)node->visits+1);
			hash = hash_get(move, target, goban.hash, 
					NODETYPE_POS|NODETYPE_TARGET|NODETYPE_MOVE);
			node = hash_get_node(hash);
			move_info->wins = node->wins;
			move_info->visits = node->visits;
		}

		move_info->uct = getuct(move_info->winrate, move_info->visits, move_info->parent_visits, nodetype);
	}
}